summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/tc/asc.c2160
-rw-r--r--sys/dev/tc/asc_ioasic.c330
-rw-r--r--sys/dev/tc/asc_tc.c192
-rw-r--r--sys/dev/tc/ascvar.h93
-rw-r--r--sys/dev/tc/if_le_ibus.c193
-rw-r--r--sys/dev/tc/tcvar.h22
6 files changed, 3 insertions, 2987 deletions
diff --git a/sys/dev/tc/asc.c b/sys/dev/tc/asc.c
deleted file mode 100644
index a7baa8eb1aa..00000000000
--- a/sys/dev/tc/asc.c
+++ /dev/null
@@ -1,2160 +0,0 @@
-/* $OpenBSD: asc.c,v 1.19 2001/06/25 15:27:59 aaron Exp $ */
-/* $NetBSD: asc.c,v 1.46 1998/05/08 15:39:01 mhitch Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Ralph Campbell and Rick Macklem.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)asc.c 8.3 (Berkeley) 7/3/94
- */
-
-/*
- * 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.
- */
-
-/*
- * HISTORY
- * Log: scsi_53C94_hdw.c,v
- * Revision 2.5 91/02/05 17:45:07 mrt
- * Added author notices
- * [91/02/04 11:18:43 mrt]
- *
- * Changed to use new Mach copyright
- * [91/02/02 12:17:20 mrt]
- *
- * Revision 2.4 91/01/08 15:48:24 rpd
- * Added continuation argument to thread_block.
- * [90/12/27 rpd]
- *
- * Revision 2.3 90/12/05 23:34:48 af
- * Recovered from pmax merge.. and from the destruction of a disk.
- * [90/12/03 23:40:40 af]
- *
- * Revision 2.1.1.1 90/11/01 03:39:09 af
- * Created, from the DEC specs:
- * "PMAZ-AA TURBOchannel SCSI Module Functional Specification"
- * Workstation Systems Engineering, Palo Alto, CA. Aug 27, 1990.
- * And from the NCR data sheets
- * "NCR 53C94, 53C95, 53C96 Advances SCSI Controller"
- * [90/09/03 af]
- */
-
-/*
- * File: scsi_53C94_hdw.h
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 9/90
- *
- * Bottom layer of the SCSI driver: chip-dependent functions
- *
- * This file contains the code that is specific to the NCR 53C94
- * SCSI chip (Host Bus Adapter in SCSI parlance): probing, start
- * operation, and interrupt routine.
- */
-
-/*
- * This layer works based on small simple 'scripts' that are installed
- * at the start of the command and drive the chip to completion.
- * The idea comes from the specs of the NCR 53C700 'script' processor.
- *
- * There are various reasons for this, mainly
- * - Performance: identify the common (successful) path, and follow it;
- * at interrupt time no code is needed to find the current status
- * - Code size: it should be easy to compact common operations
- * - Adaptability: the code skeleton should adapt to different chips without
- * terrible complications.
- * - Error handling: and it is easy to modify the actions performed
- * by the scripts to cope with strange but well identified sequences
- *
- */
-
-#include <asc.h>
-#if NASC > 0
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/timeout.h>
-#include <sys/dkstat.h>
-#include <sys/buf.h>
-#include <sys/conf.h>
-#include <sys/errno.h>
-#include <sys/kernel.h>
-#include <sys/device.h>
-#include <sys/reboot.h>
-
-#include <dev/tc/tcvar.h>
-#include <dev/tc/ioasicvar.h>
-
-#include <scsi/scsi_all.h>
-#include <scsi/scsiconf.h>
-
-#include <machine/cpu.h>
-#include <machine/autoconf.h>
-#include <machine/bus.h>
-
-#include <pmax/dev/device.h>
-#include <pmax/dev/scsi.h>
-#include <pmax/dev/ascreg.h>
-
-#include <pmax/pmax/asic.h>
-#include <pmax/pmax/kmin.h>
-
-
-/*#define readback(a) { register int foo; wbflush(); foo = (a); }*/
-#define readback(a) { register int foo; foo = (a); }
-
-/*
- * In 4ns ticks.
- */
-int asc_to_scsi_period[] = {
- 32,
- 33,
- 34,
- 35,
- 5,
- 5,
- 6,
- 7,
- 8,
- 9,
- 10,
- 11,
- 12,
- 13,
- 14,
- 15,
- 16,
- 17,
- 18,
- 19,
- 20,
- 21,
- 22,
- 23,
- 24,
- 25,
- 26,
- 27,
- 28,
- 29,
- 30,
- 31,
-};
-
-/*
- * Debugging log of SCSI operations.
- */
-
-#ifdef DEBUG
-int asc_debug = 1;
-int asc_debug_cmd;
-int asc_debug_bn;
-int asc_debug_sz;
-#define NLOG 32
-struct asc_log {
- u_int status;
- u_char state;
- u_char msg;
- int target;
- int resid;
-} asc_log[NLOG], *asc_logp = asc_log;
-#define PACK(unit, status, ss, ir) \
- ((unit << 24) | (status << 16) | (ss << 8) | ir)
-void asc_DumpLog __P((char *str));
-#endif
-
-
-/*
- * Script, scsi state, and device softc structure declarations.
- * script pointers occur in both scsi state and the softc,
- * so they are defined first.
- */
-
-
-/*
- * Scripts are entries in a state machine table.
- * A script has four parts: a pre-condition, an action, a command to the chip,
- * and an index into asc_scripts for the next state. The first triggers error
- * handling if not satisfied and in our case it is formed by the
- * values of the interrupt register and status register, this
- * basically captures the phase of the bus and the TC and BS
- * bits. The action part is just a function pointer, and the
- * command is what the 53C94 should be told to do at the end
- * of the action processing. This command is only issued and the
- * script proceeds if the action routine returns TRUE.
- * See asc_intr() for how and where this is all done.
- */
-struct asc_softc;
-typedef struct script {
- int condition; /* expected state at interrupt time */
-
- int (*action) /* extra operations */
- __P((register struct asc_softc *asc, register int status,
- register int ss, register int ir));
- int command; /* command to the chip */
- struct script *next; /* index into asc_scripts for next state */
-} script_t;
-
-
-/*
- * script definitions
- */
-
-/* Matching on the condition value */
-#define SCRIPT_MATCH(ir, csr) ((ir) | (((csr) & 0x67) << 8))
-
-/*
- * A typedef for a script function, to use in forward declarations.
- */
-typedef int
-script_fn_t __P((register struct asc_softc *asc, register int status,
- register int ss, register int ir));
-
-
-/* forward decls of script actions */
-static script_fn_t script_nop; /* when nothing needed */
-static script_fn_t asc_end; /* all come to an end */
-static script_fn_t asc_get_status; /* get status from target */
-static script_fn_t asc_dma_in; /* start reading data from target */
-static script_fn_t asc_last_dma_in; /* cleanup after all data is read */
-static script_fn_t asc_resume_in; /* resume data in after a message */
-static script_fn_t asc_resume_dma_in; /* resume DMA after a disconnect */
-static script_fn_t asc_dma_out; /* send data to target via dma */
-static script_fn_t asc_last_dma_out; /* cleanup after all data is written */
-static script_fn_t asc_resume_out; /* resume data out after a message */
-static script_fn_t asc_resume_dma_out; /* resume DMA after a disconnect */
-static script_fn_t asc_sendsync; /* negotiate sync xfer */
-static script_fn_t asc_replysync; /* negotiate sync xfer */
-static script_fn_t asc_msg_in; /* process a message byte */
-static script_fn_t asc_disconnect; /* process an expected disconnect */
-
-/* Define the index into asc_scripts for various state transitions */
-#define SCRIPT_DATA_IN 0
-#define SCRIPT_CONTINUE_IN 2
-#define SCRIPT_DATA_OUT 3
-#define SCRIPT_CONTINUE_OUT 5
-#define SCRIPT_SIMPLE 6
-#define SCRIPT_GET_STATUS 7
-#define SCRIPT_DONE 8
-#define SCRIPT_MSG_IN 9
-#define SCRIPT_REPLY_SYNC 11
-#define SCRIPT_TRY_SYNC 12
-#define SCRIPT_DISCONNECT 15
-#define SCRIPT_RESEL 16
-#define SCRIPT_RESUME_IN 17
-#define SCRIPT_RESUME_DMA_IN 18
-#define SCRIPT_RESUME_OUT 19
-#define SCRIPT_RESUME_DMA_OUT 20
-#define SCRIPT_RESUME_NO_DATA 21
-
-/*
- * Scripts
- */
-script_t asc_scripts[] = {
- /* start data in */
- {SCRIPT_MATCH(ASC_INT_FC | ASC_INT_BS, SCSI_PHASE_DATAI), /* 0 */
- asc_dma_in, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
- &asc_scripts[SCRIPT_DATA_IN + 1]},
- {SCRIPT_MATCH(ASC_INT_BS, SCSI_PHASE_STATUS), /* 1 */
- asc_last_dma_in, ASC_CMD_I_COMPLETE,
- &asc_scripts[SCRIPT_GET_STATUS]},
-
- /* continue data in after a chunk is finished */
- {SCRIPT_MATCH(ASC_INT_BS, SCSI_PHASE_DATAI), /* 2 */
- asc_dma_in, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
- &asc_scripts[SCRIPT_DATA_IN + 1]},
-
- /* start data out */
- {SCRIPT_MATCH(ASC_INT_FC | ASC_INT_BS, SCSI_PHASE_DATAO), /* 3 */
- asc_dma_out, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
- &asc_scripts[SCRIPT_DATA_OUT + 1]},
- {SCRIPT_MATCH(ASC_INT_BS, SCSI_PHASE_STATUS), /* 4 */
- asc_last_dma_out, ASC_CMD_I_COMPLETE,
- &asc_scripts[SCRIPT_GET_STATUS]},
-
- /* continue data out after a chunk is finished */
- {SCRIPT_MATCH(ASC_INT_BS, SCSI_PHASE_DATAO), /* 5 */
- asc_dma_out, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
- &asc_scripts[SCRIPT_DATA_OUT + 1]},
-
- /* simple command with no data transfer */
- {SCRIPT_MATCH(ASC_INT_FC | ASC_INT_BS, SCSI_PHASE_STATUS), /* 6 */
- script_nop, ASC_CMD_I_COMPLETE,
- &asc_scripts[SCRIPT_GET_STATUS]},
-
- /* get status and finish command */
- {SCRIPT_MATCH(ASC_INT_FC, SCSI_PHASE_MSG_IN), /* 7 */
- asc_get_status, ASC_CMD_MSG_ACPT,
- &asc_scripts[SCRIPT_DONE]},
- {SCRIPT_MATCH(ASC_INT_DISC, 0), /* 8 */
- asc_end, ASC_CMD_NOP,
- &asc_scripts[SCRIPT_DONE]},
-
- /* message in */
- {SCRIPT_MATCH(ASC_INT_FC, SCSI_PHASE_MSG_IN), /* 9 */
- asc_msg_in, ASC_CMD_MSG_ACPT,
- &asc_scripts[SCRIPT_MSG_IN + 1]},
- {SCRIPT_MATCH(ASC_INT_BS, SCSI_PHASE_MSG_IN), /* 10 */
- script_nop, ASC_CMD_XFER_INFO,
- &asc_scripts[SCRIPT_MSG_IN]},
-
- /* send synchonous negotiation reply */
- {SCRIPT_MATCH(ASC_INT_BS, SCSI_PHASE_MSG_OUT), /* 11 */
- asc_replysync, ASC_CMD_XFER_INFO,
- &asc_scripts[SCRIPT_REPLY_SYNC]},
-
- /* try to negotiate synchonous transfer parameters */
- {SCRIPT_MATCH(ASC_INT_FC | ASC_INT_BS, SCSI_PHASE_MSG_OUT), /* 12 */
- asc_sendsync, ASC_CMD_XFER_INFO,
- &asc_scripts[SCRIPT_TRY_SYNC + 1]},
- {SCRIPT_MATCH(ASC_INT_BS, SCSI_PHASE_MSG_IN), /* 13 */
- script_nop, ASC_CMD_XFER_INFO,
- &asc_scripts[SCRIPT_MSG_IN]},
- {SCRIPT_MATCH(ASC_INT_BS, SCSI_PHASE_COMMAND), /* 14 */
- script_nop, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
- &asc_scripts[SCRIPT_RESUME_NO_DATA]},
-
- /* handle a disconnect */
- {SCRIPT_MATCH(ASC_INT_DISC, SCSI_PHASE_DATAO), /* 15 */
- asc_disconnect, ASC_CMD_ENABLE_SEL,
- &asc_scripts[SCRIPT_RESEL]},
-
- /* reselect sequence: this is just a placeholder so match fails */
- {SCRIPT_MATCH(0, SCSI_PHASE_MSG_IN), /* 16 */
- script_nop, ASC_CMD_MSG_ACPT,
- &asc_scripts[SCRIPT_RESEL]},
-
- /* resume data in after a message */
- {SCRIPT_MATCH(ASC_INT_BS, SCSI_PHASE_DATAI), /* 17 */
- asc_resume_in, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
- &asc_scripts[SCRIPT_DATA_IN + 1]},
-
- /* resume partial DMA data in after a message */
- {SCRIPT_MATCH(ASC_INT_BS, SCSI_PHASE_DATAI), /* 18 */
- asc_resume_dma_in, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
- &asc_scripts[SCRIPT_DATA_IN + 1]},
-
- /* resume data out after a message */
- {SCRIPT_MATCH(ASC_INT_BS, SCSI_PHASE_DATAO), /* 19 */
- asc_resume_out, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
- &asc_scripts[SCRIPT_DATA_OUT + 1]},
-
- /* resume partial DMA data out after a message */
- {SCRIPT_MATCH(ASC_INT_BS, SCSI_PHASE_DATAO), /* 20 */
- asc_resume_dma_out, ASC_CMD_XFER_INFO | ASC_CMD_DMA,
- &asc_scripts[SCRIPT_DATA_OUT + 1]},
-
- /* resume after a message when there is no more data */
- {SCRIPT_MATCH(ASC_INT_BS, SCSI_PHASE_STATUS), /* 21 */
- script_nop, ASC_CMD_I_COMPLETE,
- &asc_scripts[SCRIPT_GET_STATUS]},
-};
-
-
-#include <dev/tc/ascvar.h>
-
-/*
- * Internal forward declarations.
- */
-static void asc_reset __P((asc_softc_t asc, asc_regmap_t *regs));
-static void asc_startcmd __P((asc_softc_t asc, int target));
-static void asc_timeout __P((void *arg));
-
-#ifdef USE_NEW_SCSI
-/* Glue to the machine-independent scsi */
-struct scsi_adapter asc_switch = {
- NULL, /* XXX - asc_scsi_cmd */
-/*XXX*/ minphys, /* no max transfer size; DMA engine deals */
- NULL,
- NULL,
-};
-
-struct scsi_device asc_dev = {
-/*XXX*/ NULL, /* Use default error handler */
-/*XXX*/ NULL, /* have a queue, served by this */
-/*XXX*/ NULL, /* have no async handler */
-/*XXX*/ NULL, /* Use default 'done' routine */
-};
-#endif
-
-/*
- * Definition of the controller for the old auto-configuration program.
- */
-void asc_start __P((register ScsiCmd *scsicmd));
-int asc_intr __P ((void *asc));
-struct pmax_driver ascdriver = {
- "asc", NULL, asc_start, 0, asc_intr,
-};
-
-void asc_minphys __P((struct buf *bp));
-
-extern struct cfdriver asc_cd;
-struct cfdriver asc_cd = {
- NULL, "asc", DV_DULL
-};
-
-/*
- * bus-parent shared attach function
- */
-void
-ascattach(asc, bus_speed)
- register asc_softc_t asc;
- int bus_speed;
-{
- register asc_regmap_t *regs;
- int id, s;
-
- int unit;
-
- unit = asc->sc_dev.dv_unit;
-
- /*
- * Set up machine dependencies.
- * (1) timing based on turbochannel frequency
- */
-
- /* dma setup done in parent-specific attach code */
-
- /*
- * Now for timing. The 3max has a 25Mhz tb whereas the 3min and
- * maxine are 12.5Mhz.
- */
- switch (bus_speed) {
- case ASC_SPEED_25_MHZ:
- asc->min_period = ASC_MIN_PERIOD25;
- asc->max_period = ASC_MAX_PERIOD25;
- asc->ccf = ASC_CCF(25);
- asc->timeout_250 = ASC_TIMEOUT_250(25, asc->ccf);
- asc->tb_ticks = 10;
- break;
-
- case ASC_SPEED_12_5_MHZ:
- default:
- asc->min_period = ASC_MIN_PERIOD12;
- asc->max_period = ASC_MAX_PERIOD12;
- asc->ccf = ASC_CCF(13);
- asc->timeout_250 = ASC_TIMEOUT_250(13, asc->ccf);
- asc->tb_ticks = 20;
- break;
- };
-
- asc->state = ASC_STATE_IDLE;
- asc->target = -1;
-
- regs = asc->regs;
-
- /*
- * Reset chip, fully. Note that interrupts are already enabled.
- */
- s = splbio();
-
- /* preserve our ID for now */
- asc->sc_id = regs->asc_cnfg1 & ASC_CNFG1_MY_BUS_ID;
- asc->myidmask = ~(1 << asc->sc_id);
-
- asc_reset(asc, regs);
-
- /*
- * Our SCSI id on the bus.
- * The user can set this via the prom on 3maxen/pmaxen.
- * If this changes it is easy to fix: make a default that
- * can be changed as boot arg.
- */
-#ifdef unneeded
- regs->asc_cnfg1 = (regs->asc_cnfg1 & ~ASC_CNFG1_MY_BUS_ID) |
- (scsi_initiator_id[unit] & 0x7);
- asc->sc_id = regs->asc_cnfg1 & ASC_CNFG1_MY_BUS_ID;
-#endif
-
- id = asc->sc_id;
- splx(s);
-
- /* Hack for old-sytle SCSI-device probe */
- (void) pmax_add_scsi(&ascdriver, unit);
-
- printf(": target %d\n", id);
-
-
-#ifdef USE_NEW_SCSI
- /*
- * fill in the prototype scsi_link.
- */
- asc->sc_link.channel = SCSI_CHANNEL_ONLY_ONE;
- asc->sc_link.adapter_softc = asc;
- asc->sc_link.adapter_target = asc->sc_id;
- asc->sc_link.adapter = &asc_switch;
- asc->sc_link.device = &asc_dev;
- asc->sc_link.openings = 2;
-
- /*
- * Now try to attach all the sub-devices.
- */
- config_found(self, &asc->sc_link, scsiprint);
-
-#endif /* USE_NEW_SCSI */
-}
-
-/*
- * Per Fogelstrom's SCSI Driver breaks down request transfer size.
- */
-void
-asc_minphys(bp)
- struct buf *bp;
-{
- /*XXX*/
-}
-
-/*
- * Start activity on a SCSI device.
- * We maintain information on each device separately since devices can
- * connect/disconnect during an operation.
- */
-void
-asc_start(scsicmd)
- register ScsiCmd *scsicmd; /* command to start */
-{
- register struct pmax_scsi_device *sdp = scsicmd->sd;
- register asc_softc_t asc = asc_cd.cd_devs[sdp->sd_ctlr];
- int s;
-
- s = splbio();
- /*
- * Check if another command is already in progress.
- * We may have to change this if we allow SCSI devices with
- * separate LUNs.
- */
- if (asc->cmd[sdp->sd_drive]) {
- printf("asc %d: device %s busy at start\n",
- sdp->sd_ctlr, /*XXX*/
- sdp->sd_driver->d_name);
- (*sdp->sd_driver->d_done)(scsicmd->unit, EBUSY,
- scsicmd->buflen, 0);
- splx(s);
- }
- asc->cmd[sdp->sd_drive] = scsicmd;
- /*
- * Kludge: use a 60 second timeout if data is being transferred,
- * otherwise use a 30 minute timeout.
- */
- timeout_set(&asc->asc_timo, asc_timeout, scsicmd);
- timeout_add(&asc->asc_timo, hz * (scsicmd->buflen == 0 ? 1800 : 60));
- asc_startcmd(asc, sdp->sd_drive);
- splx(s);
-}
-
-
-#ifdef USE_NEW_SCSI
-int
-asc_poll(asc, target)
- struct asc_softc *asc;
- int target;
-{
- struct scsi_xfer *scsicmd = asc->cmd[target];
- int count = scsicmd->timeout * 10;
-
- while(count) {
- if(asc->regs->asc_status &ASC_CSR_INT) {
- asc_intr(asc);
- }
- if(scsicmd->flags & ITSDONE)
- break;
- DELAY(5);
- count--;
- }
- if(count == 0) {
- scsicmd->error = XS_TIMEOUT;
- asc_end(asc, 0, 0, 0);
- }
- return COMPLETE;
-}
-#endif /*USE_NEW_SCSI*/
-
-static void
-asc_reset(asc, regs)
- asc_softc_t asc;
- asc_regmap_t *regs;
-{
-
- /*
- * Reset chip and wait till done
- */
- regs->asc_cmd = ASC_CMD_RESET;
- tc_syncbus(); DELAY(25);
-
- /* spec says this is needed after reset */
- regs->asc_cmd = ASC_CMD_NOP;
- tc_syncbus(); DELAY(25);
-
- /*
- * Set up various chip parameters
- */
- regs->asc_ccf = asc->ccf;
- tc_syncbus(); DELAY(25);
- regs->asc_sel_timo = asc->timeout_250;
- /* restore our ID */
- regs->asc_cnfg1 = asc->sc_id | ASC_CNFG1_P_CHECK;
- /* include ASC_CNFG2_SCSI2 if you want to allow SCSI II commands */
- regs->asc_cnfg2 = /* ASC_CNFG2_RFB | ASC_CNFG2_SCSI2 | */ ASC_CNFG2_EPL;
- regs->asc_cnfg3 = 0;
- /* zero anything else */
- ASC_TC_PUT(regs, 0);
- regs->asc_syn_p = asc->min_period;
- regs->asc_syn_o = 0; /* async for now */
- tc_mb();
-}
-
-/*
- * Start a SCSI command on a target.
- */
-static void
-asc_startcmd(asc, target)
- asc_softc_t asc;
- int target;
-{
- register asc_regmap_t *regs;
- register ScsiCmd *scsicmd;
- register State *state;
- int len;
-
- /*
- * See if another target is currently selected on this SCSI bus.
- */
- if (asc->target >= 0)
- return;
-
- regs = asc->regs;
-
- /*
- * If a reselection is in progress, it is Ok to ignore it since
- * the ASC will automatically cancel the command and flush
- * the FIFO if the ASC is reselected before the command starts.
- * If we try to use ASC_CMD_DISABLE_SEL, we can hang the system if
- * a reselect occurs before starting the command.
- */
-
- asc->state = ASC_STATE_BUSY;
- asc->target = target;
-
- /* cache some pointers */
- scsicmd = asc->cmd[target];
- state = &asc->st[target];
-
-#ifdef DEBUG
- if (asc_debug > 1) {
- printf("asc_startcmd: %s target %d cmd %x len %d\n",
- scsicmd->sd->sd_driver->d_name, target,
- scsicmd->cmd[0], scsicmd->buflen);
- }
-#endif
-
- /* Try to avoid reselect collisions */
- if ((regs->asc_status & (ASC_CSR_INT|SCSI_PHASE_MSG_IN)) ==
- (ASC_CSR_INT|SCSI_PHASE_MSG_IN)) {
-/* printf("asc_startcmd: possible reselect in progress\n"); */
- return;
- }
-
- /*
- * Init the chip and target state.
- */
- state->flags = state->flags & DID_SYNC;
- state->error = 0;
- state->script = (script_t *)0;
- state->msg_out = SCSI_NO_OP;
-
- len = scsicmd->cmdlen;
- state->dmalen = len;
-
- /* check for simple SCSI command with no data transfer */
- if ((state->buflen = scsicmd->buflen) == 0) {
- /* check for sync negotiation */
- if ((scsicmd->flags & SCSICMD_USE_SYNC) &&
- !(state->flags & DID_SYNC)) {
- asc->script = &asc_scripts[SCRIPT_TRY_SYNC];
- state->flags |= TRY_SYNC;
- } else
- asc->script = &asc_scripts[SCRIPT_SIMPLE];
- state->buf = (char *)0;
- } else if (scsicmd->flags & SCSICMD_DATA_TO_DEVICE) {
- asc->script = &asc_scripts[SCRIPT_DATA_OUT];
- state->buf = scsicmd->buf;
- state->flags |= DMA_OUT;
- } else {
- asc->script = &asc_scripts[SCRIPT_DATA_IN];
- state->buf = scsicmd->buf;
- state->flags |= DMA_IN;
- }
-
-#ifdef DEBUG
- asc_debug_cmd = scsicmd->cmd[0];
- if (scsicmd->cmd[0] == SCSI_READ_EXT) {
- asc_debug_bn = (scsicmd->cmd[2] << 24) |
- (scsicmd->cmd[3] << 16) |
- (scsicmd->cmd[4] << 8) |
- scsicmd->cmd[5];
- asc_debug_sz = (scsicmd->cmd[7] << 8) | scsicmd->cmd[8];
- }
- asc_logp->status = PACK(asc->sc_dev.dv_unit, 0, 0, asc_debug_cmd);
- asc_logp->target = asc->target;
- asc_logp->state = asc->script - asc_scripts;
- asc_logp->msg = SCSI_DIS_REC_IDENTIFY;
- asc_logp->resid = scsicmd->buflen;
- if (++asc_logp >= &asc_log[NLOG])
- asc_logp = asc_log;
-#endif
-
- /* initialize the DMA */
- len = (*asc->dma_start)(asc, state, scsicmd->cmd, ASCDMA_WRITE,
- len, 0);
- ASC_TC_PUT(regs, len);
- readback(regs->asc_cmd);
-
- regs->asc_dbus_id = target;
- readback(regs->asc_dbus_id);
- regs->asc_syn_p = state->sync_period;
- readback(regs->asc_syn_p);
- regs->asc_syn_o = state->sync_offset;
- readback(regs->asc_syn_o);
-
- /* Try to avoid reselect collisions */
- if ((regs->asc_status & (ASC_CSR_INT|SCSI_PHASE_MSG_IN)) ==
- (ASC_CSR_INT|SCSI_PHASE_MSG_IN)) {
-/* printf("asc_startcmd: reselect in progress (before select)\n");*/
- return;
- }
-
- /* preload the FIFO with the message to be sent */
- regs->asc_fifo = SCSI_DIS_REC_IDENTIFY;
- tc_mb();
-
- if (state->flags & TRY_SYNC)
- regs->asc_cmd = len = ASC_CMD_SEL_ATN_STOP;
- else
- regs->asc_cmd = len = ASC_CMD_SEL_ATN | ASC_CMD_DMA;
- readback(regs->asc_cmd);
-
- /* Try to avoid reselect collisions */
- if ((regs->asc_status & (ASC_CSR_INT|SCSI_PHASE_MSG_IN)) ==
- (ASC_CSR_INT|SCSI_PHASE_MSG_IN)) {
-/* printf("asc_startcmd: reselect in progress after select\n");*/
- return;
- } else {
- /*
- * Here's a potentially nasty but infrequent problem: a
- * reselect may have occurred, but did not interrupt.
- */
- if (regs->asc_cmd != len &&
- regs->asc_cmd == (ASC_CMD_NOP|ASC_CMD_DMA)) {
- if ((regs->asc_status & ASC_CSR_INT) == 0) {
- delay(250);
- if (regs->asc_status == SCSI_PHASE_MSG_IN) {
- printf("asc_startcmd: reselect failed to interrupt?\n");
- /* XXXX THIS NEEDS FIXING */
- }
- }
- }
- }
-
-}
-
-/*
- * Interrupt routine
- * Take interrupts from the chip
- *
- * Implementation:
- * Move along the current command's script if
- * all is well, invoke error handler if not.
- */
-int
-asc_intr(sc)
- void *sc;
-{
- register asc_softc_t asc = (asc_softc_t) sc;
- register asc_regmap_t *regs = asc->regs;
- register State *state;
- register script_t *scpt;
- register int ss, ir, status;
- register unsigned char cmd_was;
- static int ill_cmd_count = 0; /* XXX */
-
- /* collect ephemeral information */
- status = regs->asc_status;
-again:
- ss = regs->asc_ss;
- cmd_was = regs->asc_cmd;
-
- /* drop spurious interrupts */
- if ((status & ASC_CSR_INT) == 0)
- return (-1); /* XXX */
-
- ir = regs->asc_intr; /* this resets the previous two: i.e.,*/
- /* this re-latches CSR (and SSTEP) */
- scpt = asc->script;
-
-
-#ifdef DEBUG
- asc_logp->status = PACK(asc->sc_dev.dv_unit, status, ss, ir);
- asc_logp->target = (asc->state == ASC_STATE_BUSY) ? asc->target : -1;
- asc_logp->state = scpt - asc_scripts;
- asc_logp->msg = cmd_was;
- asc_logp->resid = 0;
- if (++asc_logp >= &asc_log[NLOG])
- asc_logp = asc_log;
- if (asc_debug > 2)
- printf("asc_intr: status %x ss %x ir %x cond %d:%x\n",
- status, ss, ir, scpt - asc_scripts, scpt->condition);
-#endif
-
- /* This must be done withing 250msec of disconnect */
- if (ir & ASC_INT_DISC) {
- regs->asc_cmd = ASC_CMD_ENABLE_SEL;
- readback(regs->asc_cmd);
- }
-
- /* check the expected state */
- if (SCRIPT_MATCH(ir, status) == scpt->condition) {
- /*
- * Perform the appropriate operation, then proceed.
- */
- if ((*scpt->action)(asc, status, ss, ir)) {
- regs->asc_cmd = scpt->command;
- readback(regs->asc_cmd);
- asc->script = scpt->next;
- }
- goto done;
- }
-
- /*
- * Check for parity error.
- * Hardware will automatically set ATN
- * to request the device for a MSG_OUT phase.
- */
- if (status & ASC_CSR_PE) {
- printf("%s: SCSI device %d: incomming parity error seen\n",
- asc->sc_dev.dv_xname, asc->target);
- asc->st[asc->target].flags |= PARITY_ERR;
- }
-
- /*
- * Check for gross error.
- * Probably a bug in a device driver.
- */
- if (status & ASC_CSR_GE) {
- printf("%s: SCSI device %d: gross error\n",
- asc->sc_dev.dv_xname, asc->target);
- goto abort;
- }
-
- /* check for message in or out */
- if ((ir & ~ASC_INT_FC) == ASC_INT_BS) {
- register int len, fifo;
-
- state = &asc->st[asc->target];
- switch (ASC_PHASE(status)) {
- case SCSI_PHASE_DATAI:
- case SCSI_PHASE_DATAO:
- ASC_TC_GET(regs, len);
- fifo = regs->asc_flags & ASC_FLAGS_FIFO_CNT;
- if (len != 0 && (
- (asc->script - asc_scripts) == SCRIPT_DATA_IN + 1 ||
- (asc->script - asc_scripts) == SCRIPT_CONTINUE_IN ||
- (asc->script - asc_scripts) == SCRIPT_DATA_OUT + 1 ||
- (asc->script - asc_scripts) == SCRIPT_CONTINUE_OUT)) { /*
- * From the Mach driver:
- * After a reconnect and restart dma in/out, we
- * seem to have gotten an interrupt even though
- * the DMA is running. The Mach driver just
- * ignores this interrupt.
- */
- printf("asc_intr: ignoring strange interrupt");
- printf(" tc %d fifo residue %d script %d\n",
- len, fifo, asc->script - asc_scripts);
- goto done;
- }
- printf("asc_intr: data overrun: buflen %d dmalen %d tc %d fifo %d\n",
- state->buflen, state->dmalen, len, fifo);
- goto abort;
-
- case SCSI_PHASE_MSG_IN:
- break;
-
- case SCSI_PHASE_MSG_OUT:
- /*
- * Check for parity error.
- * Hardware will automatically set ATN
- * to request the device for a MSG_OUT phase.
- */
- if (state->flags & PARITY_ERR) {
- state->flags &= ~PARITY_ERR;
- state->msg_out = SCSI_MESSAGE_PARITY_ERROR;
- /* reset message in counter */
- state->msglen = 0;
- } else
- state->msg_out = SCSI_NO_OP;
- regs->asc_fifo = state->msg_out;
- regs->asc_cmd = ASC_CMD_XFER_INFO;
- readback(regs->asc_cmd);
- goto done;
-
- case SCSI_PHASE_STATUS:
- /* probably an error in the SCSI command */
- asc->script = &asc_scripts[SCRIPT_GET_STATUS];
- regs->asc_cmd = ASC_CMD_I_COMPLETE;
- readback(regs->asc_cmd);
- goto done;
-
- case SCSI_PHASE_COMMAND:
- /*
- * This seems to occur after the command is sent
- * following sync negotiation. The device still
- * wants more command data. The fifo appears to
- * to still have the unsent data - but the 53C94
- * signaled TC. If the fifo still contains data,
- * transfer it, otherwise do a transfer pad. The
- * target should then continue through the rest of
- * the phases and complete normally.
- */
- printf("asc_intr: tgt %d command phase TC zero",
- asc->target);
- if ((regs->asc_flags & ASC_FLAGS_FIFO_CNT) != 0) {
- printf(" with non-empty fifo %d\n",
- regs->asc_flags & ASC_FLAGS_FIFO_CNT);
- regs->asc_cmd = ASC_CMD_XFER_INFO;
- } else {
- printf("; padding command\n");
- ASC_TC_PUT(regs, 0xff);
- regs->asc_cmd = ASC_CMD_XFER_PAD | ASC_CMD_DMA;
- }
- goto done;
-
- default:
- printf("asc_intr: target %d, unknown phase 0x%x\n",
- asc->target, status);
- goto abort;
- }
-
- if (state->script) {
- printf("asc_intr: target %d, incomplete script %p\n",
- asc->target, state->script);
- goto abort;
- }
-
- /* check for DMA in progress */
- ASC_TC_GET(regs, len);
- fifo = regs->asc_flags & ASC_FLAGS_FIFO_CNT;
- /* flush any data in the FIFO */
- if (fifo) {
- if (state->flags & DMA_OUT) {
-#ifdef ASC_DIAGNOSTIC
- printf("asc: DMA_OUT, fifo resid %d, len %d, flags 0x%x\n",
- fifo, len, state->flags);
-#endif /* ASC_DIAGNOSTIC */
- len += fifo;
- } else if (state->flags & DMA_IN) {
-#ifdef ASC_DIAGNOSTIC
- printf("asc_intr: IN: dmalen %d len %d fifo %d\n",
- state->dmalen, len, fifo); /* XXX */
-#endif /* ASC_DIAGNOSTIC */
- } else
- printf("asc_intr: dmalen %d len %d fifo %d\n",
- state->dmalen, len, fifo); /* XXX */
- regs->asc_cmd = ASC_CMD_FLUSH;
- tc_mb();
- readback(regs->asc_cmd);
- DELAY(2);
- }
- if (len && (state->flags & DMA_IN_PROGRESS)) {
- /* save number of bytes still to be sent or received */
- state->dmaresid = len;
- state->flags &= ~DMA_IN_PROGRESS;
- ASC_TC_PUT(regs, 0);
-#ifdef DEBUG
- if (asc_logp == asc_log)
- asc_log[NLOG - 1].resid = len;
- else
- asc_logp[-1].resid = len;
-#endif
- /* setup state to resume to */
- if (state->flags & DMA_IN) {
- /*
- * Since the ASC_CNFG3_SRB bit of the
- * cnfg3 register bit is not set,
- * we just transferred an extra byte.
- * Since we can't resume on an odd byte
- * boundary, we copy the valid data out
- * and resume DMA at the start address.
- */
- if (len & 1) {
- printf("asc_intr: msg in len %d (fifo %d)\n",
- len, fifo); /* XXX */
- len = state->dmalen - len;
- goto do_in;
- }
- state->script =
- &asc_scripts[SCRIPT_RESUME_DMA_IN];
- state->flags |= DMA_RESUME;
- } else if (state->flags & DMA_OUT) {
- state->script =
- &asc_scripts[SCRIPT_RESUME_DMA_OUT];
- state->flags |= DMA_RESUME;
- } else
- state->script = asc->script;
- } else if (state->flags & DMA_IN) {
-#ifdef ASC_DIAGNOSTIC
- if (len) {
- printf("asc_intr: 1: len %d (fifo %d)\n",
- len, fifo); /* XXX */
- }
-#endif
- /* setup state to resume to */
- if (state->flags & DMA_IN_PROGRESS) {
- len = state->dmalen;
- state->flags &= ~DMA_IN_PROGRESS;
- do_in:
- state->dmalen = len; /* dma_end needs actual length */
- (*asc->dma_end)(asc, state, ASCDMA_READ);
- state->buf += len;
- state->buflen -= len;
- }
- if (state->buflen)
- state->script = (state->flags & DMA_RESUME) ?
- &asc_scripts[SCRIPT_RESUME_DMA_IN] :
- &asc_scripts[SCRIPT_RESUME_IN];
- else
- state->script =
- &asc_scripts[SCRIPT_RESUME_NO_DATA];
- } else if (state->flags & DMA_OUT) {
- if (len) {
-#ifdef DEBUG
- printf("asc_intr: 2: len %d (fifo %d)\n", len,
- fifo); /* XXX */
-#endif
- }
- /*
- * If this is the last chunk, the next expected
- * state is to get status.
- */
- if (state->flags & DMA_IN_PROGRESS) {
- state->flags &= ~DMA_IN_PROGRESS;
- (*asc->dma_end)(asc, state, ASCDMA_WRITE);
- len = state->dmalen;
- state->buf += len;
- state->buflen -= len;
- }
- if (state->buflen)
- state->script = (state->flags & DMA_RESUME) ?
- &asc_scripts[SCRIPT_RESUME_DMA_OUT] :
- &asc_scripts[SCRIPT_RESUME_OUT];
- else
- state->script =
- &asc_scripts[SCRIPT_RESUME_NO_DATA];
- } else if (asc->script == &asc_scripts[SCRIPT_SIMPLE])
- state->script = &asc_scripts[SCRIPT_RESUME_NO_DATA];
- else
- state->script = asc->script;
-
- /* setup to receive a message */
- asc->script = &asc_scripts[SCRIPT_MSG_IN];
- state->msglen = 0;
- regs->asc_cmd = ASC_CMD_XFER_INFO;
- readback(regs->asc_cmd);
- goto done;
- }
-
- /* check for SCSI bus reset */
- if (ir & ASC_INT_RESET) {
- register int i;
-
- printf("%s: SCSI bus reset!!\n", asc->sc_dev.dv_xname);
- /* need to flush any pending commands */
- for (i = 0; i < ASC_NCMD; i++) {
- if (!asc->cmd[i])
- continue;
- asc->st[i].error = EIO;
- asc_end(asc, 0, 0, 0);
- }
- /* rearbitrate synchronous offset */
- for (i = 0; i < ASC_NCMD; i++) {
- asc->st[i].sync_offset = 0;
- asc->st[i].flags = 0;
- }
- asc->target = -1;
- return 0 ; /* XXX ??? */
- }
-
- /* check for disconnect */
- if (ir & ASC_INT_DISC) {
- state = &asc->st[asc->target];
- switch (asc->script - asc_scripts) {
- case SCRIPT_DONE:
- case SCRIPT_DISCONNECT:
- /*
- * Disconnects can happen normally when the
- * command is complete with the phase being
- * either SCSI_PHASE_DATAO or SCSI_PHASE_MSG_IN.
- * The SCRIPT_MATCH() only checks for one phase
- * so we can wind up here.
- * Perform the appropriate operation, then proceed.
- */
- if ((*scpt->action)(asc, status, ss, ir)) {
- regs->asc_cmd = scpt->command;
- readback(regs->asc_cmd);
- asc->script = scpt->next;
- }
- goto done;
-
- case SCRIPT_TRY_SYNC:
- case SCRIPT_SIMPLE:
- case SCRIPT_DATA_IN:
- case SCRIPT_DATA_OUT: /* one of the starting scripts */
- if (ASC_SS(ss) == 0) {
- /* device did not respond */
- if (regs->asc_flags & ASC_FLAGS_FIFO_CNT) {
- regs->asc_cmd = ASC_CMD_FLUSH;
- readback(regs->asc_cmd);
- }
- state->error = ENXIO;
- asc_end(asc, status, ss, ir);
- return 0 ; /* XXX ??? */
- }
- /* FALLTHROUGH */
-
- default:
- printf("%s: SCSI device %d: unexpected disconnect\n",
- asc->sc_dev.dv_xname, asc->target);
-#ifdef DEBUG
- asc_DumpLog("asc_disc");
-#endif
- /*
- * On rare occasions my RZ24 does a disconnect during
- * data in phase and the following seems to keep it
- * happy.
- * XXX Should a scsi disk ever do this??
- */
- asc->script = &asc_scripts[SCRIPT_RESEL];
- asc->state = ASC_STATE_RESEL;
- state->flags |= DISCONN;
- regs->asc_cmd = ASC_CMD_ENABLE_SEL;
- readback(regs->asc_cmd);
- return 0 ; /* XXX ??? */
- }
- }
-
- /* mhitch - debug - check select/reselect collision */
- if ((ir & ASC_INT_ILL) && (regs->asc_cmd & ASC_CMD_SEL_ATN)) {
- printf("asc_intr: Illegal command status %x ir %x\n",
- status, ir);
- /* Should process reselect? */
- }
-
- /* check for illegal command */
- if (ir & ASC_INT_ILL) {
-#ifdef ASC_DIAGNOSTIC
- printf("asc_intr: Illegal command status %x ir %x cmd %x ? %x\n",
- status, ir, regs->asc_cmd, asc_scripts[SCRIPT_MSG_IN].command);
-#endif
- /*
- * On a 5000/200, I see this frequently when using an RD52
- * CDROM. The 53c94 doesn't seem to get the Message Accept
- * command, and generates an "Illegal Command" interrupt.
- * Re-issuing the Message Accept at this point seems to keep
- * things going. Don't allow this too many times in a row,
- * just to make sure we don't get hung up. mhitch
- */
- if (ill_cmd_count++ != 3) { /* XXX */
- regs->asc_cmd = ASC_CMD_MSG_ACPT; /* XXX */
- readback(regs->asc_cmd); /* XXX */
- goto done; /* XXX */
- } /* XXX */
- printf("asc_intr: Illegal command tgt %d\n", asc->target);
- goto abort; /* XXX */
- }
- ill_cmd_count = 0; /* XXX */
-
- /* check for reselect */
- if (ir & ASC_INT_RESEL) {
- unsigned fifo, id, msg;
-
- fifo = regs->asc_flags & ASC_FLAGS_FIFO_CNT;
- if (fifo < 2) {
- printf("asc_intr: target %d, reselect, fifo %d too small for msg\n",
- asc->target, fifo);
-
- goto abort;
- }
- /* read unencoded SCSI ID and convert to binary */
- msg = regs->asc_fifo & asc->myidmask;
- for (id = 0; (msg & 1) == 0; id++)
- msg >>= 1;
- /* read identify message */
- msg = regs->asc_fifo;
-#ifdef DEBUG
- if (asc_logp == asc_log)
- asc_log[NLOG - 1].msg = msg;
- else
- asc_logp[-1].msg = msg;
-#endif
- /*
- * TC may have been initialized during a selection attempt.
- * Clear it to prevent possible confusion later.
- */
- ASC_TC_PUT(regs,0); /* ensure TC clear */
- asc->state = ASC_STATE_BUSY;
- asc->target = id;
- state = &asc->st[id];
- asc->script = state->script;
- state->script = (script_t *)0;
- if (!(state->flags & DISCONN)) {
- printf("asc_intr: reselect tgt %d, flags 0x%x not disconnected\n",
- asc->target, state->flags);
- goto abort;
- }
- state->flags &= ~DISCONN;
- regs->asc_syn_p = state->sync_period;
- regs->asc_syn_o = state->sync_offset;
- regs->asc_cmd = ASC_CMD_MSG_ACPT;
- readback(regs->asc_cmd);
- goto done;
- }
-
- /* check if we are being selected as a target */
- if (ir & (ASC_INT_SEL | ASC_INT_SEL_ATN)) {
- printf("asc_intr: host adaptor selected as target\n");
- goto abort;
- }
- /*
- * 'ir' must be just ASC_INT_FC.
- * This is normal if canceling an ASC_ENABLE_SEL.
- */
-
-done:
- tc_mb();
- /* watch out for HW race conditions and setup & hold time violations */
- ir = regs->asc_status;
- while (ir != (status = regs->asc_status))
- ir = status;
- if (status & ASC_CSR_INT)
- goto again;
- return 0 ; /* XXX ??? */
-
-abort:
-#ifdef DEBUG
- asc_DumpLog("asc_intr");
-#endif
-#if 0
- panic("asc_intr");
-#else
- boot(RB_NOSYNC); /* XXX */
-#endif
-}
-
-/*
- * All the many little things that the interrupt
- * routine might switch to.
- */
-
-/* ARGSUSED */
-static int
-script_nop(asc, status, ss, ir)
- register asc_softc_t asc;
- register int status, ss, ir;
-{
- return (1);
-}
-
-/* ARGSUSED */
-static int
-asc_get_status(asc, status, ss, ir)
- register asc_softc_t asc;
- register int status, ss, ir;
-{
- register asc_regmap_t *regs = asc->regs;
- register int data;
-
- /*
- * Get the last two bytes in the FIFO.
- */
- if ((data = regs->asc_flags & ASC_FLAGS_FIFO_CNT) != 2) {
- printf("asc_get_status: cmdreg %x, fifo cnt %d\n",
- regs->asc_cmd, data); /* XXX */
-#ifdef DEBUG
- asc_DumpLog("get_status"); /* XXX */
-#endif
- if (data < 2) {
- asc->regs->asc_cmd = ASC_CMD_MSG_ACPT;
- readback(asc->regs->asc_cmd);
- return (0);
- }
- do {
- data = regs->asc_fifo;
- } while ((regs->asc_flags & ASC_FLAGS_FIFO_CNT) > 2);
- }
-
- /* save the status byte */
- asc->st[asc->target].statusByte = data = regs->asc_fifo;
-#ifdef DEBUG
- if (asc_logp == asc_log)
- asc_log[NLOG - 1].msg = data;
- else
- asc_logp[-1].msg = data;
-#endif
-
- /* get the (presumed) command_complete message */
- if ((data = regs->asc_fifo) == SCSI_COMMAND_COMPLETE)
- return (1);
-
-#ifdef DEBUG
- printf("asc_get_status: status %x cmd %x\n",
- asc->st[asc->target].statusByte, data);
- asc_DumpLog("asc_get_status");
-#endif
- return (0);
-}
-
-/* ARGSUSED */
-static int
-asc_end(asc, status, ss, ir)
- register asc_softc_t asc;
- register int status, ss, ir;
-{
- register ScsiCmd *scsicmd;
- register State *state;
- register int i, target;
-
- asc->state = ASC_STATE_IDLE;
- target = asc->target;
- asc->target = -1;
- scsicmd = asc->cmd[target];
- asc->cmd[target] = (ScsiCmd *)0;
- state = &asc->st[target];
- timeout_del(&asc->asc_timo);
-
-#ifdef DEBUG
- if (asc_debug > 1) {
- printf("asc_end: %s target %d cmd %x err %d resid %d\n",
- scsicmd->sd->sd_driver->d_name, target,
- scsicmd->cmd[0], state->error, state->buflen);
- }
-#endif
-#ifdef DIAGNOSTIC
- if (target < 0 || !scsicmd)
- panic("asc_end");
-#endif
-
- /* look for disconnected devices */
- for (i = 0; i < ASC_NCMD; i++) {
- if (!asc->cmd[i] || !(asc->st[i].flags & DISCONN))
- continue;
- asc->regs->asc_cmd = ASC_CMD_ENABLE_SEL;
- readback(asc->regs->asc_cmd);
- asc->state = ASC_STATE_RESEL;
- asc->script = &asc_scripts[SCRIPT_RESEL];
- break;
- }
-
-#ifdef USE_NEW_SCSI
- if(scsicmd->error == XS_NOERROR && !(state->flags & CHECK_SENSE)) {
- if((state->statusByte & ST_MASK) == SCSI_CHECK) {
- struct scsi_sense *ss = (void *)&state->cmd;
- /* Save return values */
- scsicmd->resid = state->buflen;
- scsicmd->status = state->statusByte;
- /* Set up sense request command */
- bzero(ss, sizeof(*ss));
- ss->opcode = REQUEST_SENSE;
- ss->byte2 = sc_link->lun << 5;
- ss->length = sizeof(struct scsi_sense_data);
- state->cmdlen = sizeof(*ss);
- state->buf = (vm_offset_t)&scsicmd->sense;
- state->buflen = sizeof(struct scsi_sense_data);
- state->flags |= CHECK_SENSE;
- MachFlushDCache(state->buf, state->buflen);
- asc->cmd[target] = scsicmd;
- asc_startcmd(asc, target);
- return(0);
- }
- }
-#endif /*USE_NEW_SCSI*/
-
- /*
- * Look for another device that is ready.
- * May want to keep last one started and increment for fairness
- * rather than always starting at zero.
- */
- for (i = 0; i < ASC_NCMD; i++) {
- /* don't restart a disconnected command */
- if (!asc->cmd[i] || (asc->st[i].flags & DISCONN))
- continue;
- asc_startcmd(asc, i);
- break;
- }
-
- /* signal device driver that the command is done */
- (*scsicmd->sd->sd_driver->d_done)(scsicmd->unit, state->error,
- state->buflen, state->statusByte);
-
- return (0);
-}
-
-/* ARGSUSED */
-static int
-asc_dma_in(asc, status, ss, ir)
- register asc_softc_t asc;
- register int status, ss, ir;
-{
- register asc_regmap_t *regs = asc->regs;
- register State *state = &asc->st[asc->target];
- register int len;
-
- /* check for previous chunk in buffer */
- if (state->flags & DMA_IN_PROGRESS) {
- /*
- * Only count bytes that have been copied to memory.
- * There may be some bytes in the FIFO if synchonous transfers
- * are in progress.
- */
- ASC_TC_GET(regs, len);
- len = state->dmalen - len;
- state->dmalen = len; /* dma_end may need actual length */
- (*asc->dma_end)(asc, state, ASCDMA_READ);
- state->buf += len;
- state->buflen -= len;
- }
-
- if (!(state->flags & DMA_IN_PROGRESS) &&
- (regs->asc_flags & ASC_FLAGS_FIFO_CNT) != 0) {
- volatile int async_fifo_junk = 0;
-
- /*
- * If the target is asynchronous, the FIFO contains
- * a byte of garbage. (see the Mach mk84 53c94 driver,
- * where this occurs on tk-50s and exabytes.)
- * It also occurs on asynch disks like SCSI-1 disks.
- * Recover by reading the byte of junk from the fifo if,
- * and only if, the target is async. If the target is
- * synch, there is no junk, and reading the fifo
- * deadlocks our SCSI state machine.
- */
- if (state->sync_offset == 0)
- async_fifo_junk = regs->asc_fifo;
-#ifdef ASC_DIAGNOSTIC
- printf("%s: asc_dma_in: FIFO count %x flags %x sync_offset %d",
- asc->sc_dev.dv_xname, regs->asc_flags,
- state->flags, state->sync_offset);
- if (state->sync_offset != 0)
- printf("\n");
- else
- printf(" unexpected fifo data %x\n", async_fifo_junk);
-#ifdef DEBUG
- asc_DumpLog("asc_dma_in");
-#endif /* DEBUG */
-#endif /* ASC_DIAGNOSTIC */
-
- }
- /* setup to start reading the next chunk */
- len = state->buflen;
-#ifdef DEBUG
- if (asc_logp == asc_log)
- asc_log[NLOG - 1].resid = len;
- else
- asc_logp[-1].resid = len;
-#endif
- len = (*asc->dma_start)(asc, state, state->buf, ASCDMA_READ, len, 0);
- state->dmalen = len;
- ASC_TC_PUT(regs, len);
-#ifdef DEBUG
- if (asc_debug > 2)
- printf("asc_dma_in: buflen %d, len %d\n", state->buflen, len);
-#endif
-
- /* check for next chunk */
- state->flags |= DMA_IN_PROGRESS;
- if (len != state->buflen) {
- regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
- readback(regs->asc_cmd);
- asc->script = &asc_scripts[SCRIPT_CONTINUE_IN];
- return (0);
- }
- return (1);
-}
-
-/* ARGSUSED */
-static int
-asc_last_dma_in(asc, status, ss, ir)
- register asc_softc_t asc;
- register int status, ss, ir;
-{
- register asc_regmap_t *regs = asc->regs;
- register State *state = &asc->st[asc->target];
- register int len, fifo;
-
- ASC_TC_GET(regs, len);
- fifo = regs->asc_flags & ASC_FLAGS_FIFO_CNT;
-#ifdef DEBUG
- if (asc_debug > 2)
- printf("asc_last_dma_in: buflen %d dmalen %d tc %d fifo %d\n",
- state->buflen, state->dmalen, len, fifo);
-#endif
- if (fifo) {
- /* device must be trying to send more than we expect */
- regs->asc_cmd = ASC_CMD_FLUSH;
- readback(regs->asc_cmd);
- }
- state->flags &= ~DMA_IN_PROGRESS;
- len = state->dmalen - len;
- state->dmalen = len; /* dma_end may need actual length */
- (*asc->dma_end)(asc, state, ASCDMA_READ);
- state->buflen -= len;
-
- return (1);
-}
-
-/* ARGSUSED */
-static int
-asc_resume_in(asc, status, ss, ir)
- register asc_softc_t asc;
- register int status, ss, ir;
-{
- register asc_regmap_t *regs = asc->regs;
- register State *state = &asc->st[asc->target];
- register int len;
-
- /* setup to start reading the next chunk */
- len = state->buflen;
-#ifdef DEBUG
- if (asc_logp == asc_log)
- asc_log[NLOG - 1].resid = len;
- else
- asc_logp[-1].resid = len;
-#endif
- len = (*asc->dma_start)(asc, state, state->buf, ASCDMA_READ, len, 0);
- state->dmalen = len;
- ASC_TC_PUT(regs, len);
-#ifdef DEBUG
- if (asc_debug > 2)
- printf("asc_resume_in: buflen %d, len %d\n", state->buflen,
- len);
-#endif
-
- /* check for next chunk */
- state->flags |= DMA_IN_PROGRESS;
- if (len != state->buflen) {
- regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
- readback(regs->asc_cmd);
- asc->script = &asc_scripts[SCRIPT_CONTINUE_IN];
- return (0);
- }
- return (1);
-}
-
-/* ARGSUSED */
-static int
-asc_resume_dma_in(asc, status, ss, ir)
- register asc_softc_t asc;
- register int status, ss, ir;
-{
- register asc_regmap_t *regs = asc->regs;
- register State *state = &asc->st[asc->target];
- register int len, off;
-
- /* setup to finish reading the current chunk */
- len = state->dmaresid;
- off = state->dmalen - len;
- if ((off & 1) && state->sync_offset) {
- printf("asc_resume_dma_in: odd xfer dmalen %d len %d off %d\n",
- state->dmalen, len, off); /* XXX */
- regs->asc_res_fifo = state->buf[off];
- }
-#ifdef DEBUG
- if (asc_logp == asc_log)
- asc_log[NLOG - 1].resid = len;
- else
- asc_logp[-1].resid = len;
-#endif
- len = (*asc->dma_start)(asc, state, state->buf + off, ASCDMA_READ, len, off);
- ASC_TC_PUT(regs, len);
-#ifdef DEBUG
- if (asc_debug > 2)
- printf("asc_resume_dma_in: buflen %d dmalen %d len %d off %d\n",
- state->dmalen, state->buflen, len, off);
-#endif
-
- /* check for next chunk */
- state->flags |= DMA_IN_PROGRESS;
- state->flags &= ~DMA_RESUME;
- if (state->dmalen != state->buflen) {
- regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
- readback(regs->asc_cmd);
- asc->script = &asc_scripts[SCRIPT_CONTINUE_IN];
- return (0);
- }
- return (1);
-}
-
-/* ARGSUSED */
-static int
-asc_dma_out(asc, status, ss, ir)
- register asc_softc_t asc;
- register int status, ss, ir;
-{
- register asc_regmap_t *regs = asc->regs;
- register State *state = &asc->st[asc->target];
- register int len, fifo;
-
- if (state->flags & DMA_IN_PROGRESS) {
- /* check to be sure previous chunk was finished */
- ASC_TC_GET(regs, len);
- fifo = regs->asc_flags & ASC_FLAGS_FIFO_CNT;
- if (len || fifo)
- printf("asc_dma_out: buflen %d dmalen %d tc %d fifo %d\n",
- state->buflen, state->dmalen, len, fifo); /* XXX */
- len += fifo;
- len = state->dmalen - len;
- state->buf += len;
- state->buflen -= len;
- }
-
- /*
- * Flush the fifo - sometimes there seems to be something left
- * in the fifo. Since the dma output has not been started,
- * the fifo is supposed to be empty.
- */
- if (regs->asc_flags & ASC_FLAGS_FIFO_CNT) {
- while (regs->asc_flags & ASC_FLAGS_FIFO_CNT)
- regs->asc_fifo;
- }
- /* setup for this chunk */
- len = state->buflen;
-#ifdef DEBUG
- if (asc_logp == asc_log)
- asc_log[NLOG - 1].resid = len;
- else
- asc_logp[-1].resid = len;
-#endif
- len = (*asc->dma_start)(asc, state, state->buf, ASCDMA_WRITE, len, 0);
- state->dmalen = len;
- ASC_TC_PUT(regs, len);
-#ifdef DEBUG
- if (asc_debug > 2)
- printf("asc_dma_out: buflen %d, len %d\n", state->buflen, len);
-#endif
-
- /* check for next chunk */
- state->flags |= DMA_IN_PROGRESS;
- if (len != state->buflen) {
- regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
- readback(regs->asc_cmd);
- asc->script = &asc_scripts[SCRIPT_CONTINUE_OUT];
- return (0);
- }
- return (1);
-}
-
-/* ARGSUSED */
-static int
-asc_last_dma_out(asc, status, ss, ir)
- register asc_softc_t asc;
- register int status, ss, ir;
-{
- register asc_regmap_t *regs = asc->regs;
- register State *state = &asc->st[asc->target];
- register int len, fifo;
-
- ASC_TC_GET(regs, len);
- fifo = regs->asc_flags & ASC_FLAGS_FIFO_CNT;
-#ifdef DEBUG
- if (asc_debug > 2)
- printf("asc_last_dma_out: buflen %d dmalen %d tc %d fifo %d\n",
- state->buflen, state->dmalen, len, fifo);
-#endif
- if (fifo) {
- len += fifo;
- regs->asc_cmd = ASC_CMD_FLUSH;
- readback(regs->asc_cmd);
- printf("asc_last_dma_out: buflen %d dmalen %d tc %d fifo %d\n",
- state->buflen, state->dmalen, len, fifo);
- }
- state->flags &= ~DMA_IN_PROGRESS;
- len = state->dmalen - len;
- state->buflen -= len;
- return (1);
-}
-
-/* ARGSUSED */
-static int
-asc_resume_out(asc, status, ss, ir)
- register asc_softc_t asc;
- register int status, ss, ir;
-{
- register asc_regmap_t *regs = asc->regs;
- register State *state = &asc->st[asc->target];
- register int len;
-
- /* setup for this chunk */
- len = state->buflen;
-#ifdef DEBUG
- if (asc_logp == asc_log)
- asc_log[NLOG - 1].resid = len;
- else
- asc_logp[-1].resid = len;
-#endif
- len = (*asc->dma_start)(asc, state, state->buf, ASCDMA_WRITE, len, 0);
- state->dmalen = len;
- ASC_TC_PUT(regs, len);
-#ifdef DEBUG
- if (asc_debug > 2)
- printf("asc_resume_out: buflen %d, len %d\n", state->buflen,
- len);
-#endif
-
- /* check for next chunk */
- state->flags |= DMA_IN_PROGRESS;
- if (len != state->buflen) {
- regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
- readback(regs->asc_cmd);
- asc->script = &asc_scripts[SCRIPT_CONTINUE_OUT];
- return (0);
- }
- return (1);
-}
-
-/* ARGSUSED */
-static int
-asc_resume_dma_out(asc, status, ss, ir)
- register asc_softc_t asc;
- register int status, ss, ir;
-{
- register asc_regmap_t *regs = asc->regs;
- register State *state = &asc->st[asc->target];
- register int len, off;
-
- /* setup to finish writing this chunk */
- len = state->dmaresid;
- off = state->dmalen - len;
- if (off & 1) {
- printf("asc_resume_dma_out: odd xfer dmalen %d len %d off %d\n",
- state->dmalen, len, off); /* XXX */
- regs->asc_fifo = state->buf[off];
- off++;
- len--;
- }
-#ifdef DEBUG
- if (asc_logp == asc_log)
- asc_log[NLOG - 1].resid = len;
- else
- asc_logp[-1].resid = len;
-#endif
- /* XXX may result in redundant copy of data */
- len = (*asc->dma_start)(asc, state, state->buf + off, ASCDMA_WRITE, len, off);
- ASC_TC_PUT(regs, len);
-#ifdef DEBUG
- if (asc_debug > 2)
- printf("asc_resume_dma_out: buflen %d dmalen %d len %d off %d\n",
- state->dmalen, state->buflen, len, off);
-#endif
-
- /* check for next chunk */
- state->flags |= DMA_IN_PROGRESS;
- state->flags &= ~DMA_RESUME;
- if (state->dmalen != state->buflen) {
- regs->asc_cmd = ASC_CMD_XFER_INFO | ASC_CMD_DMA;
- readback(regs->asc_cmd);
- asc->script = &asc_scripts[SCRIPT_CONTINUE_OUT];
- return (0);
- }
- return (1);
-}
-
-/* ARGSUSED */
-static int
-asc_sendsync(asc, status, ss, ir)
- register asc_softc_t asc;
- register int status, ss, ir;
-{
- register asc_regmap_t *regs = asc->regs;
- register State *state = &asc->st[asc->target];
-
- /* send the extended synchronous negotiation message */
- regs->asc_fifo = SCSI_EXTENDED_MSG;
- tc_mb();
- regs->asc_fifo = 3;
- tc_mb();
- regs->asc_fifo = SCSI_SYNCHRONOUS_XFER;
- tc_mb();
- regs->asc_fifo = SCSI_MIN_PERIOD;
- tc_mb();
- regs->asc_fifo = ASC_MAX_OFFSET;
- /* state to resume after we see the sync reply message */
- state->script = asc->script + 2;
- state->msglen = 0;
- return (1);
-}
-
-/* ARGSUSED */
-static int
-asc_replysync(asc, status, ss, ir)
- register asc_softc_t asc;
- register int status, ss, ir;
-{
- register asc_regmap_t *regs = asc->regs;
- register State *state = &asc->st[asc->target];
-
-#ifdef DEBUG
- if (asc_debug > 2)
- printf("asc_replysync: %x %x\n",
- asc_to_scsi_period[state->sync_period] * asc->tb_ticks,
- state->sync_offset);
-#endif
- /* send synchronous transfer in response to a request */
- regs->asc_fifo = SCSI_EXTENDED_MSG;
- tc_mb();
- regs->asc_fifo = 3;
- tc_mb();
- regs->asc_fifo = SCSI_SYNCHRONOUS_XFER;
- tc_mb();
- regs->asc_fifo = asc_to_scsi_period[state->sync_period] * asc->tb_ticks;
- tc_mb();
- regs->asc_fifo = state->sync_offset;
- regs->asc_cmd = ASC_CMD_XFER_INFO;
- readback(regs->asc_cmd);
-
- /* return to the appropriate script */
- if (!state->script) {
-#ifdef DEBUG
- asc_DumpLog("asc_replsync");
-#endif
- panic("asc_replysync");
- }
- asc->script = state->script;
- state->script = (script_t *)0;
- return (0);
-}
-
-/* ARGSUSED */
-static int
-asc_msg_in(asc, status, ss, ir)
- register asc_softc_t asc;
- register int status, ss, ir;
-{
- register asc_regmap_t *regs = asc->regs;
- register State *state = &asc->st[asc->target];
- register int msg;
- int i;
-
- /* read one message byte */
- msg = regs->asc_fifo;
-#ifdef DEBUG
- if (asc_logp == asc_log)
- asc_log[NLOG - 1].msg = msg;
- else
- asc_logp[-1].msg = msg;
-#endif
-
- /* check for multi-byte message */
- if (state->msglen != 0) {
- /* first byte is the message length */
- if (state->msglen < 0) {
- state->msglen = msg;
- return (1);
- }
- if (state->msgcnt >= state->msglen) {
- printf("asc: msg_in too big, msgcnt %d msglen %d\n",
- state->msgcnt, state->msglen);
- goto abort;
- }
- state->msg_in[state->msgcnt++] = msg;
-
- /* did we just read the last byte of the message? */
- if (state->msgcnt != state->msglen)
- return (1);
-
- /* process an extended message */
-#ifdef DEBUG
- if (asc_debug > 2)
- printf("asc_msg_in: msg %x %x %x\n",
- state->msg_in[0],
- state->msg_in[1],
- state->msg_in[2]);
-#endif
- switch (state->msg_in[0]) {
- case SCSI_SYNCHRONOUS_XFER:
- state->flags |= DID_SYNC;
- state->sync_offset = state->msg_in[2];
-
- /* convert SCSI period to ASC period */
- i = state->msg_in[1] / asc->tb_ticks;
- if (i < asc->min_period)
- i = asc->min_period;
- else if (i >= asc->max_period) {
- /* can't do sync transfer, period too long */
- printf("%s: SCSI device %d: sync xfer period too long (%d)\n",
- asc->sc_dev.dv_xname, asc->target, i);
- i = asc->max_period;
- state->sync_offset = 0;
- }
- if ((i * asc->tb_ticks) != state->msg_in[1])
- i++;
- state->sync_period = i & 0x1F;
-
- /*
- * If this is a request, check minimums and
- * send back an acknowledge.
- */
- if (!(state->flags & TRY_SYNC)) {
- regs->asc_cmd = ASC_CMD_SET_ATN;
- readback(regs->asc_cmd);
-
- if (state->sync_period < asc->min_period)
- state->sync_period =
- asc->min_period;
- if (state->sync_offset > ASC_MAX_OFFSET)
- state->sync_offset =
- ASC_MAX_OFFSET;
- asc->script = &asc_scripts[SCRIPT_REPLY_SYNC];
- regs->asc_syn_p = state->sync_period;
- readback(regs->asc_syn_p);
- regs->asc_syn_o = state->sync_offset;
- readback(regs->asc_syn_o);
- regs->asc_cmd = ASC_CMD_MSG_ACPT;
- readback(regs->asc_cmd);
- return (0);
- }
-
- regs->asc_syn_p = state->sync_period;
- readback(regs->asc_syn_p);
- regs->asc_syn_o = state->sync_offset;
- readback(regs->asc_syn_o);
- goto done;
-
- default:
- printf("%s: SCSI device %d: rejecting extended message 0x%x\n",
- asc->sc_dev.dv_xname, asc->target,
- state->msg_in[0]);
- goto reject;
- }
- }
-
- /* process first byte of a message */
-#ifdef DEBUG
- if (asc_debug > 2)
- printf("asc_msg_in: msg %x\n", msg);
-#endif
- switch (msg) {
-#if 0
- case SCSI_MESSAGE_REJECT:
- printf(" did not like SYNCH xfer "); /* XXX */
- state->flags |= DID_SYNC;
- regs->asc_cmd = ASC_CMD_MSG_ACPT;
- readback(regs->asc_cmd);
- status = asc_wait(regs, ASC_CSR_INT);
- ir = regs->asc_intr;
- /* some just break out here, some dont */
- if (ASC_PHASE(status) == SCSI_PHASE_MSG_OUT) {
- regs->asc_fifo = SCSI_ABORT;
- regs->asc_cmd = ASC_CMD_XFER_INFO;
- readback(regs->asc_cmd);
- status = asc_wait(regs, ASC_CSR_INT);
- ir = regs->asc_intr;
- }
- if (ir & ASC_INT_DISC) {
- asc_end(asc, status, 0, ir);
- return (0);
- }
- goto status;
-#endif /*0*/
-
- case SCSI_EXTENDED_MSG: /* read an extended message */
- /* setup to read message length next */
- state->msglen = -1;
- state->msgcnt = 0;
- return (1);
-
- case SCSI_NO_OP:
- break;
-
- case SCSI_SAVE_DATA_POINTER:
- /* expect another message */
- return (1);
-
- case SCSI_RESTORE_POINTERS:
- /*
- * Need to do the following if resuming synchonous data in
- * on an odd byte boundary.
- regs->asc_cnfg2 |= ASC_CNFG2_RFB;
- */
- break;
-
- case SCSI_DISCONNECT:
- if (state->flags & DISCONN) {
- printf("asc: disconnected target %d disconnecting again\n",
- asc->target);
- goto abort;
- }
- state->flags |= DISCONN;
- regs->asc_cmd = ASC_CMD_MSG_ACPT;
- readback(regs->asc_cmd);
- asc->script = &asc_scripts[SCRIPT_DISCONNECT];
- return (0);
-
- default:
- printf("%s: SCSI device %d: rejecting message 0x%x\n",
- asc->sc_dev.dv_xname, asc->target, msg);
- reject:
- /* request a message out before acknowledging this message */
- state->msg_out = SCSI_MESSAGE_REJECT;
- regs->asc_cmd = ASC_CMD_SET_ATN;
- readback(regs->asc_cmd);
- }
-
-done:
- /* return to original script */
- regs->asc_cmd = ASC_CMD_MSG_ACPT;
- readback(regs->asc_cmd);
- if (!state->script) {
- printf("asc_msg_in: target %d, no script?\n", asc->target);
-
- abort:
-#ifdef DEBUG
- asc_DumpLog("asc_msg_in");
-#endif
- panic("asc_msg_in");
- }
- asc->script = state->script;
- state->script = (script_t *)0;
- return (0);
-}
-
-/* ARGSUSED */
-static int
-asc_disconnect(asc, status, ss, ir)
- register asc_softc_t asc;
- register int status, ss, ir;
-{
- int i;
-#ifdef DIAGNOSTIC
- /* later Mach driver checks for late asych disconnect here. */
- register State *state = &asc->st[asc->target];
-
- if (!(state->flags & DISCONN)) {
- printf("asc_disconnect: device %d: DISCONN not set!\n",
- asc->target);
- }
-#endif /*DIAGNOSTIC*/
- asc->target = -1;
- asc->state = ASC_STATE_RESEL;
- /*
- * Look for another device that is ready.
- * May want to keep last one started and increment for fairness
- * rather than always starting at zero.
- */
- for (i = 0; i < ASC_NCMD; i++) {
- /* don't restart a disconnected command */
- if (!asc->cmd[i] || asc->st[i].flags & DISCONN)
- continue;
- asc_startcmd(asc, i);
- return (0);
- }
- return (1);
-}
-
-void
-asc_timeout(arg)
- void *arg;
-{
- int s = splbio();
- ScsiCmd *scsicmd = (ScsiCmd *) arg;
-
- printf("asc_timeout: cmd %p drive %d\n", scsicmd, scsicmd->sd->sd_drive);
-#ifdef DEBUG
- asc_DumpLog("asc_timeout");
-#endif
-#if 0
- panic("asc_timeout");
-#else
- boot(RB_NOSYNC); /* XXX */
-#endif
- splx(s);
-}
-
-
-#ifdef DEBUG
-void
-asc_DumpLog(str)
- char *str;
-{
- register struct asc_log *lp;
- register u_int status;
-
- printf("asc: %s: cmd %x bn %d cnt %d\n", str, asc_debug_cmd,
- asc_debug_bn, asc_debug_sz);
- lp = asc_logp;
- do {
- status = lp->status;
- printf("asc%d tgt %d status %x ss %x ir %x cond %d:%x msg %x resid %d\n",
- status >> 24,
- lp->target,
- (status >> 16) & 0xFF,
- (status >> 8) & 0xFF,
- status & 0XFF,
- lp->state,
- asc_scripts[lp->state].condition,
- lp->msg, lp->resid);
- if (++lp >= &asc_log[NLOG])
- lp = asc_log;
- } while (lp != asc_logp);
-}
-#endif /*DEBUG*/
-
-#endif /* NASC > 0 */
diff --git a/sys/dev/tc/asc_ioasic.c b/sys/dev/tc/asc_ioasic.c
deleted file mode 100644
index fde58e9355f..00000000000
--- a/sys/dev/tc/asc_ioasic.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/* $OpenBSD: asc_ioasic.c,v 1.5 2001/06/25 15:27:59 aaron Exp $ */
-/* $NetBSD: asc_ioasic.c,v 1.12 1998/01/12 09:51:30 thorpej Exp $ */
-
-/*
- * Copyright 1996 The Board of Trustees of The Leland Stanford
- * Junior University. All Rights Reserved.
- *
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies. Stanford University
- * makes no representations about the suitability of this
- * software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- */
-#define USE_CACHED_BUFFER 0
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/timeout.h>
-#include <sys/device.h>
-#include <dev/tc/tcvar.h>
-#include <dev/tc/ioasicvar.h>
-#include <machine/autoconf.h>
-
-#include <pmax/dev/device.h> /* XXX */
-#include <pmax/dev/scsi.h> /* XXX */
-
-#include <pmax/dev/ascreg.h> /* XXX */
-#include <dev/tc/ascvar.h>
-
-#include <machine/cpu.h>
-#include <machine/bus.h> /* bus, cache consistency, etc */
-
-/*XXX*/
-#include <pmax/pmax/asic.h> /* XXX ioasic register defs? */
-#include <pmax/pmax/kmin.h> /* XXX ioasic register defs? */
-#include <pmax/pmax/pmaxtype.h>
-extern int pmax_boardtype;
-
-extern vm_offset_t kvtophys __P((vm_offset_t));
-
-/*
- * Autoconfiguration data for config.
- */
-int asc_ioasic_match __P((struct device *, void *, void *));
-void asc_ioasic_attach __P((struct device *, struct device *, void *));
-
-struct cfattach asc_ioasic_ca = {
- sizeof(struct asc_softc), asc_ioasic_match, asc_ioasic_attach
-};
-
-#ifdef notdef
-extern struct cfdriver asc_cd;
-#endif
-
-/*
- * DMA callback declarations
- */
-
-#ifdef ASC_IOASIC_BOUNCE
-extern u_long asc_iomem;
-#endif
-static int
-asic_dma_start __P((asc_softc_t asc, State *state, caddr_t cp, int flag,
- int len, int off));
-
-static void
-asic_dma_end __P((asc_softc_t asc, State *state, int flag));
-
-int
-asc_ioasic_match(parent, match, aux)
- struct device *parent;
- void *match;
- void *aux;
-{
- struct ioasicdev_attach_args *d = aux;
- void *ascaddr;
-
- if (strncmp(d->iada_modname, "asc", TC_ROM_LLEN) &&
- strncmp(d->iada_modname, "PMAZ-AA ", TC_ROM_LLEN))
- return (0);
-
- /* probe for chip */
- ascaddr = (void*)d->iada_addr;
- if (tc_badaddr(ascaddr + ASC_OFFSET_53C94))
- return (0);
-
- return (1);
-}
-
-void
-asc_ioasic_attach(parent, self, aux)
- struct device *parent;
- struct device *self;
- void *aux;
-{
- register struct ioasicdev_attach_args *d = aux;
- register asc_softc_t asc = (asc_softc_t) self;
-#ifdef ASC_IOASIC_BOUNCE
- u_char *buff;
- int i;
-#endif
-
- void *ascaddr;
- int unit;
-
- ascaddr = (void*)MIPS_PHYS_TO_KSEG1(d->iada_addr);
- unit = asc->sc_dev.dv_unit;
-
- /*
- * Initialize hw descriptor, cache some pointers
- */
- asc->regs = (asc_regmap_t *)(ascaddr + ASC_OFFSET_53C94);
-
- /*
- * Set up machine dependencies.
- * (1) how to do dma
- * (2) timing based on turbochannel frequency
- */
-
-#ifdef ASC_IOASIC_BOUNCE
-#if USE_CACHED_BUFFER
- /* XXX Use cached address for DMA buffer to increase raw read speed */
- buff = (u_char *)MIPS_PHYS_TO_KSEG0(asc_iomem);
-#else
- buff = (u_char *)MIPS_PHYS_TO_KSEG1(asc_iomem);
-#endif /* USE_CACHED_BUFFER */
- /*
- * Statically partition the DMA buffer between targets.
- * This way we will eventually be able to attach/detach
- * drives on-fly. And 18k/target is plenty for normal use.
- */
-
- /*
- * Give each target its own DMA buffer region.
- * We may want to try ping ponging buffers later.
- */
- for (i = 0; i < ASC_NCMD; i++)
- asc->st[i].dmaBufAddr = buff + 8192 * i;
-
-#endif /* ASC_IOASIC_BOUNCE */
- *((volatile int *)IOASIC_REG_SCSI_DMAPTR(ioasic_base)) = -1;
- *((volatile int *)IOASIC_REG_SCSI_DMANPTR(ioasic_base)) = -1;
- *((volatile int *)IOASIC_REG_SCSI_SCR(ioasic_base)) = 0;
- asc->dma_start = asic_dma_start;
- asc->dma_end = asic_dma_end;
-
- /* digital meters show IOASIC 53c94s are clocked at approx 25MHz */
- ascattach(asc, ASC_SPEED_25_MHZ);
-
- /* tie pseudo-slot to device */
-
- ioasic_intr_establish(parent, d->iada_cookie, TC_IPL_BIO,
- asc_intr, asc);
-}
-
-
-/*
- * DMA handling routines. For a turbochannel device, just set the dmar.
- * For the I/O ASIC, handle the actual DMA interface.
- */
-static int
-asic_dma_start(asc, state, cp, flag, len, off)
- asc_softc_t asc;
- State *state;
- caddr_t cp;
- int flag;
- int len;
- int off;
-{
- register volatile u_int *ssr = (volatile u_int *)
- IOASIC_REG_CSR(ioasic_base);
- u_int phys, nphys;
-
- /* stop DMA engine first */
- *ssr &= ~IOASIC_CSR_DMAEN_SCSI;
- *((volatile int *)IOASIC_REG_SCSI_SCR(ioasic_base)) = 0;
-
-#ifndef ASC_IOASIC_BOUNCE
- /* restrict len to the maximum the IOASIC can transfer */
- if (len > ((caddr_t)mips_trunc_page(cp + NBPG * 2) - cp))
- len = (caddr_t)mips_trunc_page(cp + NBPG * 2) - cp;
-
- /* If R4K, writeback and invalidate the buffer */
- if (CPUISMIPS3)
- mips3_HitFlushDCache((vm_offset_t)cp, len);
-
- /* Get physical address of buffer start, no next phys addr */
- phys = (u_int)kvtophys((vm_offset_t)cp);
- nphys = -1;
-
- /* Compute 2nd DMA pointer only if next page is part of this I/O */
- if ((NBPG - (phys & (NBPG - 1))) < len) {
- cp = (caddr_t)mips_trunc_page(cp + NBPG);
- nphys = (u_int)kvtophys((vm_offset_t)cp);
- }
-
- /* If not R4K, need to invalidate cache lines for both physical segments */
- if (!CPUISMIPS3 && flag == ASCDMA_READ) {
- MachFlushDCache(MIPS_PHYS_TO_KSEG0(phys),
- nphys == 0xffffffff ? len : NBPG - (phys & (NBPG - 1)));
- if (nphys != 0xffffffff)
- MachFlushDCache(MIPS_PHYS_TO_KSEG0(nphys),
- NBPG); /* XXX */
- }
-#else /* ASC_IOASIC_BOUNCE */
- /* restrict len to the maximum the IOASIC can transfer */
- if (len > ((caddr_t)mips_trunc_page(state->dmaBufAddr + off + NBPG * 2) - (caddr_t)(state->dmaBufAddr + off)))
- len = (caddr_t)mips_trunc_page(state->dmaBufAddr + off + NBPG * 2) - (caddr_t)(state->dmaBufAddr + off);
-
- if (flag == ASCDMA_WRITE)
- bcopy(cp, state->dmaBufAddr + off, len);
- cp = state->dmaBufAddr + off;
-#if USE_CACHED_BUFFER
-#ifdef MIPS3
- /* If R4K, need to writeback the bounce buffer */
- if (CPUISMIPS3)
- mips3_HitFlushDCache((vm_offset_t)cp, len);
-#endif /* MIPS3 */
- phys = MIPS_KSEG0_TO_PHYS(cp);
- cp = (caddr_t)mips_trunc_page(cp + NBPG);
- nphys = MIPS_KSEG0_TO_PHYS(cp);
-#else
- phys = MIPS_KSEG1_TO_PHYS(cp);
- cp = (caddr_t)mips_trunc_page(cp + NBPG);
- nphys = MIPS_KSEG1_TO_PHYS(cp);
-#endif /* USE_CACHED_BUFFER */
-#endif /* ASC_IOASIC_BOUNCE */
-
-#ifdef notyet
- asc->dma_next = cp;
- asc->dma_xfer = state->dmalen - (nphys - phys);
-#endif
-
- *(volatile int *)IOASIC_REG_SCSI_DMAPTR(ioasic_base) =
- IOASIC_DMA_ADDR(phys);
- *(volatile int *)IOASIC_REG_SCSI_DMANPTR(ioasic_base) =
- IOASIC_DMA_ADDR(nphys);
- if (flag == ASCDMA_READ)
- *ssr |= IOASIC_CSR_SCSI_DIR | IOASIC_CSR_DMAEN_SCSI;
- else
- *ssr = (*ssr & ~IOASIC_CSR_SCSI_DIR) | IOASIC_CSR_DMAEN_SCSI;
- wbflush();
- return (len);
-}
-
-static void
-asic_dma_end(asc, state, flag)
- asc_softc_t asc;
- State *state;
- int flag;
-{
- register volatile u_int *ssr = (volatile u_int *)
- IOASIC_REG_CSR(ioasic_base);
- register volatile u_int *dmap = (volatile u_int *)
- IOASIC_REG_SCSI_DMAPTR(ioasic_base);
- register u_short *to;
- register int w;
- int nb;
-
- *ssr &= ~IOASIC_CSR_DMAEN_SCSI;
-#if USE_CACHED_BUFFER /* XXX - Should uncached address always be used? */
- to = (u_short *)MIPS_PHYS_TO_KSEG0(*dmap >> 3);
-#else
- to = (u_short *)MIPS_PHYS_TO_KSEG1(*dmap >> 3);
-#endif
- *dmap = -1;
- *((volatile int *)IOASIC_REG_SCSI_DMANPTR(ioasic_base)) = -1;
- wbflush();
-
- if (flag == ASCDMA_READ) {
-#if !defined(ASC_IOASIC_BOUNCE) && USE_CACHED_BUFFER
- /* Invalidate cache for the buffer */
-#ifdef MIPS3
- if (CPUISMIPS3)
- MachFlushDCache(MIPS_KSEG1_TO_PHYS(state->dmaBufAddr),
- state->dmalen);
- else
-#endif /* MIPS3 */
- MachFlushDCache(MIPS_PHYS_TO_KSEG0(
- MIPS_KSEG1_TO_PHYS(state->dmaBufAddr)),
- state->dmalen);
-#endif /* USE_CACHED_BUFFER */
- if ( (nb = *((int *)IOASIC_REG_SCSI_SCR(ioasic_base))) != 0) {
- /* pick up last upto6 bytes, sigh. */
-
- /* Last byte really xferred is.. */
- w = *(int *)IOASIC_REG_SCSI_SDR0(ioasic_base);
- *to++ = w;
- if (--nb > 0) {
- w >>= 16;
- *to++ = w;
- }
- if (--nb > 0) {
- w = *(int *)IOASIC_REG_SCSI_SDR1(ioasic_base);
- *to++ = w;
- }
- }
-#ifdef ASC_IOASIC_BOUNCE
- bcopy(state->dmaBufAddr, state->buf, state->dmalen);
-#endif
- }
-}
-
-#ifdef notdef
-/*
- * Called by asic_intr() for scsi dma pointer update interrupts.
- */
-void
-asc_dma_intr()
-{
- asc_softc_t asc = &asc_cd.cd_devs[0]; /*XXX*/
- u_int next_phys;
-
- asc->dma_xfer -= NBPG;
- if (asc->dma_xfer <= -NBPG) {
- volatile u_int *ssr = (volatile u_int *)
- IOASIC_REG_CSR(ioasic_base);
- *ssr &= ~IOASIC_CSR_DMAEN_SCSI;
- } else {
- asc->dma_next += NBPG;
- next_phys = MIPS_KSEG0_TO_PHYS(asc->dma_next);
- }
- *(volatile int *)IOASIC_REG_SCSI_DMANPTR(ioasic_base) =
- IOASIC_DMA_ADDR(next_phys);
- wbflush();
-}
-#endif /*notdef*/
diff --git a/sys/dev/tc/asc_tc.c b/sys/dev/tc/asc_tc.c
deleted file mode 100644
index a47a6299eaf..00000000000
--- a/sys/dev/tc/asc_tc.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/* $OpenBSD: asc_tc.c,v 1.4 2001/06/25 15:27:59 aaron Exp $ */
-/* $NetBSD: asc_tc.c,v 1.8 1997/10/31 06:29:59 jonathan Exp $ */
-
-/*
- * Copyright 1996 The Board of Trustees of The Leland Stanford
- * Junior University. All Rights Reserved.
- *
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies. Stanford University
- * makes no representations about the suitability of this
- * software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/timeout.h>
-#include <sys/types.h>
-#include <sys/device.h>
-#include <dev/tc/tcvar.h>
-#include <machine/autoconf.h>
-#include <dev/tc/ioasicvar.h>
-
-#include <pmax/dev/device.h> /* XXX */
-#include <pmax/dev/scsi.h> /* XXX */
-
-#include <pmax/dev/ascreg.h> /* XXX */
-#include <dev/tc/ascvar.h>
-
-/*XXX*/
-
-
-/*
- * Autoconfiguration data for config.
- */
-int asc_tc_match __P((struct device *, void *, void *));
-void asc_tc_attach __P((struct device *, struct device *, void *));
-
-struct cfattach asc_tc_ca = {
- sizeof(struct asc_softc), asc_tc_match, asc_tc_attach
-};
-
-/*
- * DMA callbacks
- */
-
-static int
-tc_dma_start __P((struct asc_softc *asc, struct scsi_state *state,
- caddr_t cp, int flag, int len, int off));
-
-static void
-tc_dma_end __P((struct asc_softc *asc, struct scsi_state *state,
- int flag));
-
-
-int
-asc_tc_match(parent, match, aux)
- struct device *parent;
- void *match;
- void *aux;
-{
- struct tc_attach_args *t = aux;
- void *ascaddr;
-
- if (strncmp(t->ta_modname, "PMAZ-AA ", TC_ROM_LLEN))
- return (0);
-
- ascaddr = (void*)t->ta_addr;
-
- if (tc_badaddr(ascaddr + ASC_OFFSET_53C94))
- return (0);
-
- return (1);
-}
-
-
-
-void
-asc_tc_attach(parent, self, aux)
- struct device *parent;
- struct device *self;
- void *aux;
-{
- register struct tc_attach_args *t = aux;
- register asc_softc_t asc = (asc_softc_t) self;
- u_char *buff;
- int i, speed;
-
- void *ascaddr;
- int unit;
-
- /* Use uncached address for chip registers. */
- ascaddr = (void*)MIPS_PHYS_TO_KSEG1(t->ta_addr);
- unit = asc->sc_dev.dv_unit;
-
- /*
- * Initialize hw descriptor, cache some pointers
- */
- asc->regs = (asc_regmap_t *)(ascaddr + ASC_OFFSET_53C94);
-
- /*
- * Set up machine dependencies.
- * (1) how to do dma
- * (2) timing based on turbochannel frequency
- */
-
- /*
- * Fall through for turbochannel option.
- */
- asc->dmar = (volatile int *)(ascaddr + ASC_OFFSET_DMAR);
- buff = (u_char *)(ascaddr + ASC_OFFSET_RAM);
-
- /*
- * Statically partition the DMA buffer between targets.
- * This way we will eventually be able to attach/detach
- * drives on-fly. And 18k/target is plenty for normal use.
- */
-
- /*
- * Give each target its own DMA buffer region.
- * We may want to try ping ponging buffers later.
- */
- for (i = 0; i < ASC_NCMD; i++)
- asc->st[i].dmaBufAddr = buff + PER_TGT_DMA_SIZE * i;
-
- asc->dma_start = tc_dma_start;
- asc->dma_end = tc_dma_end;
-
- /*
- * Now for timing. The 3max has a 25Mhz tb whereas the 3min and
- * maxine are 12.5Mhz.
- */
- printf(" (bus speed: %s MHz) ", t->ta_busspeed? "25" : "12.5");
-
- switch (t->ta_busspeed) {
- case TC_SPEED_25_MHZ:
- speed = ASC_SPEED_25_MHZ;
- break;
-
- default:
- printf(" (unknown TC speed, assuming 12.5MHz) ");
- /* FALLTHROUGH*/
- case TC_SPEED_12_5_MHZ:
- speed = ASC_SPEED_12_5_MHZ;
- break;
- };
-
- ascattach(asc, speed);
-
- /* tie pseudo-slot to device */
- tc_intr_establish(parent, t->ta_cookie, TC_IPL_BIO,
- asc_intr, asc);
-}
-
-
-/*
- * DMA handling routines. For a turbochannel device, just set the dmar.
- * For the I/O ASIC, handle the actual DMA interface.
- */
-static int
-tc_dma_start(asc, state, cp, flag, len, off)
- asc_softc_t asc;
- State *state;
- caddr_t cp;
- int flag;
- int len;
- int off;
-{
-
- if (len > PER_TGT_DMA_SIZE)
- len = PER_TGT_DMA_SIZE;
- if (flag == ASCDMA_WRITE)
- bcopy(cp, state->dmaBufAddr + off, len);
- if (flag == ASCDMA_WRITE)
- *asc->dmar = ASC_DMAR_WRITE | ASC_DMA_ADDR(state->dmaBufAddr + off);
- else
- *asc->dmar = ASC_DMA_ADDR(state->dmaBufAddr + off);
- return (len);
-}
-
-static void
-tc_dma_end(asc, state, flag)
- asc_softc_t asc;
- State *state;
- int flag;
-{
- if (flag == ASCDMA_READ)
- bcopy(state->dmaBufAddr, state->buf, state->dmalen);
-}
diff --git a/sys/dev/tc/ascvar.h b/sys/dev/tc/ascvar.h
deleted file mode 100644
index fac62d72ea3..00000000000
--- a/sys/dev/tc/ascvar.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* $OpenBSD: ascvar.h,v 1.7 2001/06/25 15:27:59 aaron Exp $ */
-/* $NetBSD: ascvar.h,v 1.4 1997/11/28 18:23:40 mhitch Exp $ */
-
-
-/*
- * State kept for each active SCSI device.
- */
-struct script;
-
-typedef struct scsi_state {
- struct script *script; /* saved script while processing error */
- int statusByte; /* status byte returned during STATUS_PHASE */
- int error; /* errno to pass back to device driver */
- u_char *dmaBufAddr; /* DMA buffer address */
- int dmalen; /* amount to transfer in this chunk */
- int dmaresid; /* amount not transferred if chunk suspended */
- int buflen; /* total remaining amount of data to transfer */
- char *buf; /* current pointer within scsicmd->buf */
- int flags; /* see below */
- int msglen; /* number of message bytes to read */
- int msgcnt; /* number of message bytes received */
- u_char sync_period; /* DMA synchronous period */
- u_char sync_offset; /* DMA synchronous xfer offset or 0 if async */
- u_char msg_out; /* next MSG_OUT byte to send */
- u_char msg_in[16]; /* buffer for multibyte messages */
-} State;
-
-/* state flags */
-#define DISCONN 0x001 /* true if currently disconnected from bus */
-#define DMA_IN_PROGRESS 0x002 /* true if data DMA started */
-#define DMA_IN 0x004 /* true if reading from SCSI device */
-#define DMA_RESUME 0x08 /* true if DMA was interrupted by disc. */
-#define DMA_OUT 0x010 /* true if writing to SCSI device */
-#define DID_SYNC 0x020 /* true if synchronous offset was negotiated */
-#define TRY_SYNC 0x040 /* true if try neg. synchronous offset */
-#define PARITY_ERR 0x080 /* true if parity error seen */
-#define CHECK_SENSE 0x100 /* true if doing sense command */
-
-
-/*
- * State kept for each active SCSI host interface (53C94).
- */
-
-struct asc_softc {
- struct device sc_dev; /* us as a device */
- asc_regmap_t *regs; /* chip address */
- volatile int *dmar; /* DMA address register address */
- int sc_id; /* SCSI ID of this interface */
- int myidmask; /* ~(1 << myid) */
- int state; /* current SCSI connection state */
- int target; /* target SCSI ID if busy */
- struct script *script; /* next expected interrupt & action */
- ScsiCmd *cmd[ASC_NCMD]; /* active command indexed by SCSI ID */
- State st[ASC_NCMD]; /* state info for each active command */
- /* Start dma routine */
- int (*dma_start) __P((struct asc_softc *asc,
- struct scsi_state *state,
- caddr_t cp, int flag, int len, int off));
- /* End dma routine */
- void (*dma_end) __P((struct asc_softc *asc,
- struct scsi_state *state, int flag));
-
- u_char *dma_next;
- int dma_xfer; /* Dma len still to go */
- int min_period; /* Min transfer period clk/byte */
- int max_period; /* Max transfer period clk/byte */
- int ccf; /* CCF, whatever that really is? */
- int timeout_250; /* 250ms timeout */
- int tb_ticks; /* 4ns. ticks/tb channel ticks */
- struct timeout asc_timo;
-#ifdef USE_NEW_SCSI
- struct scsi_link sc_link; /* scsipi link struct */
-#endif
-};
-typedef struct asc_softc *asc_softc_t;
-
-#define ASC_STATE_IDLE 0 /* idle state */
-#define ASC_STATE_BUSY 1 /* selecting or currently connected */
-#define ASC_STATE_TARGET 2 /* currently selected as target */
-#define ASC_STATE_RESEL 3 /* currently waiting for reselect */
-
-
-#define ASC_SPEED_25_MHZ 250
-#define ASC_SPEED_12_5_MHZ 125
-
-void ascattach __P((struct asc_softc *asc, int bus_speed));
-int asc_intr __P ((void *asc));
-
-/*
- * Dma operations.
- */
-#define ASCDMA_READ 1
-#define ASCDMA_WRITE 2
diff --git a/sys/dev/tc/if_le_ibus.c b/sys/dev/tc/if_le_ibus.c
deleted file mode 100644
index 6f2420e428d..00000000000
--- a/sys/dev/tc/if_le_ibus.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/* $OpenBSD: if_le_ibus.c,v 1.3 1998/09/16 22:41:21 jason Exp $ */
-/* $NetBSD: if_le_ibus.c,v 1.3 1996/05/20 23:19:16 jonathan Exp $ */
-
-/*
- * Copyright 1996 The Board of Trustees of The Leland Stanford
- * Junior University. All Rights Reserved.
- *
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies. Stanford University
- * makes no representations about the suitability of this
- * software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- * This driver was contributed by Jonathan Stone.
- */
-
-/*
- * LANCE on Decstation kn01/kn220(?) baseboard.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/mbuf.h>
-#include <sys/syslog.h>
-#include <sys/socket.h>
-#include <sys/device.h>
-
-#include <net/if.h>
-#include <net/if_media.h>
-
-#ifdef INET
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-#endif
-
-#include <dev/ic/am7990reg.h>
-#include <dev/ic/am7990var.h>
-
-#include <dev/tc/if_levar.h>
-#include <dev/tc/tcvar.h>
-#include <machine/autoconf.h>
-#include <pmax/pmax/kn01.h>
-#include <pmax/pmax/kn01var.h>
-
-extern struct cfdriver mainbus_cd; /* should be in header but where? */
-
-extern void le_dec_copytobuf_gap2 __P((struct am7990_softc *, void *,
- int, int));
-extern void le_dec_copyfrombuf_gap2 __P((struct am7990_softc *, void *,
- int, int));
-
-hide void le_dec_zerobuf_gap2 __P((struct am7990_softc *, int, int));
-
-
-int le_pmax_match __P((struct device *, void *, void *));
-void le_pmax_attach __P((struct device *, struct device *, void *));
-
-struct cfattach le_pmax_ca = {
- sizeof(struct le_softc), le_pmax_match, le_pmax_attach
-};
-
-
-int
-le_pmax_match(parent, match, aux)
- struct device *parent;
- void *match, *aux;
-{
- if (parent->dv_cfdata->cf_driver == &mainbus_cd) {
- struct confargs *d = aux;
- if (strcmp("lance", d->ca_name) == 0)
- return (1);
- }
- return (0);
-}
-
-void
-le_pmax_attach(parent, self, aux)
- struct device *parent, *self;
- void *aux;
-{
- register struct le_softc *lesc = (void *)self;
- register struct am7990_softc *sc = &lesc->sc_am7990;
- register u_char *cp;
- register struct confargs *ca = aux;
-
- /*
- * It's on the baseboard, with a dedicated interrupt line.
- */
- lesc->sc_r1 = (struct lereg1 *)(ca->ca_addr);
-/*XXX*/ sc->sc_mem = (void *)TC_PHYS_TO_UNCACHED(0x19000000);
-/*XXX*/ cp = (u_char *)(TC_PHYS_TO_UNCACHED(KN01_SYS_CLOCK) + 1);
-
- sc->sc_copytodesc = le_dec_copytobuf_gap2;
- sc->sc_copyfromdesc = le_dec_copyfrombuf_gap2;
- sc->sc_copytobuf = le_dec_copytobuf_gap2;
- sc->sc_copyfrombuf = le_dec_copyfrombuf_gap2;
- sc->sc_zerobuf = le_dec_zerobuf_gap2;
-
- dec_le_common_attach(sc, cp);
- /* XXX more thought about ca->slotpri */
- kn01_intr_establish(parent, (void*)ca->ca_slotpri, TC_IPL_NET,
- am7990_intr, sc);
-}
-
-/*
- * gap2: two bytes of data followed by two bytes of pad.
- *
- * Buffers must be 4-byte aligned. The code doesn't worry about
- * doing an extra byte.
- */
-
-void
-le_dec_copytobuf_gap2(sc, fromv, boff, len)
- struct am7990_softc *sc;
- void *fromv;
- int boff;
- register int len;
-{
- volatile caddr_t buf = sc->sc_mem;
- register caddr_t from = fromv;
- register volatile u_int16_t *bptr;
-
- if (boff & 0x1) {
- /* handle unaligned first byte */
- bptr = ((volatile u_int16_t *)buf) + (boff - 1);
- *bptr = (*from++ << 8) | (*bptr & 0xff);
- bptr += 2;
- len--;
- } else
- bptr = ((volatile u_int16_t *)buf) + boff;
- while (len > 1) {
- *bptr = (from[1] << 8) | (from[0] & 0xff);
- bptr += 2;
- from += 2;
- len -= 2;
- }
- if (len == 1)
- *bptr = (u_int16_t)*from;
-}
-
-void
-le_dec_copyfrombuf_gap2(sc, tov, boff, len)
- struct am7990_softc *sc;
- void *tov;
- int boff, len;
-{
- volatile caddr_t buf = sc->sc_mem;
- register caddr_t to = tov;
- register volatile u_int16_t *bptr;
- register u_int16_t tmp;
-
- if (boff & 0x1) {
- /* handle unaligned first byte */
- bptr = ((volatile u_int16_t *)buf) + (boff - 1);
- *to++ = (*bptr >> 8) & 0xff;
- bptr += 2;
- len--;
- } else
- bptr = ((volatile u_int16_t *)buf) + boff;
- while (len > 1) {
- tmp = *bptr;
- *to++ = tmp & 0xff;
- *to++ = (tmp >> 8) & 0xff;
- bptr += 2;
- len -= 2;
- }
- if (len == 1)
- *to = *bptr & 0xff;
-}
-
-void
-le_dec_zerobuf_gap2(sc, boff, len)
- struct am7990_softc *sc;
- int boff, len;
-{
- volatile caddr_t buf = sc->sc_mem;
- register volatile u_int16_t *bptr;
-
- if ((unsigned)boff & 0x1) {
- bptr = ((volatile u_int16_t *)buf) + (boff - 1);
- *bptr &= 0xff;
- bptr += 2;
- len--;
- } else
- bptr = ((volatile u_int16_t *)buf) + boff;
- while (len > 0) {
- *bptr = 0;
- bptr += 2;
- len -= 2;
- }
-}
diff --git a/sys/dev/tc/tcvar.h b/sys/dev/tc/tcvar.h
index 3be4d7677c8..8d68b170276 100644
--- a/sys/dev/tc/tcvar.h
+++ b/sys/dev/tc/tcvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcvar.h,v 1.6 1996/12/08 01:03:07 niklas Exp $ */
+/* $OpenBSD: tcvar.h,v 1.7 2001/06/27 20:23:38 miod Exp $ */
/* $NetBSD: tcvar.h,v 1.7 1996/10/22 21:37:31 cgd Exp $ */
/*
@@ -35,23 +35,18 @@
* Definitions for TurboChannel autoconfiguration.
*/
-#ifdef __alpha__ /* XXX pmax does not yet have machine/bus.h */
#include <machine/bus.h>
-#endif
#include <dev/tc/tcreg.h>
/*
* Machine-dependent definitions.
*/
-#if (alpha + pmax != 1)
+#if !defined(__alpha__)
ERROR: COMPILING FOR UNSUPPORTED MACHINE, OR MORE THAN ONE.
#endif
-#if alpha
+#ifdef __alpha__
#include <alpha/tc/tc_machdep.h>
#endif
-#if pmax
-#include <machine/tc_machdep.h>
-#endif
/*
* In the long run, the following block will go completely away
@@ -74,17 +69,6 @@ ERROR: COMPILING FOR UNSUPPORTED MACHINE, OR MORE THAN ONE.
#define TC_IPL_TTY IPL_TTY
#define TC_IPL_CLOCK IPL_CLOCK
-#else
-/*
- * On the pmax, we still need the old definitions.
- */
-typedef enum {
- TC_IPL_NONE, /* block only this interrupt */
- TC_IPL_BIO, /* block disk interrupts */
- TC_IPL_NET, /* block network interrupts */
- TC_IPL_TTY, /* block terminal interrupts */
- TC_IPL_CLOCK, /* block clock interrupts */
-} tc_intrlevel_t;
#endif
/*