diff options
Diffstat (limited to 'scsi/adapters/scsi_53C700_hdw.c')
-rw-r--r-- | scsi/adapters/scsi_53C700_hdw.c | 696 |
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 61b5a3ba..00000000 --- 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*/ - |