summaryrefslogtreecommitdiff
path: root/scsi/rz_disk_bbr.c
diff options
context:
space:
mode:
Diffstat (limited to 'scsi/rz_disk_bbr.c')
-rw-r--r--scsi/rz_disk_bbr.c259
1 files changed, 0 insertions, 259 deletions
diff --git a/scsi/rz_disk_bbr.c b/scsi/rz_disk_bbr.c
deleted file mode 100644
index 9d87675..0000000
--- a/scsi/rz_disk_bbr.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: rz_disk_bbr.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 4/91
- *
- * Top layer of the SCSI driver: interface with the MI.
- * This file contains bad-block management functions
- * (retry, replace) for disk-like devices.
- */
-
-#include <mach/std_types.h>
-#include <scsi/compat_30.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_defs.h>
-#include <scsi/rz.h>
-
-#if (NSCSI > 0)
-
-int scsi_bbr_retries = 10;
-
-#define BBR_ACTION_COMPLETE 1
-#define BBR_ACTION_RETRY_READ 2
-#define BBR_ACTION_REASSIGN 3
-#define BBR_ACTION_COPY 4
-#define BBR_ACTION_VERIFY 5
-
-static void make_msf(); /* forward */
-
-/*
- * Bad block replacement routine, invoked on
- * unrecovereable disk read/write errors.
- */
-boolean_t
-scdisk_bad_block_repl(tgt, blockno)
- target_info_t *tgt;
- unsigned int blockno;
-{
- register io_req_t ior = tgt->ior;
-
- if (scsi_no_automatic_bbr || (ior->io_op & IO_INTERNAL))
- return FALSE;
-
- /* signal we took over */
- tgt->flags |= TGT_BBR_ACTIVE;
-
- printf("%s", "Attempting bad block replacement..");
-
- tgt->dev_info.disk.b.badblockno = blockno;
- tgt->dev_info.disk.b.retry_count = 0;
-
- tgt->dev_info.disk.b.save_rec = ior->io_recnum;
- tgt->dev_info.disk.b.save_addr = ior->io_data;
- tgt->dev_info.disk.b.save_count = ior->io_count;
- tgt->dev_info.disk.b.save_resid = ior->io_residual;
-
- /*
- * On a write all we need is to rewire the offending block.
- * Note that the sense data identified precisely which 512 sector
- * is bad. At the end we'll retry the entire write, so if there
- * is more than one bad sector involved they will be handled one
- * at a time.
- */
- if ((ior->io_op & IO_READ) == 0) {
- char msf[sizeof(int)];
- ior->io_temporary = BBR_ACTION_COMPLETE;
- printf("%s", "just reassign..");
- make_msf(msf,blockno);
- scsi_reassign_blocks( tgt, msf, 1, ior);
- } else
- /*
- * This is more complicated. We asked for N bytes, and somewhere
- * in there there is a chunk of bad data. First off, we should retry
- * at least a couple of times to retrieve that data [yes the drive
- * should have done its best already so what]. If that fails we
- * should recover as much good data as possible (before the bad one).
- */
- {
- ior->io_temporary = BBR_ACTION_RETRY_READ;
- printf("%s", "retry read..");
- ior->io_residual = 0;
- scdisk_start_rw(tgt, ior);
- }
-
- return TRUE;
-}
-
-static
-void make_msf(buf,val)
- unsigned char *buf;
- unsigned int val;
-{
- *buf++ = val >> 24;
- *buf++ = val >> 16;
- *buf++ = val >> 8;
- *buf++ = val >> 0;
-}
-
-/*
- * This effectively replaces the strategy routine during bbr.
- */
-void scdisk_bbr_start( tgt, done)
- target_info_t *tgt;
- boolean_t done;
-{
- register io_req_t ior = tgt->ior;
- char *msg;
-
- switch (ior->io_temporary) {
-
- case BBR_ACTION_COMPLETE:
-
- /* all done, either way */
-fin:
- tgt->flags &= ~TGT_BBR_ACTIVE;
- ior->io_recnum = tgt->dev_info.disk.b.save_rec;
- ior->io_data = tgt->dev_info.disk.b.save_addr;
- ior->io_count = tgt->dev_info.disk.b.save_count;
- ior->io_residual = tgt->dev_info.disk.b.save_resid;
-
- if (tgt->done == SCSI_RET_SUCCESS) {
- /* restart normal life */
- register unsigned int xferred;
- if (xferred = ior->io_residual) {
- ior->io_data -= xferred;
- ior->io_count += xferred;
- ior->io_recnum -= xferred / tgt->block_size;
- ior->io_residual = 0;
- }
- /* from the beginning */
- ior->io_error = 0;
- msg = "done, restarting.";
- } else {
- /* we could not fix it. Tell user and give up */
- tgt->ior = ior->io_next;
- iodone(ior);
- msg = "done, but could not recover.";
- }
-
- printf("%s\n", msg);
- scdisk_start( tgt, FALSE);
- return;
-
- case BBR_ACTION_RETRY_READ:
-
- /* see if retry worked, if not do it again */
- if (tgt->done == SCSI_RET_SUCCESS) {
- char msf[sizeof(int)];
-
- /* whew, retry worked. Now rewire that bad block
- * and don't forget to copy the good data over */
-
- tgt->dev_info.disk.b.retry_count = 0;
- printf("%s", "ok now, reassign..");
- ior->io_temporary = BBR_ACTION_COPY;
- make_msf(msf, tgt->dev_info.disk.b.badblockno);
- scsi_reassign_blocks( tgt, msf, 1, ior);
- return;
- }
- if (tgt->dev_info.disk.b.retry_count++ < scsi_bbr_retries) {
- scdisk_start_rw( tgt, ior);
- return;
- }
- /* retrying was hopeless. Leave the bad block there for maintainance */
- /* because we do not know what to write on it */
- printf("%s%d%s", "failed after ", scsi_bbr_retries, " retries..");
- goto fin;
-
-
- case BBR_ACTION_COPY:
-
- /* retrying succeded and we rewired the bad block. */
- if (tgt->done == SCSI_RET_SUCCESS) {
- unsigned int tmp;
- struct diskpart *label;
-
- printf("%s", "ok, rewrite..");
-
- /* writeback only the bad sector */
-
- /* map blockno back to partition offset */
-/* !!! partition code changes: */
- tmp = rzpartition(ior->io_unit);
-/* label=lookup_part(array, tmp +1); */
- tmp = tgt->dev_info.disk.b.badblockno -
-/* label->start; */
-/* #if 0 */
- tgt->dev_info.disk.l.d_partitions[tmp].p_offset;
-/* #endif 0 */
- ior->io_data += (tmp - ior->io_recnum) * tgt->block_size;
- ior->io_recnum = tmp;
- ior->io_count = tgt->block_size;
- ior->io_op &= ~IO_READ;
-
- ior->io_temporary = BBR_ACTION_VERIFY;
- scdisk_start_rw( tgt, ior);
- } else {
-
- /* either unsupported command, or repl table full */
- printf("%s", "reassign failed (really needs reformatting), ");
- ior->io_error = 0;
- goto fin;
- }
- break;
-
- case BBR_ACTION_VERIFY:
-
- if (tgt->done == SCSI_RET_SUCCESS) {
- ior->io_op |= IO_READ;
- goto fin;
- }
-
- if (tgt->dev_info.disk.b.retry_count++ > scsi_bbr_retries) {
- printf("%s%d%s", "failed after ",
- scsi_bbr_retries, " retries..");
- ior->io_op |= IO_READ;
- goto fin;
- }
-
- /* retry, we are *this* close to success.. */
- scdisk_start_rw( tgt, ior);
-
- break;
-
- case BBR_ACTION_REASSIGN:
-
- /* if we wanted to issue the reassign multiple times */
- /* XXX unimplemented XXX */
-
- default: /* snafu */
- panic("scdisk_bbr_start");
- }
-}
-#endif /* NSCSI > 0 */