summaryrefslogtreecommitdiff
path: root/scsi/adapters/scsi_53C700_hdw.c
diff options
context:
space:
mode:
Diffstat (limited to 'scsi/adapters/scsi_53C700_hdw.c')
-rw-r--r--scsi/adapters/scsi_53C700_hdw.c696
1 files changed, 0 insertions, 696 deletions
diff --git a/scsi/adapters/scsi_53C700_hdw.c b/scsi/adapters/scsi_53C700_hdw.c
deleted file mode 100644
index 61b5a3b..0000000
--- a/scsi/adapters/scsi_53C700_hdw.c
+++ /dev/null
@@ -1,696 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 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
- * 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 the
- * rights to redistribute these changes.
- */
-/*
- * File: scsi_53C700_hdw.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 8/91
- *
- * Bottom layer of the SCSI driver: chip-dependent functions
- *
- * This file contains the code that is specific to the NCR 53C700
- * SCSI chip (Host Bus Adapter in SCSI parlance): probing, start
- * operation, and interrupt routine.
- */
-
-
-#include <siop.h>
-#if NSIOP > 0
-#include <platforms.h>
-
-#include <mach/std_types.h>
-#include <sys/types.h>
-#include <chips/busses.h>
-#include <scsi/compat_30.h>
-#include <machine/machspl.h>
-
-#include <sys/syslog.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi2.h>
-#include <scsi/scsi_defs.h>
-
-#include <scsi/adapters/scsi_53C700.h>
-
-#ifdef PAD
-typedef struct {
- volatile unsigned char siop_scntl0; /* rw: SCSI control reg 0 */
- PAD(pad0);
- volatile unsigned char siop_scntl1; /* rw: SCSI control reg 1 */
- PAD(pad1);
- volatile unsigned char siop_sdid; /* rw: SCSI Destination ID */
- PAD(pad2);
- volatile unsigned char siop_sien; /* rw: SCSI Interrupt Enable */
- PAD(pad3);
- volatile unsigned char siop_scid; /* rw: SCSI Chip ID reg */
- PAD(pad4);
- volatile unsigned char siop_sxfer; /* rw: SCSI Transfer reg */
- PAD(pad5);
- volatile unsigned char siop_sodl; /* rw: SCSI Output Data Latch */
- PAD(pad6);
- volatile unsigned char siop_socl; /* rw: SCSI Output Control Latch */
- PAD(pad7);
- volatile unsigned char siop_sfbr; /* ro: SCSI First Byte Received */
- PAD(pad8);
- volatile unsigned char siop_sidl; /* ro: SCSI Input Data Latch */
- PAD(pad9);
- volatile unsigned char siop_sbdl; /* ro: SCSI Bus Data Lines */
- PAD(pad10);
- volatile unsigned char siop_sbcl; /* ro: SCSI Bus Control Lines */
- PAD(pad11);
- volatile unsigned char siop_dstat; /* ro: DMA status */
- PAD(pad12);
- volatile unsigned char siop_sstat0; /* ro: SCSI status reg 0 */
- PAD(pad13);
- volatile unsigned char siop_sstat1; /* ro: SCSI status reg 1 */
- PAD(pad14);
- volatile unsigned char siop_sstat2; /* ro: SCSI status reg 2 */
- PAD(pad15);
- volatile unsigned char siop_res1;
- PAD(pad16);
- volatile unsigned char siop_res2;
- PAD(pad17);
- volatile unsigned char siop_res3;
- PAD(pad18);
- volatile unsigned char siop_res4;
- PAD(pad19);
- volatile unsigned char siop_ctest0; /* ro: Chip test register 0 */
- PAD(pad20);
- volatile unsigned char siop_ctest1; /* ro: Chip test register 1 */
- PAD(pad21);
- volatile unsigned char siop_ctest2; /* ro: Chip test register 2 */
- PAD(pad22);
- volatile unsigned char siop_ctest3; /* ro: Chip test register 3 */
- PAD(pad23);
- volatile unsigned char siop_ctest4; /* rw: Chip test register 4 */
- PAD(pad24);
- volatile unsigned char siop_ctest5; /* rw: Chip test register 5 */
- PAD(pad25);
- volatile unsigned char siop_ctest6; /* rw: Chip test register 6 */
- PAD(pad26);
- volatile unsigned char siop_ctest7; /* rw: Chip test register 7 */
- PAD(pad27);
- volatile unsigned char siop_temp0; /* rw: Temporary Stack reg */
- PAD(pad28);
- volatile unsigned char siop_temp1;
- PAD(pad29);
- volatile unsigned char siop_temp2;
- PAD(pad30);
- volatile unsigned char siop_temp3;
- PAD(pad31);
- volatile unsigned char siop_dfifo; /* rw: DMA FIFO */
- PAD(pad32);
- volatile unsigned char siop_istat; /* rw: Interrupt Status reg */
- PAD(pad33);
- volatile unsigned char siop_res5;
- PAD(pad34);
- volatile unsigned char siop_res6;
- PAD(pad35);
- volatile unsigned char siop_dbc0; /* rw: DMA Byte Counter reg */
- PAD(pad36);
- volatile unsigned char siop_dbc1;
- PAD(pad37);
- volatile unsigned char siop_dbc2;
- PAD(pad38);
- volatile unsigned char siop_dcmd; /* rw: DMA Command Register */
- PAD(pad39);
- volatile unsigned char siop_dnad0; /* rw: DMA Next Address */
- PAD(pad40);
- volatile unsigned char siop_dnad1;
- PAD(pad41);
- volatile unsigned char siop_dnad2;
- PAD(pad42);
- volatile unsigned char siop_dnad3;
- PAD(pad43);
- volatile unsigned char siop_dsp0; /* rw: DMA SCRIPTS Pointer reg */
- PAD(pad44);
- volatile unsigned char siop_dsp1;
- PAD(pad45);
- volatile unsigned char siop_dsp2;
- PAD(pad46);
- volatile unsigned char siop_dsp3;
- PAD(pad47);
- volatile unsigned char siop_dsps0; /* rw: DMA SCRIPTS Pointer Save reg */
- PAD(pad48);
- volatile unsigned char siop_dsps1;
- PAD(pad49);
- volatile unsigned char siop_dsps2;
- PAD(pad50);
- volatile unsigned char siop_dsps3;
- PAD(pad51);
- volatile unsigned char siop_dmode; /* rw: DMA Mode reg */
- PAD(pad52);
- volatile unsigned char siop_res7;
- PAD(pad53);
- volatile unsigned char siop_res8;
- PAD(pad54);
- volatile unsigned char siop_res9;
- PAD(pad55);
- volatile unsigned char siop_res10;
- PAD(pad56);
- volatile unsigned char siop_dien; /* rw: DMA Interrupt Enable */
- PAD(pad57);
- volatile unsigned char siop_dwt; /* rw: DMA Watchdog Timer */
- PAD(pad58);
- volatile unsigned char siop_dcntl; /* rw: DMA Control reg */
- PAD(pad59);
- volatile unsigned char siop_res11;
- PAD(pad60);
- volatile unsigned char siop_res12;
- PAD(pad61);
- volatile unsigned char siop_res13;
- PAD(pad62);
- volatile unsigned char siop_res14;
- PAD(pad63);
-} siop_padded_regmap_t;
-#else
-typedef siop_regmap_t siop_padded_regmap_t;
-#endif
-
-/*
- * Macros to make certain things a little more readable
- */
-
-/* forward decls */
-
-int siop_reset_scsibus();
-boolean_t siop_probe_target();
-
-/*
- * State descriptor for this layer. There is one such structure
- * per (enabled) 53C700 interface
- */
-struct siop_softc {
- watchdog_t wd;
- siop_padded_regmap_t *regs; /* 53C700 registers */
- scsi_dma_ops_t *dma_ops; /* DMA operations and state */
- opaque_t dma_state;
-
- script_t script;
- int (*error_handler)();
- int in_count; /* amnt we expect to receive */
- int out_count; /* amnt we are going to ship */
-
- volatile char state;
-#define SIOP_STATE_BUSY 0x01 /* selecting or currently connected */
-#define SIOP_STATE_TARGET 0x04 /* currently selected as target */
-#define SIOP_STATE_COLLISION 0x08 /* lost selection attempt */
-#define SIOP_STATE_DMA_IN 0x10 /* tgt --> initiator xfer */
-
- unsigned char ntargets; /* how many alive on this scsibus */
- unsigned char done;
-
- scsi_softc_t *sc;
- target_info_t *active_target;
-
- target_info_t *next_target; /* trying to seize bus */
- queue_head_t waiting_targets;/* other targets competing for bus */
-
-} siop_softc_data[NSIOP];
-
-typedef struct siop_softc *siop_softc_t;
-
-siop_softc_t siop_softc[NSIOP];
-
-/*
- * Definition of the controller for the auto-configuration program.
- */
-
-int siop_probe(), scsi_slave(), scsi_attach(), siop_go(), siop_intr();
-
-caddr_t siop_std[NSIOP] = { 0 };
-struct bus_device *siop_dinfo[NSIOP*8];
-struct bus_ctlr *siop_minfo[NSIOP];
-struct bus_driver siop_driver =
- { siop_probe, scsi_slave, scsi_attach, siop_go, siop_std, "rz", siop_dinfo,
- "siop", siop_minfo, BUS_INTR_B4_PROBE};
-
-/*
- * Scripts
- */
-struct script
-siop_script_data_in[] = {
-},
-
-siop_script_data_out[] = {
-},
-
-siop_script_cmd[] = {
-},
-
-/* Synchronous transfer neg(oti)ation */
-
-siop_script_try_synch[] = {
-},
-
-/* Disconnect sequence */
-
-siop_script_disconnect[] = {
-};
-
-
-#define DEBUG
-#ifdef DEBUG
-
-siop_state(base)
- vm_offset_t base;
-{
- siop_padded_regmap_t *regs;
-....
- return 0;
-}
-siop_target_state(tgt)
- target_info_t *tgt;
-{
- if (tgt == 0)
- tgt = siop_softc[0]->active_target;
- if (tgt == 0)
- return 0;
- db_printf("@x%x: fl %x dma %X+%x cmd %x@%X id %x per %x off %x ior %X ret %X\n",
- tgt,
- tgt->flags, tgt->dma_ptr, tgt->transient_state.dma_offset, tgt->cur_cmd,
- tgt->cmd_ptr, tgt->target_id, tgt->sync_period, tgt->sync_offset,
- tgt->ior, tgt->done);
- if (tgt->flags & TGT_DISCONNECTED){
- script_t spt;
-
- spt = tgt->transient_state.script;
- db_printf("disconnected at ");
- db_printsym(spt,1);
- db_printf(": %x ", spt->condition);
- db_printsym(spt->action,1);
- db_printf(", ");
- db_printsym(tgt->transient_state.handler, 1);
- db_printf("\n");
- }
-
- return 0;
-}
-
-siop_all_targets(unit)
-{
- int i;
- target_info_t *tgt;
- for (i = 0; i < 8; i++) {
- tgt = siop_softc[unit]->sc->target[i];
- if (tgt)
- siop_target_state(tgt);
- }
-}
-
-siop_script_state(unit)
-{
- script_t spt = siop_softc[unit]->script;
-
- if (spt == 0) return 0;
- db_printsym(spt,1);
- db_printf(": %x ", spt->condition);
- db_printsym(spt->action,1);
- db_printf(", ");
- db_printsym(siop_softc[unit]->error_handler, 1);
- return 0;
-
-}
-
-#define PRINT(x) if (scsi_debug) printf x
-
-#define TRMAX 200
-int tr[TRMAX+3];
-int trpt, trpthi;
-#define TR(x) tr[trpt++] = x
-#define TRWRAP trpthi = trpt; trpt = 0;
-#define TRCHECK if (trpt > TRMAX) {TRWRAP}
-
-#define TRACE
-
-#ifdef TRACE
-
-#define LOGSIZE 256
-int siop_logpt;
-char siop_log[LOGSIZE];
-
-#define MAXLOG_VALUE 0x24
-struct {
- char *name;
- unsigned int count;
-} logtbl[MAXLOG_VALUE];
-
-static LOG(e,f)
- char *f;
-{
- siop_log[siop_logpt++] = (e);
- if (siop_logpt == LOGSIZE) siop_logpt = 0;
- if ((e) < MAXLOG_VALUE) {
- logtbl[(e)].name = (f);
- logtbl[(e)].count++;
- }
-}
-
-siop_print_log(skip)
- int skip;
-{
- register int i, j;
- register unsigned char c;
-
- for (i = 0, j = siop_logpt; i < LOGSIZE; i++) {
- c = siop_log[j];
- if (++j == LOGSIZE) j = 0;
- if (skip-- > 0)
- continue;
- if (c < MAXLOG_VALUE)
- db_printf(" %s", logtbl[c].name);
- else
- db_printf("-%d", c & 0x7f);
- }
- db_printf("\n");
- return 0;
-}
-
-siop_print_stat()
-{
- register int i;
- register char *p;
- for (i = 0; i < MAXLOG_VALUE; i++) {
- if (p = logtbl[i].name)
- printf("%d %s\n", logtbl[i].count, p);
- }
-}
-
-#else /* TRACE */
-#define LOG(e,f)
-#endif /* TRACE */
-
-#else /* DEBUG */
-#define PRINT(x)
-#define LOG(e,f)
-#define TR(x)
-#define TRCHECK
-#define TRWRAP
-#endif /* DEBUG */
-
-
-/*
- * Probe/Slave/Attach functions
- */
-
-/*
- * Probe routine:
- * Should find out (a) if the controller is
- * present and (b) which/where slaves are present.
- *
- * Implementation:
- * Send an identify msg to each possible target on the bus
- * except of course ourselves.
- */
-siop_probe(reg, ui)
- char *reg;
- struct bus_ctlr *ui;
-{
- int unit = ui->unit;
- siop_softc_t siop = &siop_softc_data[unit];
- int target_id, i;
- scsi_softc_t *sc;
- register siop_padded_regmap_t *regs;
- int s;
- boolean_t did_banner = FALSE;
- char *cmd_ptr;
- static char *here = "siop_probe";
-
- /*
- * We are only called if the chip is there,
- * but make sure anyways..
- */
- regs = (siop_padded_regmap_t *) (reg);
- if (check_memory(regs, 0))
- return 0;
-
-#if notyet
- /* Mappable version side */
- SIOP_probe(reg, ui);
-#endif
-
- /*
- * Initialize hw descriptor
- */
- siop_softc[unit] = siop;
- siop->regs = regs;
-
- if ((siop->dma_ops = (scsi_dma_ops_t *)siop_std[unit]) == 0)
- /* use same as unit 0 if undefined */
- siop->dma_ops = (scsi_dma_ops_t *)siop_std[0];
- siop->dma_state = (*siop->dma_ops->init)(unit, reg);
-
- queue_init(&siop->waiting_targets);
-
- sc = scsi_master_alloc(unit, siop);
- siop->sc = sc;
-
- sc->go = siop_go;
- sc->probe = siop_probe_target;
- sc->watchdog = scsi_watchdog;
- siop->wd.reset = siop_reset_scsibus;
-
-#ifdef MACH_KERNEL
- sc->max_dma_data = -1; /* unlimited */
-#else
- sc->max_dma_data = scsi_per_target_virtual;
-#endif
-
- /*
- * Reset chip
- */
- s = splbio();
- siop_reset(siop, TRUE);
-
- /*
- * Our SCSI id on the bus.
- */
-
- sc->initiator_id = my_scsi_id(unit);
- printf("%s%d: my SCSI id is %d", ui->name, unit, sc->initiator_id);
-
- /*
- * For all possible targets, see if there is one and allocate
- * a descriptor for it if it is there.
- */
- for (target_id = 0; target_id < 8; target_id++) {
-
- register unsigned csr, dsr;
- scsi_status_byte_t status;
-
- /* except of course ourselves */
- if (target_id == sc->initiator_id)
- continue;
-
- .....
-
- printf(",%s%d", did_banner++ ? " " : " target(s) at ",
- target_id);
-
- .....
-
-
- /*
- * Found a target
- */
- siop->ntargets++;
- {
- register target_info_t *tgt;
-
- tgt = scsi_slave_alloc(unit, target_id, siop);
-
- tgt->cmd_ptr = ...
- tgt->dma_ptr = ...
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
- fdma_init(&tgt->fdma, scsi_per_target_virtual);
-#endif /*MACH_KERNEL*/
- }
- }
- printf(".\n");
-
- splx(s);
- return 1;
-}
-
-boolean_t
-siop_probe_target(sc, tgt, ior)
- scsi_softc_t *sc;
- target_info_t *tgt;
- io_req_t ior;
-{
- siop_softc_t siop = siop_softc[sc->masterno];
- boolean_t newlywed;
-
- newlywed = (tgt->cmd_ptr == 0);
- if (newlywed) {
- /* desc was allocated afresh */
-
- tgt->cmd_ptr = ...
- tgt->dma_ptr = ...
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
- fdma_init(&tgt->fdma, scsi_per_target_virtual);
-#endif /*MACH_KERNEL*/
-
- }
-
- if (scsi_inquiry(sc, tgt, SCSI_INQ_STD_DATA) == SCSI_RET_DEVICE_DOWN)
- return FALSE;
-
- tgt->flags = TGT_ALIVE;
- return TRUE;
-}
-
-
-static siop_wait(preg, until)
- volatile unsigned char *preg;
-{
- int timeo = 1000000;
- while ((*preg & until) != until) {
- delay(1);
- if (!timeo--) {
- printf("siop_wait TIMEO with x%x\n", *preg);
- break;
- }
- }
- return *preg;
-}
-
-
-siop_reset(siop, quickly)
- siop_softc_t siop;
- boolean_t quickly;
-{
- register siop_padded_regmap_t *regs = siop->regs;
-
- ....
-
- if (quickly)
- return;
-
- /*
- * reset the scsi bus, the interrupt routine does the rest
- * or you can call siop_bus_reset().
- */
- ....
-
-}
-
-/*
- * Operational functions
- */
-
-/*
- * Start a SCSI command on a target
- */
-siop_go(sc, tgt, cmd_count, in_count, cmd_only)
- scsi_softc_t *sc;
- target_info_t *tgt;
- boolean_t cmd_only;
-{
- siop_softc_t siop;
- register int s;
- boolean_t disconn;
- script_t scp;
- boolean_t (*handler)();
-
- LOG(1,"go");
-
- siop = (siop_softc_t)tgt->hw_state;
-
- ....
-}
-
-siop_attempt_selection(siop)
- siop_softc_t siop;
-{
- target_info_t *tgt;
- register int out_count;
- siop_padded_regmap_t *regs;
- register int cmd;
- boolean_t ok;
- scsi_ret_t ret;
-
- regs = siop->regs;
- tgt = siop->next_target;
-
- LOG(4,"select");
- LOG(0x80+tgt->target_id,0);
-
- /*
- * Init bus state variables and set registers.
- */
- siop->active_target = tgt;
-
- /* reselection pending ? */
- ......
-}
-
-/*
- * Interrupt routine
- * Take interrupts from the chip
- *
- * Implementation:
- * Move along the current command's script if
- * all is well, invoke error handler if not.
- */
-siop_intr(unit)
-{
- register siop_softc_t siop;
- register script_t scp;
- register unsigned csr, bs, cmd;
- register siop_padded_regmap_t *regs;
- boolean_t try_match;
-#if notyet
- extern boolean_t rz_use_mapped_interface;
-
- if (rz_use_mapped_interface)
- return SIOP_intr(unit);
-#endif
-
- LOG(5,"\n\tintr");
-
- siop = siop_softc[unit];
- regs = siop->regs;
-
- /* ack interrupt */
- ....
-}
-
-
-siop_target_intr(siop)
- register siop_softc_t siop;
-{
- panic("SIOP: TARGET MODE !!!\n");
-}
-
-/*
- * All the many little things that the interrupt
- * routine might switch to
- */
-
-#endif /*NSIOP > 0*/
-