summaryrefslogtreecommitdiff
path: root/scsi/rz.c
diff options
context:
space:
mode:
Diffstat (limited to 'scsi/rz.c')
-rw-r--r--scsi/rz.c462
1 files changed, 0 insertions, 462 deletions
diff --git a/scsi/rz.c b/scsi/rz.c
deleted file mode 100644
index febf629..0000000
--- a/scsi/rz.c
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1993-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.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 10/90
- *
- * Top layer of the SCSI driver: interface with the MI side.
- */
-
-/*
- * This file contains the code that is common to all scsi devices,
- * operations and/or behaviours specific to certain devices live
- * in the corresponding rz_mumble files.
- */
-
-#include <scsi.h>
-
-#if (NSCSI>0)
-
-#include <mach/std_types.h>
-#include <machine/machspl.h> /* spl definitions */
-#include <scsi/compat_30.h>
-
-#ifdef MACH_KERNEL
-#include <kern/time_out.h>
-#else /*MACH_KERNEL*/
-#include <sys/kernel.h> /* for hz */
-
-static io_req_t getbp();
-#endif /*MACH_KERNEL*/
-
-#include <scsi/scsi_defs.h>
-#include <scsi/rz.h>
-
-
-boolean_t
-rz_check(dev, p_sc, p_tgt)
- int dev;
- scsi_softc_t **p_sc;
- target_info_t **p_tgt;
-{
- if (rzcontroller(dev) >= NSCSI ||
- (*p_sc = scsi_softc[rzcontroller(dev)]) == 0)
- return FALSE;
-
- *p_tgt = (*p_sc)->target[rzslave(dev)];
-
- if (!*p_tgt ||
- !((*p_tgt)->flags&TGT_ALIVE))
- return FALSE;
- return TRUE;
-}
-
-/*
- * Open routine
- *
- * On tapes and other devices might have to wait a bit for
- * the unit to come alive. The following patchable variable
- * takes this into account
- */
-int rz_open_timeout = 60;/* seconds */
-
-int rz_open(dev, mode, ior)
- int dev;
- dev_mode_t mode;
- io_req_t ior;
-{
- scsi_softc_t *sc = 0;
- target_info_t *tgt;
- scsi_ret_t ret;
- register int i;
-
- if (!rz_check(dev, &sc, &tgt)) {
- /*
- * Probe it again: might have installed a new device
- */
- if (!sc || !scsi_probe(sc, &tgt, rzslave(dev), ior))
- return D_NO_SUCH_DEVICE;
- }
-
- /* tapes do not wait for rewind to complete on close */
- if (tgt->ior && !(tgt->flags & TGT_ONLINE))
- return D_WOULD_BLOCK;
-
- if (scsi_debug)
- printf("opening %s%d..", (*tgt->dev_ops->driver_name)(TRUE), dev&0xff);
-
- if (sc->watchdog) {
- (*sc->watchdog)(tgt->hw_state);
- sc->watchdog = 0;
- }
-
- /*
- * Bring the unit online, retrying if necessary.
- * If the target is spinning up we wait for it.
- */
- if ( ! (tgt->flags & TGT_ONLINE)) {
- io_req_t tmp_ior;
-
- io_req_alloc(tmp_ior,0);
- tmp_ior->io_next = 0;
- tmp_ior->io_count = 0;
-
- for (i = 0; i < rz_open_timeout; i++) {
-
- tmp_ior->io_op = IO_INTERNAL;
- tmp_ior->io_error = 0;
- ret = scsi_test_unit_ready(tgt, tmp_ior);
-
- if (ret == SCSI_RET_SUCCESS)
- break;
-
- if (ret == SCSI_RET_DEVICE_DOWN) {
- i = rz_open_timeout;
- break;
- }
-
- if (ret == SCSI_RET_NEED_SENSE) {
-
- tmp_ior->io_op = IO_INTERNAL;
- tmp_ior->io_count = 0;
- tmp_ior->io_residual = 0;
- tgt->ior = tmp_ior;
- scsi_request_sense(tgt, tmp_ior, 0);
- iowait(tmp_ior);
-
- }
-
- if (i == 5) printf("%s%d: %s\n",
- (*tgt->dev_ops->driver_name)(TRUE),
- tgt->target_id,
- "Waiting to come online..");
- timeout(wakeup, tgt, hz);
- await(tgt);
- }
-
- /* lock on removable media */
- if ((i != rz_open_timeout) && (tgt->flags & TGT_REMOVABLE_MEDIA)) {
- tmp_ior->io_op = IO_INTERNAL;
- /* too many dont support it. Sigh */
- tgt->flags |= TGT_OPTIONAL_CMD;
- (void) scsi_medium_removal( tgt, FALSE, tmp_ior);
- tgt->flags &= ~TGT_OPTIONAL_CMD;
- }
-
- io_req_free(tmp_ior);
- if (i == rz_open_timeout)
- return D_DEVICE_DOWN;
- }
- /*
- * Perform anything open-time special on the device
- */
- if (tgt->dev_ops->open != SCSI_OPEN_NULL) {
- ret = (*tgt->dev_ops->open)(tgt, ior);
- if (ret != SCSI_RET_SUCCESS) {
- if (scsi_debug) printf("%s%d: open failed x%x\n",
- (*tgt->dev_ops->driver_name)(TRUE), dev&0xff, ret);
- return ret;
- }
- }
- tgt->flags |= TGT_ONLINE;
- ior->io_device->bsize = tgt->block_size;
- return D_SUCCESS;
-}
-
-int rz_close(dev)
- int dev;
-{
- scsi_softc_t *sc;
- target_info_t *tgt;
- scsi_ret_t ret;
-
- if (!rz_check(dev, &sc, &tgt))
- return D_NO_SUCH_DEVICE;
-
- if (scsi_debug)
- printf("closing %s%d..", (*tgt->dev_ops->driver_name)(TRUE), dev&0xff);
-
- if (tgt->flags & TGT_REMOVABLE_MEDIA) {
- io_req_t ior;
-
- io_req_alloc(ior,0);
- ior->io_next = 0;
- ior->io_count = 0;
- ior->io_op = IO_INTERNAL;
- ior->io_error = 0;
- /* too many dont support it. Sigh */
- tgt->flags |= TGT_OPTIONAL_CMD;
- (void) scsi_medium_removal( tgt, TRUE, ior);
- tgt->flags &= ~TGT_OPTIONAL_CMD;
- io_req_free(ior);
- }
-
- /*
- * Perform anything close-time special on the device
- */
- if (tgt->dev_ops->close != SCSI_CLOSE_NULL) {
- ret = (*tgt->dev_ops->close)(tgt);
- if (ret != SCSI_RET_SUCCESS) {
- printf("%s%d: close failed x%x\n",
- (*tgt->dev_ops->driver_name)(TRUE), dev&0xff, ret);
- }
- }
- if (tgt->flags & TGT_REMOVABLE_MEDIA)
- tgt->flags &= ~TGT_ONLINE;
-
- return D_SUCCESS;
-}
-
-/* our own minphys */
-void rz_minphys(ior)
- io_req_t ior;
-{
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
- if (ior->io_count > scsi_per_target_virtual)
- ior->io_count = scsi_per_target_virtual;
-#endif /*MACH_KERNEL*/
-}
-
-int rz_read(dev, ior)
- int dev;
- io_req_t ior;
-{
- target_info_t *tgt;
-
- tgt = scsi_softc[rzcontroller(dev)]->target[rzslave(dev)];
-
-#ifdef MACH_KERNEL
- return block_io(tgt->dev_ops->strategy, rz_minphys, ior);
-#else /*MACH_KERNEL*/
- return physio(tgt->dev_ops->strategy, getbp(dev), dev, IO_READ, rz_minphys, ior);
-#endif /*MACH_KERNEL*/
-}
-
-int rz_write(dev, ior)
- int dev;
- io_req_t ior;
-{
- target_info_t *tgt;
-
- tgt = scsi_softc[rzcontroller(dev)]->target[rzslave(dev)];
-
- if (tgt->flags & TGT_READONLY)
- return D_INVALID_OPERATION;
-
-#ifdef MACH_KERNEL
- return block_io(tgt->dev_ops->strategy, rz_minphys, ior);
-#else /*MACH_KERNEL*/
- return physio(tgt->dev_ops->strategy, getbp(dev), dev, IO_WRITE, rz_minphys, ior);
-#endif /*MACH_KERNEL*/
-}
-
-int rz_get_status(dev, flavor, status, status_count)
- int dev;
- dev_flavor_t flavor;
- dev_status_t status;
- natural_t *status_count;
-{
- target_info_t *tgt;
-
- tgt = scsi_softc[rzcontroller(dev)]->target[rzslave(dev)];
-
- if (scsi_debug)
- printf("rz_get_status: x%x x%x x%x x%x\n",
- dev, flavor, status, *status_count);
- return (*tgt->dev_ops->get_status)(dev, tgt, flavor, status, status_count);
-}
-
-int rz_set_status(dev, flavor, status, status_count)
- int dev;
- dev_flavor_t flavor;
- dev_status_t status;
- natural_t status_count;
-{
- target_info_t *tgt;
-
- tgt = scsi_softc[rzcontroller(dev)]->target[rzslave(dev)];
-
- if (scsi_debug)
- printf("rz_set_status: x%x x%x x%x x%x\n",
- dev, flavor, status, status_count);
- return (*tgt->dev_ops->set_status)(dev, tgt, flavor, status, status_count);
-}
-
-/*
- * Routine to return information to kernel.
- */
-int
-rz_devinfo(dev, flavor, info)
- int dev;
- int flavor;
- char *info;
-{
- register int result;
-
- result = D_SUCCESS;
-
- switch (flavor) {
- /* Caller stupidity, should use device->bsize instead */
- case D_INFO_BLOCK_SIZE:
- *((int *) info) = scsi_softc[rzcontroller(dev)]->
- target[rzslave(dev)]->block_size;
- break;
- default:
- result = D_INVALID_OPERATION;
- }
-
- return(result);
-}
-
-void
-rz_simpleq_strategy(ior, start)
- io_req_t ior;
- void (*start)();
-{
- target_info_t *tgt;
- register scsi_softc_t *sc;
- scsi_ret_t ret;
- register int i = ior->io_unit;
- io_req_t head, tail;
- spl_t s;
-
- sc = scsi_softc[rzcontroller(i)];
- tgt = sc->target[rzslave(i)];
-
- ior->io_next = 0;
- ior->io_prev = 0;
-
- s = splbio();
- simple_lock(&tgt->target_lock);
- if (head = tgt->ior) {
- /* Queue it up at the end of the list */
- if (tail = head->io_prev)
- tail->io_next = ior;
- else
- head->io_next = ior;
- head->io_prev = ior; /* tail pointer */
- simple_unlock(&tgt->target_lock);
- } else {
- /* Was empty, start operation */
- tgt->ior = ior;
- simple_unlock(&tgt->target_lock);
- (*start)( tgt, FALSE);
- }
- splx(s);
-}
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
-
-rz_strategy(ior)
- io_req_t ior;
-{
- target_info_t *tgt;
- register int dev = ior->io_unit;
-
- tgt = scsi_softc[rzcontroller(dev)]->target[rzslave(dev)];
-
- return (*tgt->dev_ops->strategy)(ior);
-}
-
-
-#define IOCPARM_SIZE(c) (((c)>>16)&IOCPARM_MASK)
-#define IOC_WDSIZE(s) ((IOCPARM_SIZE(s))>>2)
-
-rz_ioctl(dev, cmd, data, flag)
-{
- io_return_t error;
- unsigned int count;
-
- count = IOC_WDSIZE(cmd);
- if (cmd & (IOC_VOID|IOC_IN)) {
- error = rz_set_status(dev, cmd, (dev_status_t)data, count);
- if (error)
- return (error);
- }
- if (cmd & IOC_OUT) {
- error = rz_get_status(dev, cmd, (dev_status_t *)data, &count);
- if (error)
- return (error);
- }
- return (0);
-}
-
-/* This is a very simple-minded config,
- * assumes we have << 8 disks per bus */
-#define NBUF (NSCSI*8)
-struct io_req rz_buffers[NBUF];
-
-static io_req_t
-getbp(dev)
-{
- io_req_t ior;
- int hash = minor(dev) >> 3;
-
- ior = &rz_buffers[hash];
- if (ior->io_op & IO_BUSY) {
- register io_req_t ior;
- for (ior = rz_buffers; ior < &rz_buffers[NBUF]; ior++)
- if ((ior->io_op & IO_BUSY) == 0)
- return ior;
-
- }
- return ior;
-}
-
-/*
- * This ugliness is only needed because of the
- * way the minor is encoded for tapes.
- */
-tz_open(dev, mode, ior)
- int dev;
- dev_mode_t mode;
- io_req_t ior;
-{
- io_return_t error;
-
- error = rz_open(TAPE_UNIT(dev), mode, ior);
- if(error)
- return error;
- if (TAPE_REWINDS(dev)) {
- scsi_softc_t *sc;
- target_info_t *tgt;
-
- rz_check(TAPE_UNIT(dev), &sc, &tgt);
- tgt->flags |= TGT_REWIND_ON_CLOSE;
- }
- return 0;
-}
-
-tz_close(dev) { return rz_close(TAPE_UNIT(dev));}
-tz_read(dev, ior) { return rz_read(TAPE_UNIT(dev), ior);}
-tz_write(dev, ior) { return rz_write(TAPE_UNIT(dev), ior);}
-tz_ioctl(dev, cmd, data, flag) { return rz_ioctl(TAPE_UNIT(dev), cmd, data, flag);}
-
-#endif /*MACH_KERNEL*/
-
-#endif (NSCSI>0)