summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/bt742a.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/i386/isa/bt742a.c')
-rw-r--r--sys/i386/isa/bt742a.c1617
1 files changed, 0 insertions, 1617 deletions
diff --git a/sys/i386/isa/bt742a.c b/sys/i386/isa/bt742a.c
deleted file mode 100644
index 0e25091..0000000
--- a/sys/i386/isa/bt742a.c
+++ /dev/null
@@ -1,1617 +0,0 @@
-/*
- * Written by Julian Elischer (julian@tfs.com)
- * for TRW Financial Systems for use under the MACH(2.5) operating system.
- *
- * TRW Financial Systems, in accordance with their agreement with Carnegie
- * Mellon University, makes this software available to CMU to distribute
- * or use in any manner that they see fit as long as this message is kept with
- * the software. For this reason TFS also grants any other persons or
- * organisations permission to use or modify this software.
- *
- * TFS supplies this software to be publicly redistributed
- * on the understanding that TFS is not responsible for the correct
- * functioning of this software in any circumstances.
- *
- * $Id: bt742a.c,v 1.7 1993/08/28 03:07:42 rgrimes Exp $
- */
-
-/*
- * bt742a SCSI driver
- */
-
-#include <sys/types.h>
-#include <bt.h>
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/errno.h>
-#include <sys/ioctl.h>
-#include <sys/buf.h>
-#include <sys/proc.h>
-#include <sys/user.h>
-
-#ifdef MACH /* EITHER CMU OR OSF */
-#include <i386/ipl.h>
-#include <i386at/scsi.h>
-#include <i386at/scsiconf.h>
-
-#ifdef OSF /* OSF ONLY */
-#include <sys/table.h>
-#include <i386/handler.h>
-#include <i386/dispatcher.h>
-#include <i386/AT386/atbus.h>
-
-#else OSF /* CMU ONLY */
-#include <i386at/atbus.h>
-#include <i386/pio.h>
-#endif OSF
-#endif MACH /* end of MACH specific */
-
-#ifdef __386BSD__ /* 386BSD specific */
-#define isa_dev isa_device
-#define dev_unit id_unit
-#define dev_addr id_iobase
-
-#include <i386/isa/isa_device.h>
-#include <scsi/scsi_all.h>
-#include <scsi/scsiconf.h>
-#endif __386BSD__
-
-
-#ifdef __386BSD__
-#include "ddb.h"
-#if NDDB > 0
-int Debugger();
-#else NDDB
-#define Debugger() panic("should call debugger here (bt742a.c)")
-#endif NDDB
-#endif __386BSD__
-
-#ifdef MACH
-int Debugger();
-#endif MACH
-
-extern int hz;
-extern int delaycount; /* from clock setup code */
-typedef unsigned long int physaddr;
-
-/*
- * I/O Port Interface
- */
-
-#define BT_BASE bt_base[unit]
-#define BT_CTRL_STAT_PORT (BT_BASE + 0x0) /* control & status */
-#define BT_CMD_DATA_PORT (BT_BASE + 0x1) /* cmds and datas */
-#define BT_INTR_PORT (BT_BASE + 0x2) /* Intr. stat */
-
-/*
- * BT_CTRL_STAT bits (write)
- */
-
-#define BT_HRST 0x80 /* Hardware reset */
-#define BT_SRST 0x40 /* Software reset */
-#define BT_IRST 0x20 /* Interrupt reset */
-#define BT_SCRST 0x10 /* SCSI bus reset */
-
-/*
- * BT_CTRL_STAT bits (read)
- */
-
-#define BT_STST 0x80 /* Self test in Progress */
-#define BT_DIAGF 0x40 /* Diagnostic Failure */
-#define BT_INIT 0x20 /* Mbx Init required */
-#define BT_IDLE 0x10 /* Host Adapter Idle */
-#define BT_CDF 0x08 /* cmd/data out port full */
-#define BT_DF 0x04 /* Data in port full */
-#define BT_INVDCMD 0x01 /* Invalid command */
-
-/*
- * BT_CMD_DATA bits (write)
- */
-
-#define BT_NOP 0x00 /* No operation */
-#define BT_MBX_INIT 0x01 /* Mbx initialization */
-#define BT_START_SCSI 0x02 /* start scsi command */
-#define BT_START_BIOS 0x03 /* start bios command */
-#define BT_INQUIRE 0x04 /* Adapter Inquiry */
-#define BT_MBO_INTR_EN 0x05 /* Enable MBO available interrupt */
-#define BT_SEL_TIMEOUT_SET 0x06 /* set selection time-out */
-#define BT_BUS_ON_TIME_SET 0x07 /* set bus-on time */
-#define BT_BUS_OFF_TIME_SET 0x08 /* set bus-off time */
-#define BT_SPEED_SET 0x09 /* set transfer speed */
-#define BT_DEV_GET 0x0a /* return installed devices */
-#define BT_CONF_GET 0x0b /* return configuration data */
-#define BT_TARGET_EN 0x0c /* enable target mode */
-#define BT_SETUP_GET 0x0d /* return setup data */
-#define BT_WRITE_CH2 0x1a /* write channel 2 buffer */
-#define BT_READ_CH2 0x1b /* read channel 2 buffer */
-#define BT_WRITE_FIFO 0x1c /* write fifo buffer */
-#define BT_READ_FIFO 0x1d /* read fifo buffer */
-#define BT_ECHO 0x1e /* Echo command data */
-#define BT_MBX_INIT_EXTENDED 0x81 /* Mbx initialization */
-#define BT_INQUIRE_EXTENDED 0x8D /* Adapter Setup Inquiry */
-
-/* Follows command appeared at FirmWare 3.31 */
-#define BT_ROUND_ROBIN 0x8f /* Enable/Disable(default) round robin */
-#define BT_DISABLE 0x00 /* Parameter value for Disable */
-#define BT_ENABLE 0x01 /* Parameter value for Enable */
-
-struct bt_cmd_buf {
- u_char byte[16];
-};
-
-/*
- * BT_INTR_PORT bits (read)
- */
-
-#define BT_ANY_INTR 0x80 /* Any interrupt */
-#define BT_SCRD 0x08 /* SCSI reset detected */
-#define BT_HACC 0x04 /* Command complete */
-#define BT_MBOA 0x02 /* MBX out empty */
-#define BT_MBIF 0x01 /* MBX in full */
-
-/*
- * Mail box defs
- */
-
-#define BT_MBX_SIZE 255 /* mail box size (MAX 255 MBxs) */
-#define BT_CCB_SIZE 32 /* store up to 32CCBs at any one time */
- /* in bt742a H/W ( Not MAX ? ) */
-
-#define bt_nextmbx( wmb, mbx, mbio ) \
- if ( (wmb) == &((mbx)->mbio[BT_MBX_SIZE - 1 ]) ) { \
- (wmb) = &((mbx)->mbio[0]); \
- } else { \
- (wmb)++; \
- }
-
-
-typedef struct bt_mbx_out {
- physaddr ccb_addr;
- unsigned char dummy[3];
- unsigned char cmd;
-} BT_MBO;
-
-typedef struct bt_mbx_in{
- physaddr ccb_addr;
- unsigned char btstat;
- unsigned char sdstat;
- unsigned char dummy;
- unsigned char stat;
-} BT_MBI;
-
-struct bt_mbx
-{
- BT_MBO mbo[BT_MBX_SIZE];
- BT_MBI mbi[BT_MBX_SIZE];
- BT_MBO *tmbo; /* Target Mail Box out */
- BT_MBI *tmbi; /* Target Mail Box in */
-};
-
-/*
- * mbo.cmd values
- */
-
-#define BT_MBO_FREE 0x0 /* MBO entry is free */
-#define BT_MBO_START 0x1 /* MBO activate entry */
-#define BT_MBO_ABORT 0x2 /* MBO abort entry */
-
-#define BT_MBI_FREE 0x0 /* MBI entry is free */
-#define BT_MBI_OK 0x1 /* completed without error */
-#define BT_MBI_ABORT 0x2 /* aborted ccb */
-#define BT_MBI_UNKNOWN 0x3 /* Tried to abort invalid CCB */
-#define BT_MBI_ERROR 0x4 /* Completed with error */
-
-extern struct bt_mbx bt_mbx[];
-
-#if defined(BIG_DMA)
-/* #define BT_NSEG 8192 /* Number of scatter gather segments - to much vm */
-#define BT_NSEG 512
-#else
-#define BT_NSEG 33
-#endif /* BIG_DMA */
-struct bt_scat_gath
- {
- unsigned long seg_len;
- physaddr seg_addr;
- };
-
-struct bt_ccb {
- unsigned char opcode;
- unsigned char :3,data_in:1,data_out:1,:3;
- unsigned char scsi_cmd_length;
- unsigned char req_sense_length;
- /*------------------------------------longword boundary */
- unsigned long data_length;
- /*------------------------------------longword boundary */
- physaddr data_addr;
- /*------------------------------------longword boundary */
- unsigned char dummy[2];
- unsigned char host_stat;
- unsigned char target_stat;
- /*------------------------------------longword boundary */
- unsigned char target;
- unsigned char lun;
- unsigned char scsi_cmd[12]; /* 12 bytes (bytes only)*/
- unsigned char dummy2[1];
- unsigned char link_id;
- /*------------------------------------4 longword boundary */
- physaddr link_addr;
- /*------------------------------------longword boundary */
- physaddr sense_ptr;
- /*------------------------------------longword boundary */
- struct scsi_sense_data scsi_sense;
- /*------------------------------------longword boundary */
- struct bt_scat_gath scat_gath[BT_NSEG];
- /*------------------------------------longword boundary */
- struct bt_ccb *next;
- /*------------------------------------longword boundary */
- struct scsi_xfer *xfer; /* the scsi_xfer for this cmd */
- /*------------------------------------longword boundary */
- struct bt_mbx_out *mbx; /* pointer to mail box */
- /*------------------------------------longword boundary */
- int flags;
-#define CCB_FREE 0
-#define CCB_ACTIVE 1
-#define CCB_ABORTED 2
-};
-
-/*
- * opcode fields
- */
-
-#define BT_INITIATOR_CCB 0x00 /* SCSI Initiator CCB */
-#define BT_TARGET_CCB 0x01 /* SCSI Target CCB */
-#define BT_INIT_SCAT_GATH_CCB 0x02 /* SCSI Initiator with scattter gather*/
-#define BT_RESET_CCB 0x81 /* SCSI Bus reset */
-
-
-/*
- * bt_ccb.host_stat values
- */
-
-#define BT_OK 0x00 /* cmd ok */
-#define BT_LINK_OK 0x0a /* Link cmd ok */
-#define BT_LINK_IT 0x0b /* Link cmd ok + int */
-#define BT_SEL_TIMEOUT 0x11 /* Selection time out */
-#define BT_OVER_UNDER 0x12 /* Data over/under run */
-#define BT_BUS_FREE 0x13 /* Bus dropped at unexpected time */
-#define BT_INV_BUS 0x14 /* Invalid bus phase/sequence */
-#define BT_BAD_MBO 0x15 /* Incorrect MBO cmd */
-#define BT_BAD_CCB 0x16 /* Incorrect ccb opcode */
-#define BT_BAD_LINK 0x17 /* Not same values of LUN for links */
-#define BT_INV_TARGET 0x18 /* Invalid target direction */
-#define BT_CCB_DUP 0x19 /* Duplicate CCB received */
-#define BT_INV_CCB 0x1a /* Invalid CCB or segment list */
-#define BT_ABORTED 42 /* pseudo value from driver */
-
-struct bt_boardID
-{
- u_char board_type;
- u_char custom_feture;
- char firm_revision;
- u_char firm_version;
-};
-
-struct bt_setup
-{
- u_char sync_neg:1;
- u_char parity:1;
- u_char :6;
- u_char speed;
- u_char bus_on;
- u_char bus_off;
- u_char num_mbx;
- u_char mbx[3];
- struct {
- u_char offset:4;
- u_char period:3;
- u_char valid:1;
- }sync[8];
- u_char disc_sts;
-};
-
-struct bt_config
-{
- u_char chan;
- u_char intr;
- u_char scsi_dev:3;
- u_char :5;
-};
-
-#define INT9 0x01
-#define INT10 0x02
-#define INT11 0x04
-#define INT12 0x08
-#define INT14 0x20
-#define INT15 0x40
-
-#define EISADMA 0x00
-#define CHAN0 0x01
-#define CHAN5 0x20
-#define CHAN6 0x40
-#define CHAN7 0x80
-
-
-
-
-#ifdef MACH
-extern physaddr kvtophys();
-#define PHYSTOKV(x) phystokv(x)
-#define KVTOPHYS(x) kvtophys(x)
-#endif MACH
-
-#ifdef __386BSD__
-#define KVTOPHYS(x) vtophys(x)
-#endif __386BSD__
-
-
-
-#define PAGESIZ 4096
-#define INVALIDATE_CACHE {asm volatile( ".byte 0x0F ;.byte 0x08" ); }
-
-
-u_char bt_scratch_buf[256];
-#ifdef MACH
-caddr_t bt_base[NBT]; /* base port for each board */
-#else MACH
-short bt_base[NBT]; /* base port for each board */
-#endif MACH
-struct bt_mbx bt_mbx[NBT];
-struct bt_ccb *bt_ccb_free[NBT];
-struct bt_ccb bt_ccb[NBT][BT_CCB_SIZE];
-struct scsi_xfer bt_scsi_xfer[NBT];
-struct isa_dev *btinfo[NBT];
-struct bt_ccb *bt_get_ccb();
-int bt_int[NBT];
-int bt_dma[NBT];
-int bt_scsi_dev[NBT];
-int bt_initialized[NBT];
-#if defined(OSF)
-int bt_attached[NBT];
-#endif /* defined(OSF) */
-
-/***********debug values *************/
-#define BT_SHOWCCBS 0x01
-#define BT_SHOWINTS 0x02
-#define BT_SHOWCMDS 0x04
-#define BT_SHOWMISC 0x08
-int bt_debug = 0;
-
-
-int btprobe(), btattach();
-int btintr();
-
-#ifdef MACH
-struct isa_driver btdriver = { btprobe, 0, btattach, "bt", 0, 0, 0};
-int (*btintrs[])() = {btintr, 0};
-#endif MACH
-
-#ifdef __386BSD__
-struct isa_driver btdriver = { btprobe, btattach, "bt"};
-#endif __386BSD__
-
-static int btunit = 0;
-
-int bt_scsi_cmd();
-int bt_timeout();
-void btminphys();
-long int bt_adapter_info();
-
-struct scsi_switch bt_switch =
-{
- bt_scsi_cmd,
- btminphys,
- 0,
- 0,
- bt_adapter_info,
- "bt",
- 0,0
-};
-#define BT_CMD_TIMEOUT_FUDGE 200 /* multiplied to get Secs */
-#define BT_RESET_TIMEOUT 1000000
-#define BT_SCSI_TIMEOUT_FUDGE 20 /* divided by for mSecs */
-
-
-/***********************************************************************\
-* bt_cmd(unit,icnt, ocnt,wait, retval, opcode, args) *
-* Activate Adapter command *
-* icnt: number of args (outbound bytes written after opcode) *
-* ocnt: number of expected returned bytes *
-* wait: number of seconds to wait for response *
-* retval: buffer where to place returned bytes *
-* opcode: opcode BT_NOP, BT_MBX_INIT, BT_START_SCSI ... *
-* args: parameters *
-* *
-* Performs an adapter command through the ports. Not to be confused *
-* with a scsi command, which is read in via the dma *
-* One of the adapter commands tells it to read in a scsi command *
-\***********************************************************************/
-bt_cmd(unit,icnt, ocnt, wait,retval, opcode, args)
-
-u_char *retval;
-unsigned opcode;
-u_char args;
-{
- unsigned *ic = &opcode;
- u_char oc;
- register i;
- int sts;
-
- /*******************************************************\
- * multiply the wait argument by a big constant *
- * zero defaults to 1 *
- \*******************************************************/
- if(!wait)
- wait = BT_CMD_TIMEOUT_FUDGE * delaycount;
- else
- wait *= BT_CMD_TIMEOUT_FUDGE * delaycount;
- /*******************************************************\
- * Wait for the adapter to go idle, unless it's one of *
- * the commands which don't need this *
- \*******************************************************/
- if (opcode != BT_MBX_INIT && opcode != BT_START_SCSI)
- {
- i = BT_CMD_TIMEOUT_FUDGE * delaycount; /* 1 sec?*/
- while (--i)
- {
- sts = inb(BT_CTRL_STAT_PORT);
- if (sts & BT_IDLE)
- {
- break;
- }
- }
- if (!i)
- {
- printf("bt%d: bt_cmd, host not idle(0x%x)\n",unit,sts);
- return(ENXIO);
- }
- }
- /*******************************************************\
- * Now that it is idle, if we expect output, preflush the*
- * queue feeding to us. *
- \*******************************************************/
- if (ocnt)
- {
- while((inb(BT_CTRL_STAT_PORT)) & BT_DF)
- inb(BT_CMD_DATA_PORT);
- }
-
- /*******************************************************\
- * Output the command and the number of arguments given *
- * for each byte, first check the port is empty. *
- \*******************************************************/
- icnt++; /* include the command */
- while (icnt--)
- {
- sts = inb(BT_CTRL_STAT_PORT);
- for (i=0; i< wait; i++)
- {
- sts = inb(BT_CTRL_STAT_PORT);
- if (!(sts & BT_CDF))
- break;
- }
- if (i >= wait)
- {
- printf("bt%d: bt_cmd, cmd/data port full\n",unit);
- outb(BT_CTRL_STAT_PORT, BT_SRST);
- return(ENXIO);
- }
- outb(BT_CMD_DATA_PORT, (u_char)(*ic++));
- }
- /*******************************************************\
- * If we expect input, loop that many times, each time, *
- * looking for the data register to have valid data *
- \*******************************************************/
- while (ocnt--)
- {
- sts = inb(BT_CTRL_STAT_PORT);
- for (i=0; i< wait; i++)
- {
- sts = inb(BT_CTRL_STAT_PORT);
- if (sts & BT_DF)
- break;
- }
- if (i >= wait)
- {
- printf("bt%d: bt_cmd, cmd/data port empty %d\n",
- unit,ocnt);
- return(ENXIO);
- }
- oc = inb(BT_CMD_DATA_PORT);
- if (retval)
- *retval++ = oc;
- }
- /*******************************************************\
- * Wait for the board to report a finised instruction *
- \*******************************************************/
- i=BT_CMD_TIMEOUT_FUDGE * delaycount; /* 1 sec? */
- while (--i)
- {
- sts = inb(BT_INTR_PORT);
- if (sts & BT_HACC)
- {
- break;
- }
- }
- if (!i)
- {
- printf("bt%d: bt_cmd, host not finished(0x%x)\n",unit,sts);
- return(ENXIO);
- }
- outb(BT_CTRL_STAT_PORT, BT_IRST);
- return(0);
-}
-
-/*******************************************************\
-* Check if the device can be found at the port given *
-* and if so, set it up ready for further work *
-* as an argument, takes the isa_dev structure from *
-* autoconf.c *
-\*******************************************************/
-
-btprobe(dev)
-struct isa_dev *dev;
-{
- /***********************************************\
- * find unit and check we have that many defined *
- \***********************************************/
- int unit = btunit;
-#if defined(OSF)
- static ihandler_t bt_handler[NBT];
- static ihandler_id_t *bt_handler_id[NBT];
- register ihandler_t *chp = &bt_handler[unit];;
-#endif /* defined(OSF) */
-
- dev->dev_unit = unit;
- bt_base[unit] = dev->dev_addr;
- if(unit >= NBT)
- {
- printf("bt%d: unit number too high\n",unit);
- return(0);
- }
- /***********************************************\
- * Try initialise a unit at this location *
- * sets up dma and bus speed, loads bt_int[unit]*
- \***********************************************/
- if (bt_init(unit) != 0)
- {
- return(0);
- }
-
- /***********************************************\
- * If it's there, put in it's interrupt vectors *
- \***********************************************/
-#ifdef MACH
- dev->dev_pic = bt_int[unit];
-#if defined(OSF) /* OSF */
- chp->ih_level = dev->dev_pic;
- chp->ih_handler = dev->dev_intr[0];
- chp->ih_resolver = i386_resolver;
- chp->ih_rdev = dev;
- chp->ih_stats.intr_type = INTR_DEVICE;
- chp->ih_stats.intr_cnt = 0;
- chp->ih_hparam[0].intparam = unit;
- if ((bt_handler_id[unit] = handler_add(chp)) != NULL)
- handler_enable(bt_handler_id[unit]);
- else
- panic("Unable to add bt interrupt handler");
-#else /* CMU */
- take_dev_irq(dev);
-#endif /* !defined(OSF) */
- printf("port=%x spl=%d\n", dev->dev_addr, dev->dev_spl);
-#endif MACH
-#ifdef __386BSD__ /* 386BSD */
- dev->id_irq = (1 << bt_int[unit]);
- dev->id_drq = bt_dma[unit];
-#endif __386BSD__
-
- btunit++;
- return(1);
-}
-
-/***********************************************\
-* Attach all the sub-devices we can find *
-\***********************************************/
-btattach(dev)
-struct isa_dev *dev;
-{
- int unit = dev->dev_unit;
-
-
- /***********************************************\
- * ask the adapter what subunits are present *
- \***********************************************/
- scsi_attachdevs( unit, bt_scsi_dev[unit], &bt_switch);
-#if defined(OSF)
- bt_attached[unit]=1;
-#endif /* defined(OSF) */
- return;
-}
-
-/***********************************************\
-* Return some information to the caller about *
-* the adapter and it's capabilities *
-\***********************************************/
-long int bt_adapter_info(unit)
-int unit;
-{
- return(2); /* 2 outstanding requests at a time per device */
-}
-
-/***********************************************\
-* Catch an interrupt from the adaptor *
-\***********************************************/
-btintr(unit)
-{
- BT_MBI *wmbi;
- struct bt_mbx *wmbx;
- struct bt_ccb *ccb;
- unsigned char stat;
- int i,wait;
- int found = 0;
-
-#ifdef UTEST
- if(scsi_debug & PRINTROUTINES)
- printf("btintr ");
-#endif
- /***********************************************\
- * First acknowlege the interrupt, Then if it's *
- * not telling about a completed operation *
- * just return. *
- \***********************************************/
- stat = inb(BT_INTR_PORT);
-
- /* Mail Box out empty ? */
- if ( stat & BT_MBOA ) {
- printf("bt%d: Available Free mbo post\n",unit);
- /* Disable MBO available interrupt */
- outb(BT_CMD_DATA_PORT,BT_MBO_INTR_EN);
- wait = BT_CMD_TIMEOUT_FUDGE * delaycount;
- for (i=0; i< wait; i++)
- {
- if (!(inb(BT_CTRL_STAT_PORT) & BT_CDF))
- break;
- }
- if (i >= wait)
- {
- printf("bt%d: bt_intr, cmd/data port full\n",unit);
- outb(BT_CTRL_STAT_PORT, BT_SRST);
- return 1;
- }
- outb(BT_CMD_DATA_PORT, 0x00); /* Disable */
- wakeup(&bt_mbx[unit]);
- outb(BT_CTRL_STAT_PORT, BT_IRST);
- return 1;
- }
- if (! (stat & BT_MBIF)) {
- outb(BT_CTRL_STAT_PORT, BT_IRST);
- return 1;
- }
-#if defined(OSF)
- if (!bt_attached[unit])
- {
- return(1);
- }
-#endif /* defined(OSF) */
- /***********************************************\
- * If it IS then process the competed operation *
- \***********************************************/
- wmbx = &bt_mbx[unit];
- wmbi = wmbx->tmbi;
-AGAIN:
- while ( wmbi->stat != BT_MBI_FREE ) {
- found++;
- ccb = (struct bt_ccb *)PHYSTOKV((wmbi->ccb_addr));
- if((stat = wmbi->stat) != BT_MBI_OK)
- {
- switch(stat)
- {
- case BT_MBI_ABORT:
-#ifdef UTEST
- if(bt_debug & BT_SHOWMISC)
- printf("abort ");
-#endif
- ccb->host_stat = BT_ABORTED;
- break;
-
- case BT_MBI_UNKNOWN:
- ccb = (struct bt_ccb *)0;
-#ifdef UTEST
- if(bt_debug & BT_SHOWMISC)
- printf("unknown ccb for abort");
-#endif
- break;
-
- case BT_MBI_ERROR:
- break;
-
- default:
- panic("Impossible mbxi status");
-
- }
-#ifdef UTEST
- if((bt_debug & BT_SHOWCMDS ) && ccb)
- {
- u_char *cp;
- cp = ccb->scsi_cmd;
- printf("op=%x %x %x %x %x %x\n",
- cp[0], cp[1], cp[2],
- cp[3], cp[4], cp[5]);
- printf("stat %x for mbi addr = 0x%08x\n"
- , wmbi->stat, wmbi );
- printf("addr = 0x%x\n", ccb);
- }
-#endif
- }
- wmbi->stat = BT_MBI_FREE;
- if(ccb)
- {
- untimeout(bt_timeout,ccb);
- bt_done(unit,ccb);
- }
-
- /* Set the IN mail Box pointer for next */
- bt_nextmbx( wmbi, wmbx, mbi );
- }
- if ( !found ) {
- for ( i = 0; i < BT_MBX_SIZE; i++) {
- if ( wmbi->stat != BT_MBI_FREE ) {
- found ++;
- break;
- }
- bt_nextmbx( wmbi, wmbx, mbi );
- }
- if ( !found ) {
- printf("bt%d: mbi at 0x%08x should be found, stat=%02x..resync\n",
- unit, wmbi, stat );
- } else {
- found = 0;
- goto AGAIN;
- }
- }
- wmbx->tmbi = wmbi;
- outb(BT_CTRL_STAT_PORT, BT_IRST);
- return(1);
-}
-
-/***********************************************\
-* A ccb (and hence a mbx-out is put onto the *
-* free list. *
-\***********************************************/
-bt_free_ccb(unit,ccb, flags)
-struct bt_ccb *ccb;
-{
- unsigned int opri;
-
-#ifdef UTEST
- if(scsi_debug & PRINTROUTINES)
- printf("ccb%d(0x%x)> ",unit,flags);
-#endif
- if (!(flags & SCSI_NOMASK))
- opri = splbio();
-
- ccb->next = bt_ccb_free[unit];
- bt_ccb_free[unit] = ccb;
- ccb->flags = CCB_FREE;
- /***********************************************\
- * If there were none, wake abybody waiting for *
- * one to come free, starting with queued entries*
- \***********************************************/
- if (!ccb->next) {
- wakeup(&bt_ccb_free[unit]);
- }
- if (!(flags & SCSI_NOMASK))
- splx(opri);
-}
-
-/***********************************************\
-* Get a free ccb *
-\***********************************************/
-struct bt_ccb *
-bt_get_ccb(unit,flags)
-{
- unsigned opri;
- struct bt_ccb *rc;
- struct bt_mbx *wmbx; /* Mail Box pointer specified unit */
- BT_MBO *wmbo; /* Out Mail Box pointer */
-
-#ifdef UTEST
- if(scsi_debug & PRINTROUTINES)
- printf("<ccb%d(0x%x) ",unit,flags);
-#endif
- if (!(flags & SCSI_NOMASK))
- opri = splbio();
- /***********************************************\
- * If we can and have to, sleep waiting for one *
- * to come free *
- \***********************************************/
- while ((!(rc = bt_ccb_free[unit])) && (!(flags & SCSI_NOSLEEP)))
- {
- sleep(&bt_ccb_free[unit], PRIBIO);
- }
- if (rc)
- {
- /* Get CCB from from free list */
- bt_ccb_free[unit] = rc->next;
- rc->flags = CCB_ACTIVE;
-#ifdef HE
- /* Get the Target OUT mail Box pointer */
- wmbx = &bt_mbx[unit];
- wmbo = wmbx->tmbo;
- while ( wmbo->cmd != BT_MBO_FREE ) {
- /* Enable MBO available interrupt */
- outb(BT_CMD_DATA_PORT,BT_MBO_INTR_EN);
- printf("Wait free mbo.."); /* AMURAI */
- sleep( wmbx, PRIBIO);
- printf("Got free mbo\n"); /* AMURAI */
- }
-
- /* Link CCB to the Mail Box */
- rc->mbx = wmbo;
- wmbo->ccb_addr = KVTOPHYS(rc);
-
- /* Set the OUT mail Box pointer for next */
- bt_nextmbx( wmbo, wmbx, mbo );
- wmbx->tmbo = wmbo;
-#endif
- }
- if (!(flags & SCSI_NOMASK))
- splx(opri);
-
- return(rc);
-}
-/***********************************************\
-* Get a MBO and then Send it *
-\***********************************************/
-BT_MBO *bt_send_mbo( int unit,
- int flags,
- int cmd,
- struct bt_ccb *ccb )
-{
- unsigned opri;
- BT_MBO *wmbo; /* Mail Box Out pointer */
- struct bt_mbx *wmbx; /* Mail Box pointer specified unit */
- int i, wait;
-
- wmbx = &bt_mbx[unit];
-
- if (!(flags & SCSI_NOMASK))
- opri = splbio();
-
- /* Get the Target OUT mail Box pointer and move to Next */
- wmbo = wmbx->tmbo;
- wmbx->tmbo = ( wmbo == &( wmbx->mbo[BT_MBX_SIZE - 1 ] ) ?
- &(wmbx->mbo[0]) : wmbo + 1 );
-
- /*
- * Check the outmail box is free or not
- * Note: Under the normal operation, it shuld NOT happen to wait.
- */
- while ( wmbo->cmd != BT_MBO_FREE ) {
-
- wait = BT_CMD_TIMEOUT_FUDGE * delaycount;
- /* Enable MBO available interrupt */
- outb(BT_CMD_DATA_PORT,BT_MBO_INTR_EN);
- for (i=0; i< wait; i++)
- {
- if (!(inb(BT_CTRL_STAT_PORT) & BT_CDF))
- break;
- }
- if (i >= wait)
- {
- printf("bt%d: bt_send_mbo, cmd/data port full\n",unit);
- outb(BT_CTRL_STAT_PORT, BT_SRST);
- return( (BT_MBO *)0 );
- }
- outb(BT_CMD_DATA_PORT, 0x01); /* Enable */
- sleep( wmbx, PRIBIO);
- }
-
- /* Link CCB to the Mail Box */
- wmbo->ccb_addr = KVTOPHYS(ccb);
- ccb->mbx = wmbo;
- wmbo->cmd = cmd;
-
- /* Send it ! */
- outb(BT_CMD_DATA_PORT, BT_START_SCSI);
-
- if (!(flags & SCSI_NOMASK))
- splx(opri);
-
- return(wmbo);
-}
-/***********************************************\
-* We have a ccb which has been processed by the *
-* adaptor, now we look to see how the operation *
-* went. Wake up the owner if waiting *
-\***********************************************/
-bt_done(unit,ccb)
-struct bt_ccb *ccb;
-{
- struct scsi_sense_data *s1,*s2;
- struct scsi_xfer *xs = ccb->xfer;
-
-#ifdef UTEST
- if(scsi_debug & (PRINTROUTINES | TRACEINTERRUPTS))
- printf("bt_done ");
-#endif
- /***********************************************\
- * Otherwise, put the results of the operation *
- * into the xfer and call whoever started it *
- \***********************************************/
- if ( ( ccb->host_stat != BT_OK
- || ccb->target_stat != SCSI_OK)
- && (!(xs->flags & SCSI_ERR_OK)))
- {
-
- s1 = &(ccb->scsi_sense);
- s2 = &(xs->sense);
-
- if(ccb->host_stat)
- {
- switch(ccb->host_stat)
- {
- case BT_ABORTED: /* No response */
- case BT_SEL_TIMEOUT: /* No response */
-#ifdef UTEST
- if (bt_debug & BT_SHOWMISC)
- {
- printf("timeout reported back\n");
- }
-#endif
- xs->error = XS_TIMEOUT;
- break;
- default: /* Other scsi protocol messes */
- xs->error = XS_DRIVER_STUFFUP;
-#ifdef UTEST
- if (bt_debug & BT_SHOWMISC)
- {
- printf("unexpected host_stat: %x\n",
- ccb->host_stat);
- }
-#endif
- }
-
- }
- else
- {
- switch(ccb->target_stat)
- {
- case 0x02:
- /* structure copy!!!!!*/
- *s2=*s1;
- xs->error = XS_SENSE;
- break;
- case 0x08:
- xs->error = XS_BUSY;
- break;
- default:
-#ifdef UTEST
- if (bt_debug & BT_SHOWMISC)
- {
- printf("unexpected target_stat: %x\n",
- ccb->target_stat);
- }
-#endif
- xs->error = XS_DRIVER_STUFFUP;
- }
- }
- }
- else /* All went correctly OR errors expected */
- {
- xs->resid = 0;
- }
- xs->flags |= ITSDONE;
- bt_free_ccb(unit,ccb, xs->flags);
- if(xs->when_done)
- (*(xs->when_done))(xs->done_arg,xs->done_arg2);
-}
-
-/***********************************************\
-* Start the board, ready for normal operation *
-\***********************************************/
-bt_init(unit)
-int unit;
-{
- unsigned char ad[4];
- volatile int i,sts;
- struct bt_config conf;
-
- /***********************************************\
- * reset board, If it doesn't respond, assume *
- * that it's not there.. good for the probe *
- \***********************************************/
-
- outb(BT_CTRL_STAT_PORT, BT_HRST|BT_SRST);
-
- for (i=0; i < BT_RESET_TIMEOUT; i++)
- {
- sts = inb(BT_CTRL_STAT_PORT) ;
- if ( sts == (BT_IDLE | BT_INIT))
- break;
- }
- if (i >= BT_RESET_TIMEOUT)
- {
-#ifdef UTEST
- if (bt_debug & BT_SHOWMISC)
- printf("bt_init: No answer from bt742a board\n");
-#endif
- return(ENXIO);
- }
-
- /***********************************************\
- * Assume we have a board at this stage *
- * setup dma channel from jumpers and save int *
- * level *
- \***********************************************/
-#ifdef __386BSD__
- printf("bt%d: reading board settings, ",unit);
-#else __386BSD__
- printf("bt%d:",unit);
-#endif __386BSD__
-
- bt_cmd(unit,0, sizeof(conf), 0 ,&conf, BT_CONF_GET);
- switch(conf.chan)
- {
- case EISADMA:
- bt_dma[unit] = -1;
- break;
- case CHAN0:
- outb(0x0b, 0x0c);
- outb(0x0a, 0x00);
- bt_dma[unit] = 0;
- break;
- case CHAN5:
- outb(0xd6, 0xc1);
- outb(0xd4, 0x01);
- bt_dma[unit] = 5;
- break;
- case CHAN6:
- outb(0xd6, 0xc2);
- outb(0xd4, 0x02);
- bt_dma[unit] = 6;
- break;
- case CHAN7:
- outb(0xd6, 0xc3);
- outb(0xd4, 0x03);
- bt_dma[unit] = 7;
- break;
- default:
- printf("illegal dma setting %x\n",conf.chan);
- return(EIO);
- }
- if (bt_dma[unit] == -1)
- printf("eisa dma, ");
- else
- printf("dma=%d, ",bt_dma[unit]);
-
- switch(conf.intr)
- {
- case INT9:
- bt_int[unit] = 9;
- break;
- case INT10:
- bt_int[unit] = 10;
- break;
- case INT11:
- bt_int[unit] = 11;
- break;
- case INT12:
- bt_int[unit] = 12;
- break;
- case INT14:
- bt_int[unit] = 14;
- break;
- case INT15:
- bt_int[unit] = 15;
- break;
- default:
- printf("illegal int setting\n");
- return(EIO);
- }
-#ifdef __386BSD__
- printf("int=%d\n",bt_int[unit]);
-#else
- printf("int=%d ",bt_int[unit]);
-#endif __386BSD__
-
- /* who are we on the scsi bus */
- bt_scsi_dev[unit] = conf.scsi_dev;
- /***********************************************\
- * Initialize mail box *
- \***********************************************/
- *((physaddr *)ad) = KVTOPHYS(&bt_mbx[unit]);
- bt_cmd(unit,5, 0, 0, 0, BT_MBX_INIT_EXTENDED
- , BT_MBX_SIZE
- , ad[0]
- , ad[1]
- , ad[2]
- , ad[3]);
-
- /***********************************************\
- * Set Pointer chain null for just in case *
- * Link the ccb's into a free-list W/O mbox *
- * Initilize Mail Box stat to Free *
- \***********************************************/
- if ( bt_ccb_free[unit] != (struct bt_ccb *)0 ) {
- printf("bt%d: bt_ccb_free is NOT initialized but init here\n",
- unit);
- bt_ccb_free[unit] = (struct bt_ccb *)0;
- }
- for (i=0; i < BT_CCB_SIZE; i++) {
- bt_ccb[unit][i].next = bt_ccb_free[unit];
- bt_ccb_free[unit] = &bt_ccb[unit][i];
- bt_ccb_free[unit]->flags = CCB_FREE;
- }
- for (i=0; i < BT_MBX_SIZE; i++) {
- bt_mbx[unit].mbo[i].cmd = BT_MBO_FREE;
- bt_mbx[unit].mbi[i].stat = BT_MBI_FREE;
- }
-
- /***********************************************\
- * Set up Initial mail box for round-robin *
- \***********************************************/
- bt_mbx[unit].tmbo = &bt_mbx[unit].mbo[0];
- bt_mbx[unit].tmbi = &bt_mbx[unit].mbi[0];
- bt_inquire_setup_information( unit );
-
- /* Enable round-robin scheme - appeared at FirmWare 3.31 */
- bt_cmd(unit, 1, 0, 0, 0, BT_ROUND_ROBIN, BT_ENABLE );
-
- /***********************************************\
- * Note that we are going and return (to probe) *
- \***********************************************/
- bt_initialized[unit]++;
- return( 0 );
-}
-bt_inquire_setup_information( unit )
-int unit;
-{
- struct bt_setup setup;
- struct bt_boardID bID;
- int i;
-
- /* Inquire Board ID to Bt742 for FirmWare Version */
- bt_cmd(unit, 0, sizeof(bID), 0, &bID, BT_INQUIRE );
- printf("bt%d: version %c.%c, ",
- unit, bID.firm_revision, bID.firm_version );
-
- /* Ask setup information to Bt742 */
- bt_cmd(unit, 1, sizeof(setup), 0, &setup, BT_SETUP_GET, sizeof(setup) );
-
- if ( setup.sync_neg ) {
- printf("sync, ");
- } else {
- printf("async, ");
- }
-
- if ( setup.parity ) {
- printf("parity, ");
- } else {
- printf("no parity, ");
- }
-
- printf("%d mbxs, %d ccbs\n", setup.num_mbx,
- sizeof(bt_ccb)/(sizeof(struct bt_ccb) * NBT) );
-
- for ( i = 0; i < 8; i++ ) {
- if( !setup.sync[i].offset &&
- !setup.sync[i].period &&
- !setup.sync[i].valid )
- continue;
-
- printf("bt%d: dev%02d Offset=%d,Transfer period=%d, Synchronous? %s",
- unit, i,
- setup.sync[i].offset, setup.sync[i].period,
- setup.sync[i].valid ? "Yes" : "No" );
- }
-
-}
-
-
-#ifndef min
-#define min(x,y) (x < y ? x : y)
-#endif min
-
-
-void btminphys(bp)
-struct buf *bp;
-{
-#ifdef MACH
-#if !defined(OSF)
- bp->b_flags |= B_NPAGES; /* can support scat/gather */
-#endif /* defined(OSF) */
-#endif MACH
- if(bp->b_bcount > ((BT_NSEG-1) * PAGESIZ))
- {
- bp->b_bcount = ((BT_NSEG-1) * PAGESIZ);
- }
-}
-
-/***********************************************\
-* start a scsi operation given the command and *
-* the data address. Also needs the unit, target *
-* and lu *
-\***********************************************/
-int bt_scsi_cmd(xs)
-struct scsi_xfer *xs;
-{
- struct scsi_sense_data *s1,*s2;
- struct bt_ccb *ccb;
- struct bt_scat_gath *sg;
- int seg; /* scatter gather seg being worked on */
- int i = 0;
- int rc = 0;
- int thiskv;
- physaddr thisphys,nextphys;
- int unit =xs->adapter;
- int bytes_this_seg,bytes_this_page,datalen,flags;
- struct iovec *iovp;
- BT_MBO *mbo;
-
-#ifdef UTEST
- if(scsi_debug & PRINTROUTINES)
- printf("bt_scsi_cmd ");
-#endif
- /***********************************************\
- * get a ccb (mbox-out) to use. If the transfer *
- * is from a buf (possibly from interrupt time) *
- * then we can't allow it to sleep *
- \***********************************************/
- flags = xs->flags;
- if(xs->bp) flags |= (SCSI_NOSLEEP); /* just to be sure */
- if(flags & ITSDONE)
- {
- printf("bt%d: Already done?\n",unit);
- xs->flags &= ~ITSDONE;
- }
- if(!(flags & INUSE))
- {
- printf("bt%d: Not in use?\n",unit);
- xs->flags |= INUSE;
- }
- if (!(ccb = bt_get_ccb(unit,flags)))
- {
- xs->error = XS_DRIVER_STUFFUP;
- return(TRY_AGAIN_LATER);
- }
-#ifdef UTEST
- if(bt_debug & BT_SHOWCCBS)
- printf("<start ccb(%x)>",ccb);
-#endif
- /***********************************************\
- * Put all the arguments for the xfer in the ccb *
- \***********************************************/
- ccb->xfer = xs;
- if(flags & SCSI_RESET)
- {
- ccb->opcode = BT_RESET_CCB;
- }
- else
- {
- /* can't use S/G if zero length */
- ccb->opcode = (xs->datalen?
- BT_INIT_SCAT_GATH_CCB
- :BT_INITIATOR_CCB);
- }
- ccb->target = xs->targ;;
- ccb->data_out = 0;
- ccb->data_in = 0;
- ccb->lun = xs->lu;
- ccb->scsi_cmd_length = xs->cmdlen;
- ccb->sense_ptr = KVTOPHYS(&(ccb->scsi_sense));
- ccb->req_sense_length = sizeof(ccb->scsi_sense);
-
- if((xs->datalen) && (!(flags & SCSI_RESET)))
- { /* can use S/G only if not zero length */
- ccb->data_addr = KVTOPHYS(ccb->scat_gath);
- sg = ccb->scat_gath ;
- seg = 0;
- if(flags & SCSI_DATA_UIO)
- {
- iovp = ((struct uio *)xs->data)->uio_iov;
- datalen = ((struct uio *)xs->data)->uio_iovcnt;
- xs->datalen = 0;
- while ((datalen) && (seg < BT_NSEG))
- {
- sg->seg_addr = (physaddr)iovp->iov_base;
- xs->datalen += sg->seg_len = iovp->iov_len;
-#ifdef UTEST
- if(scsi_debug & SHOWSCATGATH)
- printf("(0x%x@0x%x)"
- ,iovp->iov_len
- ,iovp->iov_base);
-#endif
- sg++;
- iovp++;
- seg++;
- datalen--;
- }
- }
- else
- {
- /***********************************************\
- * Set up the scatter gather block *
- \***********************************************/
-
-#ifdef UTEST
- if(scsi_debug & SHOWSCATGATH)
- printf("%d @0x%x:- ",xs->datalen,xs->data);
-#endif
- datalen = xs->datalen;
- thiskv = (int)xs->data;
- thisphys = KVTOPHYS(thiskv);
-
- while ((datalen) && (seg < BT_NSEG))
- {
- bytes_this_seg = 0;
-
- /* put in the base address */
- sg->seg_addr = thisphys;
-
-#ifdef UTEST
- if(scsi_debug & SHOWSCATGATH)
- printf("0x%x",thisphys);
-#endif
-
- /* do it at least once */
- nextphys = thisphys;
- while ((datalen) && (thisphys == nextphys))
- /*********************************************\
- * This page is contiguous (physically) with *
- * the the last, just extend the length *
- \*********************************************/
- {
- /* how far to the end of the page */
- nextphys= (thisphys & (~(PAGESIZ - 1)))
- + PAGESIZ;
- bytes_this_page = nextphys - thisphys;
- /**** or the data ****/
- bytes_this_page = min(bytes_this_page
- ,datalen);
- bytes_this_seg += bytes_this_page;
- datalen -= bytes_this_page;
-
- /* get more ready for the next page */
- thiskv = (thiskv & (~(PAGESIZ - 1)))
- + PAGESIZ;
- if(datalen)
- thisphys = KVTOPHYS(thiskv);
- }
- /********************************************\
- * next page isn't contiguous, finish the seg *
- \********************************************/
-#ifdef UTEST
- if(scsi_debug & SHOWSCATGATH)
- printf("(0x%x)",bytes_this_seg);
-#endif
- sg->seg_len = bytes_this_seg;
- sg++;
- seg++;
- }
- } /*end of iov/kv decision */
- ccb->data_length = seg * sizeof(struct bt_scat_gath);
-#ifdef UTEST
- if(scsi_debug & SHOWSCATGATH)
- printf("\n");
-#endif
- if (datalen)
- { /* there's still data, must have run out of segs! */
- printf("bt%d: bt_scsi_cmd, more than %d DMA segs\n",
- unit,BT_NSEG);
- xs->error = XS_DRIVER_STUFFUP;
- bt_free_ccb(unit,ccb,flags);
- return(HAD_ERROR);
- }
-
- }
- else
- { /* No data xfer, use non S/G values */
- ccb->data_addr = (physaddr)0;
- ccb->data_length = 0;
- }
- ccb->link_id = 0;
- ccb->link_addr = (physaddr)0;
- /***********************************************\
- * Put the scsi command in the ccb and start it *
- \***********************************************/
- if(!(flags & SCSI_RESET))
- {
- bcopy(xs->cmd, ccb->scsi_cmd, ccb->scsi_cmd_length);
- }
-#ifdef UTEST
- if(scsi_debug & SHOWCOMMANDS)
- {
- u_char *b = ccb->scsi_cmd;
- if(!(flags & SCSI_RESET))
- {
- int i = 0;
- printf("bt%d:%d:%d-"
- ,unit
- ,ccb->target
- ,ccb->lun);
- while(i < ccb->scsi_cmd_length )
- {
- if(i) printf(",");
- printf("%x",b[i++]);
- }
- printf("-\n");
- }
- else
- {
- printf("bt%d:%d:%d-RESET- "
- ,unit
- ,ccb->target
- ,ccb->lun
- );
- }
- }
-#endif
- if ( bt_send_mbo( unit, flags, BT_MBO_START, ccb ) == (BT_MBO *)0 )
- {
- xs->error = XS_DRIVER_STUFFUP;
- bt_free_ccb(unit,ccb,flags);
- return(TRY_AGAIN_LATER);
- }
- /***********************************************\
- * Usually return SUCCESSFULLY QUEUED *
- \***********************************************/
-#ifdef UTEST
- if(scsi_debug & TRACEINTERRUPTS)
- printf("cmd_sent ");
-#endif
- if (!(flags & SCSI_NOMASK))
- {
- timeout(bt_timeout,ccb,(xs->timeout * hz) / 1000);
- return(SUCCESSFULLY_QUEUED);
- } else
- /***********************************************\
- * If we can't use interrupts, poll on completion*
- \***********************************************/
- {
- int done = 0;
- int count = delaycount * xs->timeout / BT_SCSI_TIMEOUT_FUDGE;
- struct bt_mbx *wmbx = &bt_mbx[unit];
- BT_MBI *wmbi = wmbx->tmbi;
- unsigned char stat;
-#ifdef UTEST
- if(scsi_debug & TRACEINTERRUPTS)
- printf("wait ");
-#endif
- while((!done) && count)
- {
- stat = inb(BT_INTR_PORT) & (BT_ANY_INTR | BT_MBIF );
- if ( !( stat & BT_ANY_INTR ) ||
- ( wmbi->stat == BT_MBI_FREE )||
- (PHYSTOKV(wmbi->ccb_addr)
- != (int)ccb ) ) {
- count--;
- continue;
- }
- wmbi->stat = BT_MBI_FREE;
- bt_done(unit,ccb);
- done ++;
- outb(BT_CTRL_STAT_PORT, BT_IRST);
- /* Set the IN mail Box pointer for next */
- bt_nextmbx( wmbi, wmbx, mbi );
- wmbx->tmbi = wmbi;
- }
- if (!count && !done)
- {
-#ifdef UTEST
- if (!(xs->flags & SCSI_SILENT))
- printf("cmd fail\n");
-#endif
- bt_send_mbo( unit, flags, BT_MBO_ABORT, ccb );
- count = delaycount * 2000 / BT_SCSI_TIMEOUT_FUDGE;
- while((!done) && count)
- {
- if ( !( stat & BT_ANY_INTR ) ||
- ( wmbi->stat == BT_MBI_FREE )||
- ( PHYSTOKV(wmbi->ccb_addr )
- != (int)ccb ) ) {
- count--;
- continue;
- }
- wmbi->stat = BT_MBI_FREE;
- bt_done(unit,ccb);
- done ++;
- outb(BT_CTRL_STAT_PORT, BT_IRST);
- /* Set the IN mail Box pointer for next */
- bt_nextmbx( wmbi, wmbx, mbi );
- wmbx->tmbi = wmbi;
- }
- if(!count && !done)
- {
- printf("bt%d: abort failed in wait\n", unit);
- ccb->mbx->cmd = BT_MBO_FREE;
- }
- bt_free_ccb(unit,ccb,flags);
- xs->error = XS_DRIVER_STUFFUP;
- return(HAD_ERROR);
- }
- if(xs->error) return(HAD_ERROR);
- return(COMPLETE);
- }
-}
-
-
-bt_timeout(struct bt_ccb *ccb)
-{
- int unit;
- int s = splbio();
-
- unit = ccb->xfer->adapter;
- printf("bt%d: %d device timed out\n",unit
- ,ccb->xfer->targ);
-#ifdef UTEST
- if(bt_debug & BT_SHOWCCBS)
- bt_print_active_ccbs(unit);
-#endif
-
- /***************************************\
- * If The ccb's mbx is not free, then *
- * the board has gone Far East ? *
- \***************************************/
- if((struct bt_ccb *)PHYSTOKV(ccb->mbx->ccb_addr)==ccb &&
- ccb->mbx->cmd != BT_MBO_FREE )
- {
- printf("bt%d: not taking commands!\n"
- ,unit);
- Debugger();
- }
- /***************************************\
- * If it has been through before, then *
- * a previous abort has failed, don't *
- * try abort again *
- \***************************************/
- if(ccb->flags == CCB_ABORTED) /* abort timed out */
- {
- printf("bt%d: Abort Operation has timed out\n",unit);
- ccb->xfer->retries = 0; /* I MEAN IT ! */
- ccb->host_stat = BT_ABORTED;
- bt_done(unit,ccb);
- }
- else /* abort the operation that has timed out */
- {
- printf("bt%d: Try to abort\n",unit);
- bt_send_mbo( unit, ~SCSI_NOMASK,
- BT_MBO_ABORT, ccb );
- /* 2 secs for the abort */
- timeout(bt_timeout,ccb,2 * hz);
- ccb->flags = CCB_ABORTED;
- }
- splx(s);
-}
-
-#ifdef UTEST
-bt_print_ccb(ccb)
-struct bt_ccb *ccb;
-{
- printf("ccb:%x op:%x cmdlen:%d senlen:%d\n"
- ,ccb
- ,ccb->opcode
- ,ccb->scsi_cmd_length
- ,ccb->req_sense_length);
- printf(" datlen:%d hstat:%x tstat:%x flags:%x\n"
- ,ccb->data_length
- ,ccb->host_stat
- ,ccb->target_stat
- ,ccb->flags);
-}
-
-bt_print_active_ccbs(int unit)
-{
- struct bt_ccb *ccb;
- ccb = &(bt_ccb[unit][0]);
- int i = BT_CCB_SIZE;
-
- while(i--)
- {
- if(ccb->flags != CCB_FREE)
- bt_print_ccb(ccb);
- ccb++;
- }
-}
-#endif /*UTEST*/
OpenPOWER on IntegriCloud