예제 #1
0
int ftape_abort_operation(void)
{
	int result = 0;
	int status;
	TRACE_FUN(ft_t_flow);

	if (ft_runner_status == running) {
		TRACE(ft_t_noise, "aborting runner, waiting");
		
		ft_runner_status = do_abort;
		/* set timeout so that the tape will run to logical EOT
		 * if we missed the last sector and there are no queue pulses.
		 */
		result = ftape_dumb_stop();
	}
	if (ft_runner_status != idle) {
		if (ft_runner_status == do_abort) {
			TRACE(ft_t_noise, "forcing runner abort");
		}
		TRACE(ft_t_noise, "stopping tape");
		result = ftape_stop_tape(&status);
		ft_location.known = 0;
		ft_runner_status  = idle;
	}
	ftape_reset_buffer();
	ftape_zap_read_buffers();
	ftape_set_state(idle);
	TRACE_EXIT result;
}
예제 #2
0
int ftape_abort_operation(void)
{
	TRACE_FUN(5, "ftape_abort_operation");
	int result = 0;
	int i;
	int status;

	if (runner_status == running) {
		TRACE(5, "aborting runner, waiting");
		runner_status = do_abort;
		/* set timeout so that the tape will run to logical EOT
		 * if we missed the last sector and there are no queue pulses.
		 */
		result = ftape_dumb_stop();
		if (result == 0) {
			runner_status = idle;
		}
	}
	if (runner_status != idle) {
		if (runner_status == do_abort) {
			TRACE(5, "forcing runner abort");
		}
		TRACE(5, "stopping tape");
		result = ftape_command_wait(QIC_STOP_TAPE, timeout.stop, &status);
		location.known = 0;
		runner_status = idle;
	}
	for (i = 0; i < NR_BUFFERS; ++i) {
		buffer[i].status = waiting;
	}
	head = tail = 0;
	TRACE_EXIT;
	return result;
}
예제 #3
0
int loop_until_writes_done(void)
{
    TRACE_FUN(5, "loop_until_writes_done");
    int i;
    int result = 0;

    /*
     *  Wait until all data is actually written to tape.
     */
    while (ftape_state == writing && buffer[head].status != done) {
        TRACEx2(7, "tail: %d, head: %d", tail, head);
        for (i = 0; i < NR_BUFFERS; ++i) {
            TRACEx3(8, "buffer[ %d] segment_id: %d, status: %d",
                    i, buffer[i].segment_id, buffer[i].status);
        }
        result = fdc_interrupt_wait(5 * SECOND);
        if (result < 0) {
            TRACE(1, "fdc_interrupt_wait failed");
            last_write_failed = 1;
            break;
        }
        if (buffer[head].status == error) {
            /* Allow escape from loop when signaled !
             */
            if (current->signal & _DONT_BLOCK) {
                TRACE(2, "interrupted by signal");
                TRACE_EXIT;
                result = -EINTR;	/* is this the right return value ? */
                break;
            }
            if (buffer[head].hard_error_map != 0) {
                /*  Implement hard write error recovery here
                 */
            }
            buffer[head].status = waiting;	/* retry this one */
            if (runner_status == aborting) {
                ftape_dumb_stop();
                runner_status = idle;
            }
            if (runner_status != idle) {
                TRACE(1, "unexpected state: runner_status != idle");
                result = -EIO;
                break;
            }
            start_writing(WRITE_MULTI);
        }
        TRACE(5, "looping until writes done");
        result = 0;	/* normal exit status */
    }
    TRACE_EXIT;
    return result;
}
예제 #4
0
/*      Write given segment from buffer at address onto tape.
 */
int write_segment(unsigned segment_id, byte * address, int flushing)
{
    TRACE_FUN(5, "write_segment");
    int result = 0;
    int bytes_written = 0;

    TRACEi(5, "segment_id =", segment_id);
    if (ftape_state != writing) {
        if (ftape_state == reading) {
            TRACE(5, "calling ftape_abort_operation");
            result = ftape_abort_operation();
            if (result < 0) {
                TRACE(1, "ftape_abort_operation failed");
            }
        }
        ftape_zap_read_buffers();
        ftape_zap_write_buffers();
        ftape_state = writing;
    }
    /*    if all buffers full we'll have to wait...
     */
    wait_segment(writing);
    if (buffer[tail].status == error) {
        /*  setup for a retry
         */
        buffer[tail].status = waiting;
        bytes_written = -EAGAIN;	/* force retry */
        if (buffer[tail].hard_error_map != 0) {
            TRACEx1(1, "warning: %d hard error(s) in written segment",
                    count_ones(buffer[tail].hard_error_map));
            TRACEx1(4, "hard_error_map = 0x%08lx", buffer[tail].hard_error_map);
            /*  Implement hard write error recovery here
             */
        }
    } else if (buffer[tail].status == done) {
        history.defects += count_ones(buffer[tail].hard_error_map);
    } else {
        TRACE(1, "wait for empty segment failed");
        result = -EIO;
    }
    /*    If just passed last segment on tape: wait for BOT or EOT mark.
     */
    if (result >= 0 && runner_status == logical_eot) {
        int status;

        result = ftape_ready_wait(timeout.seek, &status);
        if (result < 0 || (status & (QIC_STATUS_AT_BOT | QIC_STATUS_AT_EOT)) == 0) {
            TRACE(1, "eot/bot not reached");
        } else {
            runner_status = end_of_tape;
        }
    }
    /*    should runner stop ?
     */
    if (result >= 0 &&
            (runner_status == aborting || runner_status == buffer_underrun ||
             runner_status == end_of_tape)) {
        if (runner_status != end_of_tape) {
            result = ftape_dumb_stop();
        }
        if (result >= 0) {
            if (runner_status == aborting) {
                if (buffer[head].status == writing) {
                    buffer[head].status = done;	/* ????? */
                }
            }
            runner_status = idle;	/* aborted ? */
        }
    }
    /*  Don't start tape if runner idle and segment empty.
     */
    if (result >= 0 && !(runner_status == idle &&
                         get_bad_sector_entry(segment_id) == EMPTY_SEGMENT)) {
        if (buffer[tail].status == done) {
            /*    now at least one buffer is empty, fill it with our data.
             *    skip bad sectors and generate ecc.
             *    copy_and_gen_ecc return nr of bytes written,
             *    range 0..29 Kb inclusive !
             */
            result = copy_and_gen_ecc(buffer[tail].address, address,
                                      get_bad_sector_entry(segment_id));
            if (result >= 0) {
                bytes_written = result;
                buffer[tail].segment_id = segment_id;
                buffer[tail].status = waiting;
                next_buffer(&tail);
            }
        }
        /*    Start tape only if all buffers full or flush mode.
         *    This will give higher probability of streaming.
         */
        if (result >= 0 && runner_status != running &&
                ((head == tail && buffer[tail].status == waiting) || flushing)) {
            result = start_writing(WRITE_MULTI);
        }
    }
    TRACE_EXIT;
    return (result < 0) ? result : bytes_written;
}