The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/isa/seagate.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * (Free/Net/386)BSD ST01/02, Future Domain TMC-885, TMC-950 SCSI driver for
    3  * Julians SCSI-code
    4  *
    5  * Copyright 1994, Kent Palmkvist (kentp@isy.liu.se)
    6  * Copyright 1994, Robert Knier (rknier@qgraph.com)
    7  * Copyright 1992, 1994 Drew Eckhardt (drew@colorado.edu)
    8  * Copyright 1994, Julian Elischer (julian@tfs.com)
    9  * Copyright 1994-1995, Serge Vakulenko (vak@cronyx.ru)
   10  * Copyright 1995 Stephen Hocking (sysseh@devetir.qld.gov.au)
   11  *
   12  * Others that has contributed by example code is
   13  *              Glen Overby (overby@cray.com)
   14  *              Tatu Yllnen
   15  *              Brian E Litzinger
   16  *
   17  * Redistribution and use in source and binary forms, with or without
   18  * modification, are permitted provided that the following conditions
   19  * are met:
   20  * 1. Redistributions of source code must retain the above copyright
   21  *    notice, this list of conditions and the following disclaimer.
   22  * 2. Redistributions in binary form must reproduce the above copyright
   23  *    notice, this list of conditions and the following disclaimer in the
   24  *    documentation and/or other materials provided with the distribution.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND
   27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE DEVELOPERS BE LIABLE
   30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   36  * SUCH DAMAGE.
   37  */
   38 
   39 /*
   40  * kentp  940307 alpha version based on newscsi-03 version of Julians SCSI-code
   41  * kentp  940314 Added possibility to not use messages
   42  * rknier 940331 Added fast transfer code
   43  * rknier 940407 Added assembler coded data transfers
   44  * vak    941226 New probe algorithm, based on expected behaviour
   45  *               instead of BIOS signatures analysis, better timeout handling,
   46  *               new asm fragments for data input/output, target-dependent
   47  *               delays, device flags, polling mode, generic cleanup
   48  * vak    950115 Added request-sense ops
   49  * seh    950701 Fixed up Future Domain TMC-885 problems with disconnects,
   50  *               weird phases and the like. (we could probably investigate
   51  *               what the board's idea of the phases are, but that requires
   52  *               doco that I don't have). Note that it is slower than the
   53  *               2.0R driver with both SEA_BLINDTRANSFER & SEA_ASSEMBLER
   54  *               defined by a factor of more than 2. I'll look at that later!
   55  * seh    950712 The performance release 8^). Put in the blind transfer code
   56  *               from the 2.0R source. Don't use it by commenting out the 
   57  *               SEA_BLINDTRANSFER below. Note that it only kicks in during
   58  *               DATAOUT or DATAIN and then only when the transfer is a
   59  *               multiple of BLOCK_SIZE bytes (512). Most devices fit into
   60  *               that category, with the possible exception of scanners and
   61  *               some of the older MO drives.
   62  *
   63  * $FreeBSD: src/sys/i386/isa/seagate.c,v 1.18.2.1 1999/09/05 08:13:24 peter Exp $
   64  */
   65 
   66 /*
   67  * What should really be done:
   68  *
   69  * Restructure interrupt enable/disable code (runs too long with int disabled)
   70  * Add code to handle Future Domain 840, 841, 880 and 881
   71  * Add code to use tagged commands in SCSI2
   72  * Add code to handle slow devices better (sleep if device not disconnecting)
   73  * Fix unnecessary interrupts
   74  */
   75 
   76 /* Note to users trying to share a disk between DOS and unix:
   77  * The ST01/02 is a translating host-adapter. It is not giving DOS
   78  * the same number of heads/tracks/sectors as specified by the disk.
   79  * It is therefore important to look at what numbers DOS thinks the
   80  * disk has. Use these to disklabel your disk in an appropriate manner
   81  *
   82  * About ST02+IDE coexistence: the original Seagate ST02
   83  * BIOS cannot coexist with IDE or any other disk controller
   84  * because it does not share BIOS disk drive numbers (80h, 81h)
   85  * with others.  New probing code allows using ST02 controller
   86  * without BIOS: just unplug the ST02 BIOS chip from the board.
   87  *
   88  * Another problem is the floppy adapter on ST02 which could not be
   89  * disabled by jumpers.  I commonly use ST02 adapter as a cheap solution
   90  * for atttaching the tape and CD-ROM drives, and an extra floppy controller
   91  * is just a headache.  I found a simple workaround: cutting off
   92  * the AEN signal (A11 contact on ISA connector).  AEN then goes high and
   93  * disables the floppy adapter port address decoder.
   94  *
   95  * I also had a problem with ST02 conflicting with IDE during
   96  * IDE data write phase.  It seems than ST02 makes some noise
   97  * on /IOW line.  The /IOW line is used only for floppy controller
   98  * part of ST02, and because I don't need it, I cut off the /IOW (contact B13)
   99  * and it helped. (vak)
  100  *
  101  * Tested on the following hardware:
  102  *   Adapter: Seagate ST02
  103  *      Disk: HP D1686
  104  * Streamers: Archive Viper 150, Wangtek 5525
  105  *   CD-ROMs: Toshiba XM-3401, NEC CDR-25
  106  *
  107  * Maximum data rate is about 270-280 kbytes/sec (on 386DX/40).
  108  * (vak)
  109  */
  110 #undef DEBUG
  111 
  112 #include "sea.h"
  113 #if NSEA > 0
  114 
  115 #include <sys/types.h>
  116 #include <sys/param.h>
  117 #include <sys/systm.h>
  118 #include <sys/kernel.h>
  119 #include <sys/errno.h>
  120 #include <sys/ioctl.h>
  121 #include <sys/malloc.h>
  122 #include <sys/buf.h>
  123 #include <sys/proc.h>
  124 
  125 #include <machine/clock.h>
  126 
  127 #include <vm/vm.h>
  128 #include <vm/vm_param.h>
  129 #include <vm/pmap.h>
  130 
  131 #include <i386/isa/isa_device.h>
  132 
  133 #include <scsi/scsi_all.h>
  134 #include <scsi/scsiconf.h>
  135 
  136 #ifdef DEBUG
  137 #   define PRINT(s)     printf s
  138 #else
  139 #   define PRINT(s)     /*void*/
  140 #endif
  141 
  142 #define SCB_TABLE_SIZE  8       /* start with 8 scb entries in table */
  143 #define BLOCK_SIZE      512     /* size of READ/WRITE areas on SCSI card */
  144 #define HOST_SCSI_ADDR  7       /* address of the adapter on the SCSI bus */
  145 #define SEA_BLINDTRANSFER       1       /* for quicker than quick xfers */
  146 /*
  147  * Define config flags
  148  */
  149 #define FLAG_NOPARITY   0x01    /* disable SCSI bus parity check */
  150 
  151 /*
  152  * Board CONTROL register
  153  */
  154 #define CMD_RST         0x01            /* scsi reset */
  155 #define CMD_SEL         0x02            /* scsi select */
  156 #define CMD_BSY         0x04            /* scsi busy */
  157 #define CMD_ATTN        0x08            /* scsi attention */
  158 #define CMD_START_ARB   0x10            /* start arbitration bit */
  159 #define CMD_EN_PARITY   0x20            /* enable scsi parity generation */
  160 #define CMD_INTR        0x40            /* enable scsi interrupts */
  161 #define CMD_DRVR_ENABLE 0x80            /* scsi enable */
  162 
  163 /*
  164  * Board STATUS register
  165  */
  166 #define STAT_BSY        0x01            /* scsi busy */
  167 #define STAT_MSG        0x02            /* scsi msg */
  168 #define STAT_IO         0x04            /* scsi I/O */
  169 #define STAT_CD         0x08            /* scsi C/D */
  170 #define STAT_REQ        0x10            /* scsi req */
  171 #define STAT_SEL        0x20            /* scsi select */
  172 #define STAT_PARITY     0x40            /* parity error bit */
  173 #define STAT_ARB_CMPL   0x80            /* arbitration complete bit */
  174 #define STAT_BITS       "\2\1bsy\2msg\3i/o\4c/d\5req\6sel\7parity\10arb"
  175 
  176 /*
  177  * SCSI bus phases
  178  */
  179 #define PHASE_MASK              (STAT_MSG | STAT_CD | STAT_IO)
  180 #define PHASE_DATAOUT           0
  181 #define PHASE_DATAIN            STAT_IO
  182 #define PHASE_CMDOUT            STAT_CD
  183 #define PHASE_STATIN            (STAT_CD | STAT_IO)
  184 #define PHASE_MSGOUT            (STAT_MSG | STAT_CD)
  185 #define PHASE_MSGIN             (STAT_MSG | STAT_CD | STAT_IO)
  186 #define PHASE_NAME(ph)          phase_name[(ph)>>2]
  187 
  188 static char *phase_name[] = {
  189         "DATAOUT", "Phase1?",  "Phase2?", "Phase3?",
  190         "DATAIN",  "Phase5?",  "Phase6?", "Phase7?",
  191         "CMDOUT",  "Phase9?",  "MSGOUT",  "Phase11?",
  192         "STATIN",  "Phase13?", "MSGIN",   "Phase15?",
  193 };
  194 
  195 /*
  196  * SCSI message codes
  197  */
  198 #define MSG_COMMAND_COMPLETE    0x00
  199 #define MSG_SAVE_POINTERS       0x02
  200 #define MSG_RESTORE_POINTERS    0x03
  201 #define MSG_DISCONNECT          0x04
  202 #define MSG_ABORT               0x06
  203 #define MSG_MESSAGE_REJECT      0x07
  204 #define MSG_NOP                 0x08
  205 #define MSG_BUS_DEV_RESET       0x0c
  206 #define MSG_IDENTIFY(lun)       (0xc0 | ((lun) & 0x7))
  207 #define MSG_ISIDENT(m)          ((m) & 0x80)
  208 
  209 /*
  210  * SCSI control block used to keep info about a scsi command
  211  */
  212 typedef struct scb {
  213         int flags;                      /* status of the instruction */
  214 #define SCB_FREE        0x00
  215 #define SCB_ACTIVE      0x01
  216 #define SCB_ABORTED     0x02
  217 #define SCB_TIMEOUT     0x04
  218 #define SCB_ERROR       0x08
  219 #define SCB_TIMECHK     0x10            /* we have set a timeout on this one */
  220 #define SCB_SENSE       0x20            /* sensed data available */
  221 #define SCB_TBUSY       0x40            /* target busy */
  222         struct scb *next;               /* in free list */
  223         struct scsi_xfer *xfer;         /* the scsi_xfer for this cmd */
  224         u_char *data;                   /* position in data buffer so far */
  225         int32_t datalen;                        /* bytes remaining to transfer */;
  226 } scb_t;
  227 
  228 typedef enum {
  229         CTLR_NONE,
  230         CTLR_SEAGATE,
  231         CTLR_FUTURE_DOMAIN,
  232 } ctlr_t;
  233 
  234 /*
  235  * Flags for waiting for REQ deassert during some SCSI bus phases.
  236  */
  237 typedef struct {
  238         unsigned cmdout1 : 1;   /* after CMDOUT[0] byte */
  239         unsigned cmdout : 1;    /* after CMDOUT[1..N] bytes */
  240         unsigned msgout : 1;    /* after MSGOUT byte */
  241         unsigned statin : 1;    /* after STATIN byte */
  242 } phase_t;
  243 
  244 /*
  245  * Data structure describing the target state.
  246  */
  247 typedef struct {
  248         struct adapter *adapter;        /* pointer to the adapter structure */
  249         u_char  busy;                   /* mask of busy luns at device target */
  250         u_long  perrcnt;                /* counter of target parity errors */
  251         phase_t ndelay;                 /* "don't delay" flags */
  252         phase_t init;                   /* "initialized" flags */
  253 } target_t;
  254 
  255 /*
  256  * Data structure describing current status of the scsi bus. One for each
  257  * controller card.
  258  */
  259 typedef struct adapter {
  260         ctlr_t  type;                   /* Seagate or Future Domain */
  261         char    *name;                  /* adapter name */
  262         volatile u_char *addr;          /* base address for card */
  263 
  264         volatile u_char *CONTROL;       /* address of control register */
  265         volatile u_char *STATUS;        /* address of status register */
  266         volatile u_char *DATA;          /* address of data register */
  267 
  268         u_char  scsi_addr;              /* our scsi address, 0..7 */
  269         u_char  scsi_id;                /* our scsi id mask */
  270         u_char  parity;                 /* parity flag: CMD_EN_PARITY or 0 */
  271         u_char  irq;                    /* IRQ number used or 0 if no IRQ */
  272         u_int   timeout_active : 1;     /* timeout() active (requested) */
  273 
  274         struct scsi_link sc_link;       /* struct connecting different data */
  275         scb_t   *queue;                 /* waiting to be issued */
  276         scb_t   *disconnected_queue;    /* waiting to reconnect */
  277 
  278         int     numscb;                 /* number of scsi control blocks */
  279         scb_t   *free_scb;              /* free scb list */
  280         scb_t   scbs[SCB_TABLE_SIZE];
  281 
  282         target_t target[8];             /* target state data */
  283 } adapter_t;
  284 
  285 static adapter_t seadata[NSEA];
  286 
  287 #define IS_BUSY(a,b)    ((a)->target[(b)->xfer->sc_link->target].busy &\
  288                                 (1 << (b)->xfer->sc_link->lun))
  289 #define SET_BUSY(a,b)   ((a)->target[(b)->xfer->sc_link->target].busy |=\
  290                                 (1 << (b)->xfer->sc_link->lun))
  291 #define CLEAR_BUSY(a,b) ((a)->target[(b)->xfer->sc_link->target].busy &=\
  292                                 ~(1 << (b)->xfer->sc_link->lun))
  293 
  294 /*
  295  * Wait for condition, given as an boolean expression.
  296  * Print the message on timeout.
  297  */
  298 #define WAITFOR(condition,message) {\
  299         register u_long cnt = 100000; char *msg = message;\
  300         while (cnt-- && ! (condition)) continue;\
  301         if (cnt == -1 && msg)\
  302                 printf ("sea: %s timeout\n", msg); }
  303 
  304 #define WAITFOR10(condition,message) {\
  305         register u_long cnt = 1000000; char *msg = message;\
  306         while (cnt-- && ! (condition)) continue;\
  307         if (cnt == -1 && msg)\
  308                 printf ("sea: %s timeout\n", msg); }
  309 
  310 /*
  311  * Seagate adapter does not support in hardware
  312  * waiting for REQ deassert after transferring each data byte.
  313  * We must do it in software.
  314  * The problem is that some SCSI devices deassert REQ so fast that
  315  * we can miss it.  We the flag for each target sayind if we should (not)
  316  * wait for REQ deassert.  This flag is initialized when the first
  317  * operation on the target is done.
  318  * 1) Test if we don't need to wait for REQ deassert (`nodelay' flag).
  319  *    Initially the flag is off, i.e. wait.  If the flag is set,
  320  *    go to the step 4.
  321  * 2) Wait for REQ deassert (call sea_wait_for_req_deassert function).
  322  *    If REQ deassert got, go to the step 4.  If REQ did not cleared
  323  *    during timeout period, go to the next step.
  324  * 3) If `nodelay' flag did not initialized yet (`init' flag),
  325  *    then set `ndelay' flag.
  326  * 4) Set `init' flag.  Done.
  327  */
  328 #define WAITREQ(t,op,cnt) {\
  329         if (! (t)->ndelay.op &&\
  330             ! sea_wait_for_req_deassert ((t)->adapter, cnt, #op) &&\
  331             ! (t)->init.op)\
  332                 (t)->ndelay.op = 1;\
  333         (t)->init.op = 1; }
  334 
  335 static int sea_probe (struct isa_device *dev);
  336 static int sea_detect (adapter_t *z, struct isa_device *dev);
  337 static int sea_attach (struct isa_device *dev);
  338 static int32_t sea_scsi_cmd (struct scsi_xfer *xs);
  339 static u_int32_t sea_adapter_info (int unit);
  340 static void sea_timeout (void *scb);
  341 static void seaminphys (struct buf *bp);
  342 static void sea_done (adapter_t *z, scb_t *scb);
  343 static void sea_start (adapter_t *z);
  344 static void sea_information_transfer (adapter_t *z, scb_t *scb);
  345 static int sea_poll (adapter_t *z, scb_t *scb);
  346 static int sea_init (adapter_t *z);
  347 static int sea_reselect (adapter_t *z);
  348 static int sea_select (volatile adapter_t *z, scb_t *scb);
  349 static int sea_abort (adapter_t *z, scb_t *scb);
  350 static void sea_send_abort (adapter_t *z);
  351 static u_char sea_msg_input (adapter_t *z);
  352 static void sea_tick (void *arg);
  353 static int sea_sense (adapter_t *z, scb_t *scb);
  354 static void sea_data_output (adapter_t *z, u_char **pdata, u_long *plen);
  355 static void sea_data_input (adapter_t *z, u_char **pdata, u_long *plen);
  356 static void sea_cmd_output (target_t *z, u_char *cmd, int cmdlen);
  357 
  358 static struct scsi_adapter sea_switch = {
  359         sea_scsi_cmd, seaminphys, 0, 0, sea_adapter_info, "sea", {0},
  360 };
  361 static struct scsi_device sea_dev = { NULL, NULL, NULL, NULL, "sea", 0, {0} };
  362 struct isa_driver seadriver = { sea_probe, sea_attach, "sea" };
  363 
  364 /* FD TMC885's can't handle detach & re-attach */
  365 static int sea_select_cmd = CMD_DRVR_ENABLE | CMD_ATTN;
  366 
  367 /*
  368  * Check if the device can be found at the port given and if so,
  369  * detect the type of board. Set it up ready for further work.
  370  * Takes the isa_dev structure from autoconf as an argument.
  371  * Returns 1 if card recognized, 0 if errors.
  372  */
  373 int sea_probe (struct isa_device *dev)
  374 {
  375         adapter_t *z = &seadata[dev->id_unit];
  376         static const addrtab[] = {
  377                 0xc8000, 0xca000, 0xcc000, 0xce000, 0xdc000, 0xde000, 0,
  378         };
  379         int i;
  380 
  381         /* Init fields used by our routines */
  382         z->parity = (dev->id_flags & FLAG_NOPARITY) ? 0 : CMD_EN_PARITY;
  383         z->scsi_addr = HOST_SCSI_ADDR;
  384         z->scsi_id = 1 << z->scsi_addr;
  385         z->irq = dev->id_irq ? ffs (dev->id_irq) - 1 : 0;
  386         z->queue = 0;
  387         z->disconnected_queue = 0;
  388         for (i=0; i<8; i++) {
  389                 z->target[i].adapter = z;
  390                 z->target[i].busy = 0;
  391         }
  392 
  393         /* Link up the free list of scbs */
  394         z->numscb = SCB_TABLE_SIZE;
  395         z->free_scb = z->scbs;
  396         for (i=1; i<SCB_TABLE_SIZE; i++)
  397                 z->scbs[i-1].next = z->scbs + i;
  398         z->scbs[SCB_TABLE_SIZE-1].next = 0;
  399 
  400         /* Detect the adapter. */
  401         dev->id_msize = 0x4000;
  402         if (! dev->id_maddr)
  403                 for (i=0; addrtab[i]; ++i) {
  404                         dev->id_maddr = (u_char*) KERNBASE + addrtab[i];
  405                         if (sea_detect (z, dev))
  406                                 return (1);
  407                 }
  408         else if (sea_detect (z, dev))
  409                 return (1);
  410 
  411         bzero (z, sizeof (*z));
  412         return (0);
  413 }
  414 
  415 int sea_detect (adapter_t *z, struct isa_device *dev)
  416 {
  417         z->addr = dev->id_maddr;
  418 
  419         /* Try Seagate. */
  420         z->type    = CTLR_SEAGATE;
  421         z->name    = "Seagate ST01/ST02";
  422         z->CONTROL = z->addr + 0x1a00; /* ST01/ST02 register offsets */
  423         z->STATUS  = z->addr + 0x1a00;
  424         z->DATA    = z->addr + 0x1c00;
  425         if (sea_init (z) == 0)
  426                 return (1);
  427 
  428         /* Try Future Domain. */
  429         z->type    = CTLR_FUTURE_DOMAIN;
  430         z->name    = "Future Domain TMC-885/TMC-950";
  431         z->CONTROL = z->addr + 0x1c00; /* TMC-885/TMC-950 reg. offsets */
  432         z->STATUS  = z->addr + 0x1c00;
  433         z->DATA    = z->addr + 0x1e00;
  434         /* FD TMC885's can't handle detach & re-attach */
  435         sea_select_cmd = CMD_DRVR_ENABLE;
  436         /* FD TMC-885 is supposed to be at id 6. How strange. */
  437         z->scsi_addr = HOST_SCSI_ADDR - 1;
  438         z->scsi_id = 1 << z->scsi_addr;
  439         if (sea_init (z) == 0)
  440                 return (1);
  441 
  442         return (0);
  443 }
  444 
  445 /*
  446  * Probe the adapter, and if found, reset the board and the scsi bus.
  447  * Return 0 if the adapter found.
  448  */
  449 int sea_init (adapter_t *z)
  450 {
  451         volatile u_char *p;
  452         int i, c;
  453 
  454         /* Check that STATUS..STATUS+200h are equal. */
  455         p = z->STATUS;
  456         c = *p;
  457         if (c == 0xff)
  458                 return (2);
  459         while (++p < z->STATUS+0x200)
  460                 if (*p != c)
  461                         return (3);
  462 
  463         /* Check that DATA..DATA+200h are equal. */
  464         for (p=z->DATA, c= *p++; p<z->DATA+0x200; ++p)
  465                 if (*p != c)
  466                         return (4);
  467 
  468         /* Check that addr..addr+1800h are not writable. */
  469         for (p=z->addr; p<z->addr+0x1800; ++p) {
  470                 c = *p;
  471                 *p = ~c;
  472                 if (*p == ~c) {
  473                         *p = c;
  474                         return (5);
  475                 }
  476         }
  477 
  478         /* Check that addr+1800h..addr+1880h are writable. */
  479         for (p=z->addr+0x1800; p<z->addr+0x1880; ++p) {
  480                 c = *p;
  481                 *p = 0x55;
  482                 if (*p != 0x55) {
  483                         *p = c;
  484                         return (6);
  485                 }
  486                 *p = 0xaa;
  487                 if (*p != 0xaa) {
  488                         *p = c;
  489                         return (7);
  490                 }
  491         }
  492 
  493         /* Reset the scsi bus (I don't know if this is needed). */
  494         *z->CONTROL = CMD_RST | CMD_DRVR_ENABLE | z->parity | CMD_INTR;
  495         /* Hold reset for at least 25 microseconds. */
  496         DELAY (25);
  497         /* Check that status cleared. */
  498         if (*z->STATUS != 0) {
  499                 *z->CONTROL = 0;
  500                 return (8);
  501         }
  502 
  503         /* Check that DATA register is writable. */
  504         for (i=0; i<256; ++i) {
  505                 *z->DATA = i;
  506                 if (*z->DATA != i) {
  507                         *z->CONTROL = 0;
  508                         return (9);
  509                 }
  510         }
  511 
  512         /* Enable the adapter. */
  513         *z->CONTROL = CMD_INTR | z->parity;
  514         /* Wait a Bus Clear Delay (800 ns + bus free delay 800 ns). */
  515         DELAY (10);
  516 
  517         /* Check that DATA register is NOT writable. */
  518         c = *z->DATA;
  519         for (i=0; i<256; ++i) {
  520                 *z->DATA = i;
  521                 if (*z->DATA != c) {
  522                         *z->CONTROL = 0;
  523                         return (10);
  524                 }
  525         }
  526 
  527         return (0);
  528 }
  529 
  530 /*
  531  * Attach all sub-devices we can find.
  532  */
  533 int sea_attach (struct isa_device *dev)
  534 {
  535         int unit = dev->id_unit;
  536         adapter_t *z = &seadata[unit];
  537         struct scsibus_data *scbus;
  538 
  539         printf ("\nsea%d: type %s%s\n", unit, z->name,
  540                 (dev->id_flags & FLAG_NOPARITY) ? ", no parity" : "");
  541 
  542         /* fill in the prototype scsi_link */
  543         z->sc_link.adapter_unit = unit;
  544         z->sc_link.adapter_targ = z->scsi_addr;
  545         z->sc_link.adapter_softc = z;
  546         z->sc_link.adapter = &sea_switch;
  547         z->sc_link.device = &sea_dev;
  548 
  549         /*
  550          * Prepare the scsibus_data area for the upperlevel
  551          * scsi code.
  552          */
  553         scbus = scsi_alloc_bus();
  554         if(!scbus)
  555                 return 0;
  556         scbus->adapter_link = &z->sc_link;
  557 
  558         /* ask the adapter what subunits are present */
  559         scsi_attachdevs (scbus);
  560 
  561         return (1);
  562 }
  563 
  564 /*
  565  * Return some information to the caller about
  566  * the adapter and its capabilities.
  567  */
  568 u_int32_t sea_adapter_info (int unit)
  569 {
  570         return (1);
  571 }
  572 
  573 void seaminphys (struct buf *bp)
  574 {
  575 }
  576 
  577 /*
  578  * Catch an interrupt from the adaptor.
  579  */
  580 void seaintr (int unit)
  581 {
  582         adapter_t *z = &seadata[unit];
  583 
  584         PRINT (("sea%d: interrupt status=%b\n", unit, *z->STATUS, STAT_BITS));
  585         sea_start (z);
  586 }
  587 
  588 /*
  589  * This routine is used in the case when we have no IRQ line (z->irq == 0).
  590  * It is called every timer tick and polls for reconnect from target.
  591  */
  592 void sea_tick (void *arg)
  593 {
  594         adapter_t *z = arg;
  595         int x = splbio ();
  596 
  597         z->timeout_active = 0;
  598         sea_start (z);
  599         if (z->disconnected_queue && ! z->timeout_active) {
  600                 timeout (sea_tick, z, 1);
  601                 z->timeout_active = 1;
  602         }
  603         splx (x);
  604 }
  605 
  606 /*
  607  * Start a scsi operation given the command and the data address.
  608  * Also needs the unit, target and lu.  Get a free scb and set it up.
  609  * Call send_scb.  Either start timer or wait until done.
  610  */
  611 int32_t sea_scsi_cmd (struct scsi_xfer *xs)
  612 {
  613         int flags = xs->flags, x = 0;
  614         adapter_t *z = (adapter_t *)xs->sc_link->adapter_softc;
  615         scb_t *scb;
  616 
  617         PRINT (("sea%d/%d/%d command 0x%x\n", unit, xs->sc_link->target,
  618                 xs->sc_link->lun, xs->cmd->opcode)); 
  619         if (xs->bp)
  620                 flags |= SCSI_NOSLEEP;
  621         if (flags & ITSDONE) {
  622                 printf ("sea%d: already done?", xs->sc_link->adapter_unit);
  623                 xs->flags &= ~ITSDONE;
  624         }
  625         if (! (flags & INUSE)) {
  626                 printf ("sea%d: not in use?", xs->sc_link->adapter_unit);
  627                 xs->flags |= INUSE;
  628         }
  629         if (flags & SCSI_RESET)
  630                 printf ("sea%d: SCSI_RESET not implemented\n",
  631                         xs->sc_link->adapter_unit);
  632 
  633         if (! (flags & SCSI_NOMASK))
  634                 x = splbio ();
  635 
  636         /* Get a free scb.
  637          * If we can and have to, sleep waiting for one to come free. */
  638         while (! (scb = z->free_scb)) {
  639                 if (flags & SCSI_NOSLEEP) {
  640                         xs->error = XS_DRIVER_STUFFUP;
  641                         if (! (flags & SCSI_NOMASK))
  642                                 splx (x);
  643                         return (TRY_AGAIN_LATER);
  644                 }
  645                 tsleep ((caddr_t)&z->free_scb, PRIBIO, "seascb", 0);
  646         }
  647         /* Get scb from free list. */
  648         z->free_scb = scb->next;
  649         scb->next = 0;
  650         scb->flags = SCB_ACTIVE;
  651 
  652         /* Put all the arguments for the xfer in the scb */
  653         scb->xfer = xs;
  654         scb->datalen = xs->datalen;
  655         scb->data = xs->data;
  656 
  657         /* Setup the scb to contain necessary values.
  658          * The interesting values can be read from the xs that is saved.
  659          * I therefore think that the structure can be kept very small.
  660          * The driver doesn't use DMA so the scatter/gather is not needed? */
  661         if (! z->queue) {
  662                 scb->next = z->queue;
  663                 z->queue = scb;
  664         } else {
  665                 scb_t *q;
  666 
  667                 for (q=z->queue; q->next; q=q->next)
  668                         continue;
  669                 q->next = scb;
  670                 scb->next = 0;  /* placed at the end of the queue */
  671         }
  672 
  673         /* Try to send this command to the board. */
  674         sea_start (z);
  675 
  676         /* Usually return SUCCESSFULLY QUEUED. */
  677         if (! (flags & SCSI_NOMASK)) {
  678                 splx (x);
  679                 if (xs->flags & ITSDONE)
  680                         /* Timeout timer not started, already finished.
  681                          * Tried to return COMPLETE but the machine hanged
  682                          * with this. */
  683                         return (SUCCESSFULLY_QUEUED);
  684                 timeout (sea_timeout, (caddr_t) scb, (xs->timeout * hz) / 1000);
  685                 scb->flags |= SCB_TIMECHK;
  686                 PRINT (("sea%d/%d/%d command queued\n",
  687                         xs->sc_link->adapter_unit,
  688                         xs->sc_link->target, xs->sc_link->lun));
  689                 return (SUCCESSFULLY_QUEUED);
  690         }
  691 
  692         /* If we can't use interrupts, poll on completion. */
  693         if (! sea_poll (z, scb)) {
  694                 /* We timed out, so call the timeout handler manually,
  695                  * accounting for the fact that the clock is not running yet
  696                  * by taking out the clock queue entry it makes. */
  697                 sea_timeout ((void*) scb);
  698 
  699                 /* Because we are polling, take out the timeout entry
  700                  * sea_timeout made. */
  701                 untimeout (sea_timeout, (void*) scb);
  702 
  703                 if (! sea_poll (z, scb))
  704                         /* We timed out again... This is bad. Notice that
  705                          * this time there is no clock queue entry to remove. */
  706                         sea_timeout ((void*) scb);
  707         }
  708         PRINT (("sea%d/%d/%d command %s\n", xs->sc_link->adapter_unit,
  709                 xs->sc_link->target, xs->sc_link->lun,
  710                 xs->error ? "failed" : "done")); 
  711         return (xs->error ? HAD_ERROR : COMPLETE);
  712 }
  713 
  714 /*
  715  * Coroutine that runs as long as more work can be done.
  716  * Both scsi_cmd() and intr() will try to start it in
  717  * case it is not running.
  718  * Always called with interrupts disabled.
  719  */
  720 void sea_start (adapter_t *z)
  721 {
  722         scb_t *q, *prev;
  723 again:
  724         /* First check that if any device has tried
  725          * a reconnect while we have done other things
  726          * with interrupts disabled. */
  727         if (sea_reselect (z))
  728                 goto again;
  729 
  730         /* Search through the queue for a command
  731          * destined for a target that's not busy. */
  732         for (q=z->queue, prev=0; q; prev=q, q=q->next) {
  733                 /* Attempt to establish an I_T_L nexus here. */
  734                 if (IS_BUSY (z, q) || ! sea_select (z, q))
  735                         continue;
  736 
  737                 /* Remove the command from the issue queue. */
  738                 if (prev)
  739                         prev->next = q->next;
  740                 else
  741                         z->queue = q->next;
  742                 q->next = 0;
  743 
  744                 /* We are connected. Do the task. */
  745                 sea_information_transfer (z, q);
  746                 goto again;
  747         }
  748 }
  749 
  750 void sea_timeout (void *arg)
  751 {
  752         scb_t *scb = (scb_t*) arg;
  753         adapter_t *z = (adapter_t *)scb->xfer->sc_link->adapter_softc;
  754         int x = splbio ();
  755 
  756         if (! (scb->xfer->flags & SCSI_NOMASK))
  757                 printf ("sea%d/%d/%d (%s%d) timed out\n",
  758                         scb->xfer->sc_link->adapter_unit,
  759                         scb->xfer->sc_link->target,
  760                         scb->xfer->sc_link->lun,
  761                         scb->xfer->sc_link->device->name,
  762                         scb->xfer->sc_link->dev_unit);
  763 
  764         /* If it has been through before, then a previous abort has failed,
  765          * don't try abort again. */
  766         if (! (scb->flags & SCB_ABORTED)) {
  767                 sea_abort (z, scb);
  768                 /* 2 seconds for the abort */
  769                 timeout (sea_timeout, (caddr_t)scb, 2*hz);
  770                 scb->flags |= (SCB_ABORTED | SCB_TIMECHK);
  771         } else {
  772                 /* abort timed out */
  773                 scb->flags |= SCB_ABORTED;
  774                 scb->xfer->retries = 0;
  775                 sea_done (z, scb);
  776         }
  777         splx (x);
  778 }
  779 
  780 /*
  781  * Wait until REQ goes down.  This is needed for some devices (CDROMs)
  782  * after every MSGOUT, MSGIN, CMDOUT, STATIN request.
  783  * Return true if REQ deassert found.
  784  */
  785 static inline int sea_wait_for_req_deassert (adapter_t *z, int cnt, char *msg)
  786 {
  787         asm ("
  788         1:      testb $0x10, %2
  789                 jz 2f
  790                 loop 1b
  791         2:"
  792         : "=c" (cnt)                            /* output */
  793         : "" (cnt), "m" (*z->STATUS));         /* input */
  794         if (! cnt) {
  795                 PRINT (("sea%d (%s) timeout waiting for !REQ\n",
  796                         z->sc_link.adapter_unit, msg));
  797                 return (0);
  798         }
  799         /* PRINT (("sea_wait_for_req_deassert %s count=%d\n", msg, cnt)); */
  800         return (1);
  801 }
  802 
  803 /*
  804  * Establish I_T_L or I_T_L_Q nexus for new or existing command
  805  * including ARBITRATION, SELECTION, and initial message out
  806  * for IDENTIFY and queue messages.
  807  * Return 1 if selection succeded.
  808  */
  809 int sea_select (volatile adapter_t *z, scb_t *scb)
  810 {
  811         /* Start arbitration. */
  812         *z->CONTROL = z->parity | CMD_INTR;
  813         *z->DATA = z->scsi_id;
  814         *z->CONTROL = CMD_START_ARB | z->parity;
  815 
  816         /* Wait for arbitration to complete. */
  817         WAITFOR (*z->STATUS & STAT_ARB_CMPL, "arbitration");
  818         if (! (*z->STATUS & STAT_ARB_CMPL)) {
  819                 if (*z->STATUS & STAT_SEL) {
  820                         printf ("sea: arbitration lost\n");
  821                         scb->flags |= SCB_ERROR;
  822                 } else {
  823                         printf ("sea: arbitration timeout\n");
  824                         scb->flags |= SCB_TIMEOUT;
  825                 }
  826                 *z->CONTROL = CMD_INTR | z->parity;
  827                 return (0);
  828         }
  829         DELAY (1);
  830 
  831         *z->DATA = (1 << scb->xfer->sc_link->target) | z->scsi_id;
  832         *z->CONTROL = sea_select_cmd | CMD_SEL | z->parity;
  833         DELAY (2);
  834 
  835         /* Wait for a bsy from target.
  836          * If the target is not present on the bus, we get
  837          * the timeout.  Don't PRINT any message -- it's not an error. */
  838         WAITFOR (*z->STATUS & STAT_BSY, 0);
  839         if (! (*z->STATUS & STAT_BSY)) {
  840                 /* The target does not respond.  Not an error, though. */
  841                 PRINT (("sea%d/%d/%d target does not respond\n",
  842                         z->sc_link.adapter_unit, scb->xfer->sc_link->target,
  843                         scb->xfer->sc_link->lun));
  844                 *z->CONTROL = CMD_INTR | z->parity;
  845                 scb->flags |= SCB_TIMEOUT;
  846                 return (0);
  847         }
  848 
  849         /* Try to make the target to take a message from us.
  850          * Should start a MSGOUT phase. */
  851         *z->CONTROL = sea_select_cmd | z->parity;
  852         DELAY (15);
  853         WAITFOR (*z->STATUS & STAT_REQ, 0);
  854 
  855         if (z->type == CTLR_FUTURE_DOMAIN)
  856                 *z->CONTROL = CMD_INTR | z->parity | CMD_DRVR_ENABLE;
  857 
  858         WAITFOR (*z->STATUS & STAT_REQ, 0);
  859         if (! (*z->STATUS & STAT_REQ)) {
  860                 PRINT (("sea%d/%d/%d timeout waiting for REQ\n",
  861                         z->sc_link.adapter_unit, scb->xfer->sc_link->target,
  862                         scb->xfer->sc_link->lun));
  863                 scb->flags |= SCB_ERROR;
  864                 *z->CONTROL = CMD_INTR | z->parity;
  865                 return (0);
  866         }
  867 
  868         /* Check for phase mismatch. FD 885 always seems to get this wrong! */
  869         if ((*z->STATUS & PHASE_MASK) != PHASE_MSGOUT && z->type != CTLR_FUTURE_DOMAIN) {
  870                 PRINT (("sea%d/%d/%d waiting for MSGOUT: invalid phase %s\n",
  871                         z->sc_link.adapter_unit, scb->xfer->sc_link->target,
  872                         scb->xfer->sc_link->lun,
  873                         PHASE_NAME (*z->STATUS & PHASE_MASK)));
  874                 scb->flags |= SCB_ERROR;
  875                 *z->CONTROL = CMD_INTR | z->parity;
  876                 return (0);
  877         }
  878 
  879         /* Allow disconnects. (except for FD controllers) */
  880         if (z->type == CTLR_SEAGATE) {
  881                 *z->CONTROL = CMD_DRVR_ENABLE | z->parity;
  882                 *z->DATA = MSG_IDENTIFY (scb->xfer->sc_link->lun);
  883                 WAITREQ (&z->target[scb->xfer->sc_link->target], msgout, 1000);
  884         }
  885         *z->CONTROL = CMD_INTR | CMD_DRVR_ENABLE | z->parity;
  886 
  887         SET_BUSY (z, scb);
  888         return (1);
  889 }
  890 
  891 int sea_reselect (adapter_t *z)
  892 {
  893         scb_t *q = 0, *prev = 0;
  894         u_char msg, target_mask, lun;
  895 again:
  896         /* Wait for a device to win the reselection phase. */
  897         /* Signals this by asserting the I/O signal. */
  898         if ((*z->STATUS & (STAT_SEL | STAT_IO | STAT_BSY)) !=
  899             (STAT_SEL | STAT_IO))
  900                 return (0);
  901 
  902         /* The data bus contains original initiator id ORed with target id. */
  903         /* See that we really are the initiator. */
  904         target_mask = *z->DATA;
  905         if (! (target_mask & z->scsi_id)) {
  906                 PRINT (("sea%d reselect not for me: mask=0x%x, status=%b\n",
  907                         z->sc_link.adapter_unit, target_mask,
  908                         *z->STATUS, STAT_BITS));
  909                 goto again;
  910         }
  911 
  912         /* Find target who won. */
  913         /* Host responds by asserting the BSY signal. */
  914         /* Target should respond by deasserting the SEL signal. */
  915         target_mask &= ~z->scsi_id;
  916         *z->CONTROL = CMD_DRVR_ENABLE | CMD_BSY | z->parity | CMD_INTR;
  917         WAITFOR (! (*z->STATUS & STAT_SEL), "reselection acknowledge");
  918 
  919         /* Remove the busy status. */
  920         /* Target should set the MSGIN phase. */
  921         *z->CONTROL = CMD_INTR | CMD_DRVR_ENABLE | z->parity;
  922         WAITFOR (*z->STATUS & STAT_REQ, "identify message");
  923 
  924         /* Hope we get an IDENTIFY message. */
  925         msg = sea_msg_input (z);
  926         if (MSG_ISIDENT (msg)) {
  927                 /* Find the command corresponding to the I_T_L or I_T_L_Q
  928                  * nexus we just restablished, and remove it from
  929                  * the disconnected queue. */
  930                 lun = (msg & 7);
  931                 for (q=z->disconnected_queue; q; prev=q, q=q->next) {
  932                         if (target_mask != (1 << q->xfer->sc_link->target))
  933                                 continue;
  934                         if (lun != q->xfer->sc_link->lun)
  935                                 continue;
  936                         if (prev)
  937                                 prev->next = q->next;
  938                         else
  939                                 z->disconnected_queue = q->next;
  940                         q->next = 0;
  941                         PRINT (("sea%d/%d/%d reselect done\n",
  942                                 z->sc_link.adapter_unit,
  943                                 ffs (target_mask) - 1, lun));
  944                         sea_information_transfer (z, q);
  945                         WAITFOR (! (*z->STATUS & STAT_BSY), "reselect !busy");
  946                         return (1);
  947                 }
  948         } else
  949                 printf ("sea%d reselect: expecting IDENTIFY, got 0x%x\n",
  950                         z->sc_link.adapter_unit, msg);
  951 
  952         /* Since we have an established nexus that we can't
  953          * do anything with, we must abort it. */
  954         sea_send_abort (z);
  955         PRINT (("sea%d reselect aborted\n", z->sc_link.adapter_unit));
  956         WAITFOR (! (*z->STATUS & STAT_BSY), "bus free after reselect abort");
  957         goto again;
  958 }
  959 
  960 /*
  961  * Send an abort to the target.
  962  * Return 1 success, 0 on failure.
  963  * Called on splbio level.
  964  */
  965 int sea_abort (adapter_t *z, scb_t *scb)
  966 {
  967         scb_t *q, **prev;
  968 
  969         /* If the command hasn't been issued yet, we simply remove it
  970          * from the issue queue. */
  971         prev = &z->queue;
  972         for (q=z->queue; q; q=q->next) {
  973                 if (scb == q) {
  974                         (*prev) = q->next;
  975                         q->next = 0;
  976                         return (1);
  977                 }
  978                 prev = &q->next;
  979         }
  980 
  981         /* If the command is currently disconnected from the bus,
  982          * we reconnect the I_T_L or I_T_L_Q nexus associated with it,
  983          * go into message out, and send an abort message. */
  984         for (q=z->disconnected_queue; q; q=q->next) {
  985                 if (scb != q)
  986                         continue;
  987 
  988                 if (! sea_select (z, scb))
  989                         return (0);
  990                 sea_send_abort (z);
  991 
  992                 prev = &z->disconnected_queue;
  993                 for (q=z->disconnected_queue; q; q=q->next) {
  994                         if (scb == q) {
  995                                 *prev = q->next;
  996                                 q->next = 0;
  997                                 /* Set some type of error result
  998                                  * for the operation. */
  999                                 return (1);
 1000                         }
 1001                         prev = &q->next;
 1002                 }
 1003         }
 1004 
 1005         /* Command not found in any queue. */
 1006         return (0);
 1007 }
 1008 
 1009 /*
 1010  * The task accomplished, mark the i/o control block as done.
 1011  * Always called with interrupts disabled.
 1012  */
 1013 void sea_done (adapter_t *z, scb_t *scb)
 1014 {
 1015         struct scsi_xfer *xs = scb->xfer;
 1016 
 1017         if (scb->flags & SCB_TIMECHK)
 1018                 untimeout (sea_timeout, (caddr_t) scb);
 1019 
 1020         /* How much of the buffer was not touched. */
 1021         xs->resid = scb->datalen;
 1022 
 1023         if (scb->flags != SCB_ACTIVE && ! (xs->flags & SCSI_ERR_OK))
 1024                 if (scb->flags & (SCB_TIMEOUT | SCB_ABORTED))
 1025                         xs->error = XS_TIMEOUT;
 1026                 else if (scb->flags & SCB_ERROR)
 1027                         xs->error = XS_DRIVER_STUFFUP;
 1028                 else if (scb->flags & SCB_TBUSY)
 1029                         xs->error = XS_BUSY;
 1030                 else if (scb->flags & SCB_SENSE)
 1031                         xs->error = XS_SENSE;
 1032 
 1033         xs->flags |= ITSDONE;
 1034 
 1035         /* Free the control block. */
 1036         scb->next = z->free_scb;
 1037         z->free_scb = scb;
 1038         scb->flags = SCB_FREE;
 1039 
 1040         /* If there were none, wake anybody waiting for one to come free,
 1041          * starting with queued entries. */
 1042         if (! scb->next)
 1043                 wakeup ((caddr_t) &z->free_scb);
 1044 
 1045         scsi_done (xs);
 1046 }
 1047 
 1048 /*
 1049  * Wait for completion of command in polled mode.
 1050  * Always called with interrupts masked out.
 1051  */
 1052 int sea_poll (adapter_t *z, scb_t *scb)
 1053 {
 1054         int count;
 1055 
 1056         for (count=0; count<30; ++count) {
 1057                 DELAY (1000);                   /* delay for a while */
 1058                 sea_start (z);                  /* retry operation */
 1059                 if (scb->xfer->flags & ITSDONE)
 1060                         return (1);             /* all is done */
 1061                 if (scb->flags & SCB_TIMEOUT)
 1062                         return (0);             /* no target present */
 1063         }
 1064         return (0);
 1065 }
 1066 
 1067 /*
 1068  * Send data to the target.
 1069  */
 1070 void sea_data_output (adapter_t *z, u_char **pdata, u_long *plen)
 1071 {
 1072         volatile u_char *data = *pdata;
 1073         volatile u_long len = *plen;
 1074 
 1075 #ifdef SEA_BLINDTRANSFER
 1076         if (len && !(len % BLOCK_SIZE)) {
 1077                 while (len) {
 1078                         WAITFOR10 (*z->STATUS & STAT_REQ, "blind block read");
 1079                       asm("
 1080                         shr $2, %%ecx;
 1081                         cld;
 1082                         rep;
 1083                         movsl; " : :
 1084                         "D" (z->DATA), "S" (data), "c" (BLOCK_SIZE) :
 1085                         "cx", "si", "di" );
 1086                         data += BLOCK_SIZE;
 1087                         len -= BLOCK_SIZE;
 1088                 }
 1089         } else {
 1090 #endif
 1091                 asm ("cld
 1092                 1:      movb (%%ebx), %%al
 1093                         xorb $1, %%al
 1094                         testb $0xf, %%al
 1095                         jnz 2f
 1096                         testb $0x10, %%al
 1097                         jz 1b
 1098                         lodsb
 1099                         movb %%al, (%%edi)
 1100                         loop 1b
 1101                 2:"
 1102                 : "=S" (data), "=c" (len)               /* output */
 1103                 : "D" (z->DATA), "b" (z->STATUS),       /* input */
 1104                         "" (data), "1" (len)
 1105                 : "eax", "ebx", "edi");                 /* clobbered */
 1106 #ifdef SEA_BLINDTRANSFER
 1107         }
 1108 #endif
 1109         PRINT (("sea (DATAOUT) send %ld bytes\n", *plen - len));
 1110         *plen = len;
 1111         *pdata = data;
 1112 }
 1113 
 1114 /*
 1115  * Receive data from the target.
 1116  */
 1117 void sea_data_input (adapter_t *z, u_char **pdata, u_long *plen)
 1118 {
 1119         volatile u_char *data = *pdata;
 1120         volatile u_long len = *plen;
 1121 
 1122 #ifdef SEA_BLINDTRANSFER
 1123         if (len && !(len % BLOCK_SIZE)) {
 1124                 while (len) {
 1125                         WAITFOR10 (*z->STATUS & STAT_REQ, "blind block read");
 1126                       asm("
 1127                         shr $2, %%ecx;
 1128                         cld;
 1129                         rep;
 1130                         movsl; " : :
 1131                         "S" (z->DATA), "D" (data), "c" (BLOCK_SIZE) :
 1132                         "cx", "si", "di" );
 1133                         data += BLOCK_SIZE;
 1134                         len -= BLOCK_SIZE;
 1135                 }
 1136         } else {
 1137 #endif
 1138                 if (len >= 512) {
 1139                         asm ("  cld
 1140                         1:      movb (%%esi), %%al
 1141                                 xorb $5, %%al
 1142                                 testb $0xf, %%al
 1143                                 jnz 2f
 1144                                 testb $0x10, %%al
 1145                                 jz 1b
 1146                                 movb (%%ebx), %%al
 1147                                 stosb
 1148                                 loop 1b
 1149                         2:"
 1150                         : "=D" (data), "=c" (len)               /* output */
 1151                         : "b" (z->DATA), "S" (z->STATUS),
 1152                                 "" (data), "1" (len)           /* input */
 1153                         : "eax", "ebx", "esi");                 /* clobbered */
 1154                 } else {
 1155                         asm ("  cld
 1156                         1:      movb (%%esi), %%al
 1157                                 xorb $5, %%al
 1158                                 testb $0xf, %%al
 1159                                 jnz 2f
 1160                                 testb $0x10, %%al
 1161                                 jz 1b
 1162                                 movb (%%ebx), %%al
 1163                                 stosb
 1164                                 movb $1000, %%al
 1165                         3:      testb $0x10, (%%esi)
 1166                                 jz 4f
 1167                                 dec %%al
 1168                                 jnz 3b
 1169                         4:      loop 1b
 1170                         2:"
 1171                         : "=D" (data), "=c" (len)               /* output */
 1172                         : "b" (z->DATA), "S" (z->STATUS),
 1173                                 "" (data), "1" (len)           /* input */
 1174                         : "eax", "ebx", "esi");                 /* clobbered */
 1175                 }
 1176 #ifdef SEA_BLINDTRANSFER
 1177         }
 1178 #endif
 1179         PRINT (("sea (DATAIN) got %ld bytes\n", *plen - len));
 1180         *plen = len;
 1181         *pdata = data;
 1182 }
 1183 
 1184 /*
 1185  * Send the command to the target.
 1186  */
 1187 void sea_cmd_output (target_t *t, u_char *cmd, int cmdlen)
 1188 {
 1189         adapter_t *z = t->adapter;
 1190 
 1191         PRINT (("sea%d send command (%d bytes) ", z->sc_link.adapter_unit,
 1192                 cmdlen));
 1193 
 1194         PRINT (("%x", *cmd));
 1195         *z->DATA = *cmd++;
 1196         if (z->type == CTLR_SEAGATE)
 1197                 WAITREQ (t, cmdout1, 10000);
 1198         --cmdlen;
 1199 
 1200         while (cmdlen) {
 1201                 /* Check for target disconnect. */
 1202                 u_char sts = *z->STATUS;
 1203                 if (! (sts & STAT_BSY))
 1204                         break;
 1205 
 1206                 /* Check for phase mismatch. FD 885 seems to get this wrong! */
 1207                 if ((sts & PHASE_MASK) != PHASE_CMDOUT && z->type != CTLR_FUTURE_DOMAIN) {
 1208                         printf ("sea: sea_cmd_output: invalid phase %s\n",
 1209                                 PHASE_NAME (sts & PHASE_MASK));
 1210                         return;
 1211                 }
 1212 
 1213                 /* Wait for REQ. */
 1214                 if (! (sts & STAT_REQ))
 1215                         continue;
 1216 
 1217                 PRINT (("-%x", *cmd));
 1218                 *z->DATA = *cmd++;
 1219                 if (z->type == CTLR_SEAGATE)
 1220                         WAITREQ (t, cmdout, 1000);
 1221                 --cmdlen;
 1222         }
 1223         PRINT (("\n"));
 1224 }
 1225 
 1226 /*
 1227  * Send the message to the target.
 1228  */
 1229 void sea_send_abort (adapter_t *z)
 1230 {
 1231         u_char sts;
 1232 
 1233         *z->CONTROL = CMD_INTR | CMD_DRVR_ENABLE | CMD_ATTN | z->parity;
 1234 
 1235         /* Wait for REQ, after which the phase bits will be valid. */
 1236         WAITFOR (*z->STATUS & STAT_REQ, "abort message");
 1237         sts = *z->STATUS;
 1238         if (! (sts & STAT_REQ))
 1239                 goto ret;
 1240 
 1241         /* Check for phase mismatch. */
 1242         if ((sts & PHASE_MASK) != PHASE_MSGOUT) {
 1243                 printf ("sea: sending MSG_ABORT: invalid phase %s\n",
 1244                         PHASE_NAME (sts & PHASE_MASK));
 1245                 goto ret;
 1246         }
 1247 
 1248         *z->DATA = MSG_ABORT;
 1249         sea_wait_for_req_deassert (z, 1000, "MSG_OUTPUT");
 1250         PRINT (("sea%d send abort message\n", z->sc_link.adapter_unit));
 1251 ret:
 1252         *z->CONTROL = CMD_INTR | CMD_DRVR_ENABLE | z->parity;
 1253 }
 1254 
 1255 /*
 1256  * Get the message from the target.
 1257  * Return the length of the received message.
 1258  */
 1259 u_char sea_msg_input (adapter_t *z)
 1260 {
 1261         u_char sts, msg;
 1262 
 1263         /* Wait for REQ, after which the phase bits will be valid. */
 1264         WAITFOR (*z->STATUS & STAT_REQ, "message input");
 1265         sts = *z->STATUS;
 1266         if (! (sts & STAT_REQ))
 1267                 return (MSG_ABORT);
 1268 
 1269         /* Check for phase mismatch.
 1270          * Reached if the target decides that it has finished the transfer. */
 1271         if ((sts & PHASE_MASK) != PHASE_MSGIN) {
 1272                 printf ("sea: sea_msg_input: invalid phase %s\n",
 1273                         PHASE_NAME (sts & PHASE_MASK));
 1274                 return (MSG_ABORT);
 1275         }
 1276 
 1277         /* Do actual transfer from SCSI bus to/from memory. */
 1278         msg = *z->DATA;
 1279         sea_wait_for_req_deassert (z, 1000, "MSG_INPUT");
 1280         PRINT (("sea%d (MSG_INPUT) got 0x%x\n", z->sc_link.adapter_unit, msg));
 1281         return (msg);
 1282 }
 1283 
 1284 /*
 1285  * Send request-sense op to the target.
 1286  * Return 1 success, 0 on failure.
 1287  * Called on splbio level.
 1288  */
 1289 int sea_sense (adapter_t *z, scb_t *scb)
 1290 {
 1291         u_char cmd[6], status, msg, *data;
 1292         u_long len;
 1293 
 1294         /* Wait for target to disconnect. */
 1295         WAITFOR (! (*z->STATUS & STAT_BSY), "sense bus free");
 1296         if (*z->STATUS & STAT_BSY)
 1297                 return (0);
 1298 
 1299         /* Select the target again. */
 1300         if (! sea_select (z, scb))
 1301                 return (0);
 1302 
 1303         /* Wait for CMDOUT phase. */
 1304         WAITFOR (*z->STATUS & STAT_REQ, "sense CMDOUT");
 1305         if (! (*z->STATUS & STAT_REQ) ||
 1306             (*z->STATUS & PHASE_MASK) != PHASE_CMDOUT)
 1307                 return (0);
 1308 
 1309         /* Send command. */
 1310         len = sizeof (scb->xfer->sense);
 1311         cmd[0] = REQUEST_SENSE;
 1312         cmd[1] = scb->xfer->sc_link->lun << 5;
 1313         cmd[2] = 0;
 1314         cmd[3] = 0;
 1315         cmd[4] = len;
 1316         cmd[5] = 0;
 1317         sea_cmd_output (&z->target[scb->xfer->sc_link->target],
 1318                 cmd, sizeof (cmd));
 1319 
 1320         /* Wait for DATAIN phase. */
 1321         WAITFOR (*z->STATUS & STAT_REQ, "sense DATAIN");
 1322         if (! (*z->STATUS & STAT_REQ) ||
 1323             (*z->STATUS & PHASE_MASK) != PHASE_DATAIN)
 1324                 return (0);
 1325 
 1326         data = (u_char*) &scb->xfer->sense;
 1327         sea_data_input (z, &data, &len);
 1328         PRINT (("sea%d sense %x-%x-%x-%x-%x-%x-%x-%x\n",
 1329                 z->sc_link.adapter_unit, scb->xfer->sense.error_code,
 1330                 scb->xfer->sense.ext.extended.segment,
 1331                 scb->xfer->sense.ext.extended.flags,
 1332                 scb->xfer->sense.ext.extended.info[0],
 1333                 scb->xfer->sense.ext.extended.info[1],
 1334                 scb->xfer->sense.ext.extended.info[2],
 1335                 scb->xfer->sense.ext.extended.info[3],
 1336                 scb->xfer->sense.ext.extended.extra_len));
 1337 
 1338         /* Wait for STATIN phase. */
 1339         WAITFOR (*z->STATUS & STAT_REQ, "sense STATIN");
 1340         if (! (*z->STATUS & STAT_REQ) ||
 1341             (*z->STATUS & PHASE_MASK) != PHASE_STATIN)
 1342                 return (0);
 1343 
 1344         status = *z->DATA;
 1345 
 1346         /* Wait for MSGIN phase. */
 1347         WAITFOR (*z->STATUS & STAT_REQ, "sense MSGIN");
 1348         if (! (*z->STATUS & STAT_REQ) ||
 1349             (*z->STATUS & PHASE_MASK) != PHASE_MSGIN)
 1350                 return (0);
 1351 
 1352         msg = *z->DATA;
 1353 
 1354         if (status != 0 || msg != 0)
 1355                 printf ("sea%d: bad sense status=0x%x, msg=0x%x\n",
 1356                         z->sc_link.adapter_unit, status, msg);
 1357         return (1);
 1358 }
 1359 
 1360 /*
 1361  * Do the transfer. We know we are connected. Update the flags,
 1362  * call sea_done when task accomplished. Dialog controlled by the target.
 1363  * Always called with interrupts disabled.
 1364  */
 1365 void sea_information_transfer (adapter_t *z, scb_t *scb)
 1366 {
 1367         u_char *data = scb->data;               /* current data buffer */
 1368         u_long datalen = scb->datalen;          /* current data transfer size */
 1369         target_t *t = &z->target[scb->xfer->sc_link->target];
 1370         register u_char sts;
 1371         u_char msg;
 1372 
 1373         while ((sts = *z->STATUS) & STAT_BSY) {
 1374                 /* We only have a valid SCSI phase when REQ is asserted. */
 1375                 if (! (sts & STAT_REQ))
 1376                         continue;
 1377                 if (sts & STAT_PARITY) {
 1378                         int target = scb->xfer->sc_link->target;
 1379                         if (++z->target[target].perrcnt <= 8)
 1380                                 printf ("sea%d/%d/%d parity error\n",
 1381                                         z->sc_link.adapter_unit, target,
 1382                                         scb->xfer->sc_link->lun);
 1383                         if (z->target[target].perrcnt == 8)
 1384                                 printf ("sea%d/%d/%d too many parity errors, not logging any more\n",
 1385                                         z->sc_link.adapter_unit, target,
 1386                                         scb->xfer->sc_link->lun);
 1387                 }
 1388                 switch (sts & PHASE_MASK) {
 1389                 case PHASE_DATAOUT:
 1390                         if (datalen <= 0) {
 1391                                 printf ("sea%d/%d/%d data length underflow\n",
 1392                                         z->sc_link.adapter_unit,
 1393                                         scb->xfer->sc_link->target,
 1394                                         scb->xfer->sc_link->lun);
 1395                                 /* send zero byte */
 1396                                 *z->DATA = 0;
 1397                                 break;
 1398                         }
 1399                         sea_data_output (z, &data, &datalen);
 1400                         break;
 1401                 case PHASE_DATAIN:
 1402                         if (datalen <= 0) {
 1403                                 /* Get extra data.  Some devices (e.g. CDROMs)
 1404                                  * use fixed-length blocks (e.g. 2k),
 1405                                  * even if we need less. */
 1406                                 PRINT (("@"));
 1407                                 sts = *z->DATA;
 1408                                 break;
 1409                         }
 1410                         sea_data_input (z, &data, &datalen);
 1411                         break;
 1412                 case PHASE_CMDOUT:
 1413                         sea_cmd_output (t, (u_char*) scb->xfer->cmd,
 1414                                 scb->xfer->cmdlen);
 1415                         break;
 1416                 case PHASE_STATIN:
 1417                         scb->xfer->status = *z->DATA;
 1418                         if (z->type == CTLR_SEAGATE)
 1419                                 WAITREQ (t, statin, 2000);
 1420                         PRINT (("sea%d/%d/%d (STATIN) got 0x%x\n",
 1421                                 z->sc_link.adapter_unit,
 1422                                 scb->xfer->sc_link->target,
 1423                                 scb->xfer->sc_link->lun,
 1424                                 (u_char) scb->xfer->status));
 1425                         break;
 1426                 case PHASE_MSGOUT:
 1427                         /* Send no-op message. */
 1428                         *z->DATA = MSG_NOP;
 1429                         sea_wait_for_req_deassert (z, 1000, "MSGOUT");
 1430                         PRINT (("sea%d/%d/%d (MSGOUT) send NOP\n",
 1431                                 z->sc_link.adapter_unit,
 1432                                 scb->xfer->sc_link->target,
 1433                                 scb->xfer->sc_link->lun));
 1434                         break;
 1435                 case PHASE_MSGIN:
 1436                         /* Don't handle multi-byte messages here, because they
 1437                          * should not be present here. */
 1438                         msg = *z->DATA;
 1439                         sea_wait_for_req_deassert (z, 2000, "MSGIN");
 1440                         PRINT (("sea%d/%d/%d (MSGIN) got 0x%x\n",
 1441                                 z->sc_link.adapter_unit,
 1442                                 scb->xfer->sc_link->target,
 1443                                 scb->xfer->sc_link->lun, msg));
 1444                         switch (msg) {
 1445                         case MSG_COMMAND_COMPLETE:
 1446                                 scb->data = data;
 1447                                 scb->datalen = datalen;
 1448                                 /* In the case of check-condition status,
 1449                                  * perform the request-sense op. */
 1450                                 switch (scb->xfer->status & 0x1e) {
 1451                                 case SCSI_CHECK:
 1452                                         if (sea_sense (z, scb))
 1453                                                 scb->flags = SCB_SENSE;
 1454                                         break;
 1455                                 case SCSI_BUSY:
 1456                                         scb->flags = SCB_TBUSY;
 1457                                         break;
 1458                                 }
 1459                                 goto done;
 1460                         case MSG_ABORT:
 1461                                 printf ("sea: command aborted by target\n");
 1462                                 scb->flags = SCB_ABORTED;
 1463                                 goto done;
 1464                         case MSG_MESSAGE_REJECT:
 1465                                 printf ("sea: message rejected\n");
 1466                                 scb->flags = SCB_ABORTED;
 1467                                 goto done;
 1468                         case MSG_DISCONNECT:
 1469                                 scb->next = z->disconnected_queue;
 1470                                 z->disconnected_queue = scb;
 1471                                 if (! z->irq && ! z->timeout_active) {
 1472                                         timeout (sea_tick, z, 1);
 1473                                         z->timeout_active = 1;
 1474                                 }
 1475                                 PRINT (("sea%d/%d/%d disconnected\n",
 1476                                         z->sc_link.adapter_unit,
 1477                                         scb->xfer->sc_link->target,
 1478                                         scb->xfer->sc_link->lun));
 1479                                 goto ret;
 1480                         case MSG_SAVE_POINTERS:
 1481                                 scb->data = data;
 1482                                 scb->datalen = datalen;
 1483                                 break;
 1484                         case MSG_RESTORE_POINTERS:
 1485                                 data = scb->data;
 1486                                 datalen = scb->datalen;
 1487                                 break;
 1488                         default:
 1489                                 printf ("sea%d/%d/%d unknown message: 0x%x\n",
 1490                                         z->sc_link.adapter_unit,
 1491                                         scb->xfer->sc_link->target,
 1492                                         scb->xfer->sc_link->lun, msg);
 1493                                 break;
 1494                         }
 1495                         break;
 1496                 default:
 1497                         printf ("sea: unknown phase: %b\n", sts, STAT_BITS);
 1498                         break;
 1499                 }
 1500         }
 1501         printf ("sea%d/%d/%d unexpected target disconnect\n",
 1502                 z->sc_link.adapter_unit, scb->xfer->sc_link->target,
 1503                 scb->xfer->sc_link->lun);
 1504         scb->flags = SCB_ERROR;
 1505 done:
 1506         CLEAR_BUSY (z, scb);
 1507         sea_done (z, scb);
 1508 ret:
 1509         *z->CONTROL = CMD_INTR | z->parity;
 1510 }
 1511 #endif /* NSEA */

Cache object: 99635fcab765fc42839383815231449f


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.