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/dev/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 /*      $NetBSD: seagate.c,v 1.54 2003/04/03 15:36:31 christos Exp $    */
    2 
    3 /*
    4  * ST01/02, Future Domain TMC-885, TMC-950 SCSI driver
    5  *
    6  * Copyright 1994, Charles M. Hannum (mycroft@ai.mit.edu)
    7  * Copyright 1994, Kent Palmkvist (kentp@isy.liu.se)
    8  * Copyright 1994, Robert Knier (rknier@qgraph.com) 
    9  * Copyright 1992, 1994 Drew Eckhardt (drew@colorado.edu)
   10  * Copyright 1994, Julian Elischer (julian@tfs.com)
   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  */
   45 
   46 /*
   47  * What should really be done:
   48  * 
   49  * Add missing tests for timeouts
   50  * Restructure interrupt enable/disable code (runs to long with int disabled)
   51  * Find bug? giving problem with tape status
   52  * Add code to handle Future Domain 840, 841, 880 and 881
   53  * adjust timeouts (startup is very slow)
   54  * add code to use tagged commands in SCSI2
   55  * Add code to handle slow devices better (sleep if device not disconnecting)
   56  * Fix unnecessary interrupts
   57  */
   58 
   59 /*
   60  * Note to users trying to share a disk between DOS and unix:
   61  * The ST01/02 is a translating host-adapter. It is not giving DOS
   62  * the same number of heads/tracks/sectors as specified by the disk.
   63  * It is therefore important to look at what numbers DOS thinks the
   64  * disk has. Use these to disklabel your disk in an appropriate manner
   65  */
   66  
   67 #include <sys/cdefs.h>
   68 __KERNEL_RCSID(0, "$NetBSD: seagate.c,v 1.54 2003/04/03 15:36:31 christos Exp $");
   69 
   70 #include <sys/param.h>
   71 #include <sys/systm.h>
   72 #include <sys/kernel.h>
   73 #include <sys/errno.h>
   74 #include <sys/ioctl.h>
   75 #include <sys/device.h>
   76 #include <sys/buf.h>
   77 #include <sys/proc.h>
   78 #include <sys/user.h>
   79 #include <sys/queue.h>
   80 #include <sys/malloc.h>
   81 
   82 #include <machine/intr.h>
   83 #include <machine/pio.h>
   84 
   85 #include <dev/scsipi/scsi_all.h>
   86 #include <dev/scsipi/scsipi_all.h>
   87 #include <dev/scsipi/scsi_message.h>
   88 #include <dev/scsipi/scsiconf.h>
   89 
   90 #include <dev/isa/isareg.h>
   91 #include <dev/isa/isavar.h>     /* XXX USES ISA HOLE DIRECTLY */
   92 
   93 #define SEA_SCB_MAX     32      /* allow maximally 8 scsi control blocks */
   94 #define SCB_TABLE_SIZE  8       /* start with 8 scb entries in table */
   95 #define BLOCK_SIZE      512     /* size of READ/WRITE areas on SCSI card */
   96 
   97 /*
   98  * defining SEA_BLINDTRANSFER will make DATA IN and DATA OUT to be done with
   99  * blind transfers, i.e. no check is done for scsi phase changes. This will
  100  * result in data loss if the scsi device does not send its data using
  101  * BLOCK_SIZE bytes at a time.
  102  * If SEA_BLINDTRANSFER defined and SEA_ASSEMBLER also defined will result in
  103  * the use of blind transfers coded in assembler. SEA_ASSEMBLER is no good
  104  * without SEA_BLINDTRANSFER defined.
  105  */
  106 #define SEA_BLINDTRANSFER       /* do blind transfers */
  107 #define SEA_ASSEMBLER           /* Use assembly code for fast transfers */
  108 
  109 /*
  110  * defining SEA_NOMSGS causes messages not to be used (thereby disabling
  111  * disconnects)
  112  */
  113 #undef  SEA_NOMSGS
  114 
  115 /*
  116  * defining SEA_NODATAOUT makes dataout phase being aborted
  117  */
  118 #undef  SEA_NODATAOUT
  119 
  120 /* Debugging definitions. Should not be used unless you want a lot of
  121    printouts even under normal conditions */
  122 
  123 #undef  SEA_DEBUGQUEUE          /* Display info about queue-lengths */
  124 
  125 /******************************* board definitions **************************/
  126 /*
  127  * CONTROL defines
  128  */
  129 #define CMD_RST         0x01            /* scsi reset */
  130 #define CMD_SEL         0x02            /* scsi select */
  131 #define CMD_BSY         0x04            /* scsi busy */
  132 #define CMD_ATTN        0x08            /* scsi attention */
  133 #define CMD_START_ARB   0x10            /* start arbitration bit */
  134 #define CMD_EN_PARITY   0x20            /* enable scsi parity generation */
  135 #define CMD_INTR        0x40            /* enable scsi interrupts */
  136 #define CMD_DRVR_ENABLE 0x80            /* scsi enable */
  137 
  138 /*
  139  * STATUS
  140  */
  141 #define STAT_BSY        0x01            /* scsi busy */
  142 #define STAT_MSG        0x02            /* scsi msg */
  143 #define STAT_IO         0x04            /* scsi I/O */
  144 #define STAT_CD         0x08            /* scsi C/D */
  145 #define STAT_REQ        0x10            /* scsi req */
  146 #define STAT_SEL        0x20            /* scsi select */
  147 #define STAT_PARITY     0x40            /* parity error bit */
  148 #define STAT_ARB_CMPL   0x80            /* arbitration complete bit */
  149 
  150 /*
  151  * REQUESTS
  152  */
  153 #define PH_DATAOUT      (0)
  154 #define PH_DATAIN       (STAT_IO)
  155 #define PH_CMD          (STAT_CD)
  156 #define PH_STAT         (STAT_CD | STAT_IO)
  157 #define PH_MSGOUT       (STAT_MSG | STAT_CD)
  158 #define PH_MSGIN        (STAT_MSG | STAT_CD | STAT_IO)
  159 
  160 #define PH_MASK         (STAT_MSG | STAT_CD | STAT_IO)
  161 
  162 #define PH_INVALID      0xff
  163 
  164 #define SEA_RAMOFFSET   0x00001800
  165 
  166 #define BASE_CMD        (CMD_INTR | CMD_EN_PARITY)
  167 
  168 #define SEAGATE         1       /* Seagate ST0[12] */
  169 #define FDOMAIN         2       /* Future Domain TMC-{885,950} */
  170 #define FDOMAIN840      3       /* Future Domain TMC-{84[01],88[01]} */
  171 
  172 /******************************************************************************/
  173 
  174 /* scsi control block used to keep info about a scsi command */ 
  175 struct sea_scb {
  176         u_char *data;                   /* position in data buffer so far */
  177         int datalen;                    /* bytes remaining to transfer */
  178         TAILQ_ENTRY(sea_scb) chain;
  179         struct scsipi_xfer *xs;         /* the scsipi_xfer for this cmd */
  180         int flags;                      /* status of the instruction */
  181 #define SCB_FREE        0
  182 #define SCB_ACTIVE      1
  183 #define SCB_ABORTED     2
  184 #define SCB_TIMEOUT     4
  185 #define SCB_ERROR       8
  186 };
  187 
  188 /*
  189  * data structure describing current status of the scsi bus. One for each
  190  * controller card.
  191  */
  192 struct sea_softc {
  193         struct device sc_dev;
  194         void *sc_ih;
  195 
  196         int type;                       /* board type */
  197         caddr_t maddr;                  /* Base address for card */
  198         caddr_t maddr_cr_sr;            /* Address of control and status reg */
  199         caddr_t maddr_dr;               /* Address of data register */
  200 
  201         struct scsipi_adapter sc_adapter;
  202         struct scsipi_channel sc_channel;
  203 
  204         TAILQ_HEAD(, sea_scb) free_list, ready_list, nexus_list;
  205         struct sea_scb *nexus;          /* currently connected command */
  206         int numscbs;                    /* number of scsi control blocks */
  207         struct sea_scb scb[SCB_TABLE_SIZE];
  208 
  209         int our_id;                     /* our scsi id */
  210         u_char our_id_mask;
  211         volatile u_char busy[8];        /* index=target, bit=lun, Keep track of
  212                                            busy luns at device target */
  213 };
  214 
  215 /* flag showing if main routine is running. */
  216 static volatile int main_running = 0;
  217 
  218 #define STATUS  (*(volatile u_char *)sea->maddr_cr_sr)
  219 #define CONTROL STATUS
  220 #define DATA    (*(volatile u_char *)sea->maddr_dr)
  221 
  222 /*
  223  * These are "special" values for the tag parameter passed to sea_select
  224  * Not implemented right now.
  225  */
  226 #define TAG_NEXT        -1      /* Use next free tag */
  227 #define TAG_NONE        -2      /*
  228                                  * Establish I_T_L nexus instead of I_T_L_Q
  229                                  * even on SCSI-II devices.
  230                                  */
  231 
  232 typedef struct {
  233         char *signature;
  234         int offset, length;
  235         int type;
  236 } BiosSignature;
  237 
  238 /*
  239  * Signatures for automatic recognition of board type
  240  */
  241 static const BiosSignature signatures[] = {
  242 {"ST01 v1.7  (C) Copyright 1987 Seagate", 15, 37, SEAGATE},
  243 {"SCSI BIOS 2.00  (C) Copyright 1987 Seagate", 15, 40, SEAGATE},
  244 
  245 /*
  246  * The following two lines are NOT mistakes. One detects ROM revision
  247  * 3.0.0, the other 3.2. Since seagate has only one type of SCSI adapter,
  248  * and this is not going to change, the "SEAGATE" and "SCSI" together
  249  * are probably "good enough"
  250  */
  251 {"SEAGATE SCSI BIOS ", 16, 17, SEAGATE},
  252 {"SEAGATE SCSI BIOS ", 17, 17, SEAGATE},
  253 
  254 /*
  255  * However, future domain makes several incompatible SCSI boards, so specific
  256  * signatures must be used.
  257  */
  258 {"FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89", 5, 45, FDOMAIN},
  259 {"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89", 5, 46, FDOMAIN},
  260 {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90",5, 47, FDOMAIN},
  261 {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90",5, 47, FDOMAIN},
  262 {"FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90", 5, 46, FDOMAIN},
  263 {"FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92",   5, 44, FDOMAIN},
  264 {"FUTURE DOMAIN TMC-950",                          5, 21, FDOMAIN},
  265 };
  266 
  267 #define nsignatures     (sizeof(signatures) / sizeof(signatures[0]))
  268 
  269 #ifdef notdef
  270 static const char *bases[] = {
  271         (char *) 0xc8000, (char *) 0xca000, (char *) 0xcc000,
  272         (char *) 0xce000, (char *) 0xdc000, (char *) 0xde000
  273 };
  274 
  275 #define nbases          (sizeof(bases) / sizeof(bases[0]))
  276 #endif
  277 
  278 int seaintr __P((void *));
  279 void sea_scsipi_request __P((struct scsipi_channel *,
  280         scsipi_adapter_req_t, void *));
  281 void sea_timeout __P((void *));
  282 void sea_done __P((struct sea_softc *, struct sea_scb *));
  283 struct sea_scb *sea_get_scb __P((struct sea_softc *, int));
  284 void sea_free_scb __P((struct sea_softc *, struct sea_scb *, int));
  285 static void sea_main __P((void));
  286 static void sea_information_transfer __P((struct sea_softc *));
  287 int sea_poll __P((struct sea_softc *, struct scsipi_xfer *, int));
  288 void sea_init __P((struct sea_softc *));
  289 void sea_send_scb __P((struct sea_softc *sea, struct sea_scb *scb));
  290 void sea_reselect __P((struct sea_softc *sea));
  291 int sea_select __P((struct sea_softc *sea, struct sea_scb *scb));
  292 int sea_transfer_pio __P((struct sea_softc *sea, u_char *phase,
  293     int *count, u_char **data));
  294 int sea_abort __P((struct sea_softc *, struct sea_scb *scb));
  295 
  296 void    sea_grow_scb __P((struct sea_softc *));
  297 
  298 int     seaprobe __P((struct device *, struct cfdata *, void *));
  299 void    seaattach __P((struct device *, struct device *, void *));
  300 
  301 CFATTACH_DECL(sea, sizeof(struct sea_softc),
  302     seaprobe, seaattach, NULL, NULL);
  303 
  304 extern struct cfdriver sea_cd;
  305 
  306 #ifdef SEA_DEBUGQUEUE
  307 void
  308 sea_queue_length(sea)
  309         struct sea_softc *sea;
  310 {
  311         struct sea_scb *scb;
  312         int connected, issued, disconnected;
  313 
  314         connected = sea->nexus ? 1 : 0;
  315         for (scb = sea->ready_list.tqh_first, issued = 0; scb;
  316             scb = scb->chain.tqe_next, issued++);
  317         for (scb = sea->nexus_list.tqh_first, disconnected = 0; scb;
  318             scb = scb->chain.tqe_next, disconnected++);
  319         printf("%s: length: %d/%d/%d\n", sea->sc_dev.dv_xname, connected,
  320             issued, disconnected);
  321 }
  322 #endif
  323 
  324 /*
  325  * Check if the device can be found at the port given and if so, detect the
  326  * type the type of board.  Set it up ready for further work. Takes the isa_dev
  327  * structure from autoconf as an argument.
  328  * Returns 1 if card recognized, 0 if errors.
  329  */
  330 int
  331 seaprobe(parent, match, aux)
  332         struct device *parent;
  333         struct cfdata *match;
  334         void *aux;
  335 {
  336         struct isa_attach_args *ia = aux;
  337         int i, type = 0;
  338         caddr_t maddr;
  339 
  340         if (ia->ia_niomem < 1)
  341                 return (0);
  342         if (ia->ia_nirq < 1)
  343                 return (0);
  344 
  345         if (ISA_DIRECT_CONFIG(ia))
  346                 return (0);
  347 
  348         if (ia->ia_iomem[0].ir_addr == ISACF_IOMEM_DEFAULT)
  349                 return (0);
  350         if (ia->ia_irq[0].ir_irq == ISACF_IRQ_DEFAULT)
  351                 return (0);
  352 
  353         /* XXX XXX XXX */
  354         maddr = ISA_HOLE_VADDR(ia->ia_iomem[0].ir_addr);
  355 
  356         /* check board type */  /* No way to define this through config */
  357         for (i = 0; i < nsignatures; i++)
  358                 if (!memcmp(maddr + signatures[i].offset,
  359                     signatures[i].signature, signatures[i].length)) {
  360                         type = signatures[i].type;
  361                         break;
  362                 }
  363 
  364         /* Find controller and data memory addresses */
  365         switch (type) {
  366         case SEAGATE:
  367         case FDOMAIN840:
  368         case FDOMAIN:
  369                 break;
  370         default:
  371 #ifdef SEA_DEBUG
  372                 printf("seaprobe: board type unknown at address %p\n", maddr);
  373 #endif
  374                 return 0;
  375         }
  376 
  377         ia->ia_niomem = 1;
  378         ia->ia_iomem[0].ir_size = 0x2000;
  379 
  380         ia->ia_nirq = 1;
  381 
  382         ia->ia_nio = 0;
  383         ia->ia_ndrq = 0;
  384 
  385         return 1;
  386 }
  387 
  388 /*
  389  * Attach all sub-devices we can find
  390  */
  391 void
  392 seaattach(parent, self, aux)
  393         struct device *parent, *self;
  394         void *aux;
  395 {
  396         struct isa_attach_args *ia = aux;
  397         struct sea_softc *sea = (void *)self;
  398         struct scsipi_adapter *adapt = &sea->sc_adapter;
  399         struct scsipi_channel *chan = &sea->sc_channel;
  400         int i;
  401 
  402         /* XXX XXX XXX */
  403         sea->maddr = ISA_HOLE_VADDR(ia->ia_iomem[0].ir_addr);
  404         
  405         /* check board type */  /* No way to define this through config */
  406         for (i = 0; i < nsignatures; i++)
  407                 if (!memcmp(sea->maddr + signatures[i].offset,
  408                     signatures[i].signature, signatures[i].length)) {
  409                         sea->type = signatures[i].type;
  410                         break;
  411                 }
  412 
  413         /* Find controller and data memory addresses */
  414         switch (sea->type) {
  415         case SEAGATE:
  416         case FDOMAIN840:
  417                 sea->maddr_cr_sr =
  418                     (void *) (((u_char *)sea->maddr) + 0x1a00);
  419                 sea->maddr_dr =
  420                     (void *) (((u_char *)sea->maddr) + 0x1c00);
  421                 break;
  422         case FDOMAIN:
  423                 sea->maddr_cr_sr =
  424                     (void *) (((u_char *)sea->maddr) + 0x1c00);
  425                 sea->maddr_dr =
  426                     (void *) (((u_char *)sea->maddr) + 0x1e00);
  427                 break;
  428         default:
  429 #ifdef DEBUG
  430                 printf("%s: board type unknown at address %p\n",
  431                     sea->sc_dev.dv_xname, sea->maddr);
  432 #endif
  433                 return;
  434         }
  435 
  436         /* Test controller RAM (works the same way on future domain cards?) */
  437         *((u_char *)sea->maddr + SEA_RAMOFFSET) = 0xa5;
  438         *((u_char *)sea->maddr + SEA_RAMOFFSET + 1) = 0x5a;
  439 
  440         if ((*((u_char *)sea->maddr + SEA_RAMOFFSET) != 0xa5) ||
  441             (*((u_char *)sea->maddr + SEA_RAMOFFSET + 1) != 0x5a)) {
  442                 printf("%s: board RAM failure\n", sea->sc_dev.dv_xname);
  443                 return;
  444         }
  445 
  446         sea_init(sea);
  447 
  448         /*
  449          * Fill in the scsipi_adapter.
  450          */
  451         memset(adapt, 0, sizeof(*adapt));
  452         adapt->adapt_dev = &sea->sc_dev;
  453         adapt->adapt_nchannels = 1;
  454         adapt->adapt_openings = sea->numscbs;
  455         adapt->adapt_max_periph = 1;
  456         adapt->adapt_request = sea_scsipi_request;
  457         adapt->adapt_minphys = minphys;
  458 
  459         /*
  460          * Fill in the scsipi_channel.
  461          */
  462         memset(chan, 0, sizeof(*chan));
  463         chan->chan_adapter = adapt;
  464         chan->chan_bustype = &scsi_bustype;
  465         chan->chan_channel = 0;
  466         chan->chan_ntargets = 8;
  467         chan->chan_nluns = 8;
  468         chan->chan_id = sea->our_id;
  469         chan->chan_flags = SCSIPI_CHAN_CANGROW;
  470   
  471         printf("\n");
  472 
  473         sea->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq,
  474             IST_EDGE, IPL_BIO, seaintr, sea);
  475 
  476         /*
  477          * ask the adapter what subunits are present
  478          */
  479         config_found(self, &sea->sc_channel, scsiprint);
  480 }
  481 
  482 /*
  483  * Catch an interrupt from the adaptor
  484  */
  485 int
  486 seaintr(arg)
  487         void *arg;
  488 {
  489         struct sea_softc *sea = arg;
  490 
  491 #ifdef DEBUG    /* extra overhead, and only needed for intr debugging */
  492         if ((STATUS & STAT_PARITY) == 0 &&
  493             (STATUS & (STAT_SEL | STAT_IO)) != (STAT_SEL | STAT_IO))
  494                 return 0;
  495 #endif
  496 
  497 loop:
  498         /* dispatch to appropriate routine if found and done=0 */
  499         /* should check to see that this card really caused the interrupt */
  500 
  501         if (STATUS & STAT_PARITY) {
  502                 /* Parity error interrupt */
  503                 printf("%s: parity error\n", sea->sc_dev.dv_xname);
  504                 return 1;
  505         }
  506 
  507         if ((STATUS & (STAT_SEL | STAT_IO)) == (STAT_SEL | STAT_IO)) {
  508                 /* Reselect interrupt */
  509                 sea_reselect(sea);
  510                 if (!main_running)
  511                         sea_main();
  512                 goto loop;
  513         }
  514 
  515         return 1;
  516 }
  517 
  518 /*
  519  * Setup data structures, and reset the board and the SCSI bus.
  520  */
  521 void
  522 sea_init(sea)
  523         struct sea_softc *sea;
  524 {
  525         int i;
  526   
  527         /* Reset the scsi bus (I don't know if this is needed */
  528         CONTROL = BASE_CMD | CMD_DRVR_ENABLE | CMD_RST;
  529         delay(25);      /* hold reset for at least 25 microseconds */
  530         CONTROL = BASE_CMD;
  531         delay(10);      /* wait a Bus Clear Delay (800 ns + bus free delay (800 ns) */
  532 
  533         /* Set our id (don't know anything about this) */
  534         switch (sea->type) {
  535         case SEAGATE:
  536                 sea->our_id = 7;
  537                 break;
  538         case FDOMAIN:
  539         case FDOMAIN840:
  540                 sea->our_id = 6;
  541                 break;
  542         }
  543         sea->our_id_mask = 1 << sea->our_id;
  544 
  545         /* init fields used by our routines */
  546         sea->nexus = 0;
  547         TAILQ_INIT(&sea->ready_list);
  548         TAILQ_INIT(&sea->nexus_list);
  549         TAILQ_INIT(&sea->free_list);
  550         for (i = 0; i < 8; i++)
  551                 sea->busy[i] = 0x00;
  552 
  553         /* link up the free list of scbs */
  554         sea->numscbs = SCB_TABLE_SIZE;
  555         for (i = 0; i < SCB_TABLE_SIZE; i++) {
  556                 TAILQ_INSERT_TAIL(&sea->free_list, &sea->scb[i], chain);
  557         }
  558 }
  559 
  560 /*
  561  * start a scsi operation given the command and the data address. Also needs
  562  * the unit, target and lu.
  563  */
  564 void
  565 sea_scsipi_request(chan, req, arg)
  566         struct scsipi_channel *chan;
  567         scsipi_adapter_req_t req;
  568         void *arg;
  569 {
  570         struct scsipi_xfer *xs;
  571         struct scsipi_periph *periph;
  572         struct sea_softc *sea = (void *)chan->chan_adapter->adapt_dev;
  573         struct sea_scb *scb;
  574         int flags;
  575         int s;
  576 
  577         switch (req) {
  578         case ADAPTER_REQ_RUN_XFER:
  579                 xs = arg;
  580                 periph = xs->xs_periph;
  581                 flags = xs->xs_control;
  582 
  583                 SC_DEBUG(periph, SCSIPI_DB2, ("sea_scsipi_requeset\n"));
  584 
  585                 /* XXX Reset not implemented. */
  586                 if (flags & XS_CTL_RESET) {
  587                         printf("%s: resetting\n", sea->sc_dev.dv_xname);
  588                         xs->error = XS_DRIVER_STUFFUP;
  589                         scsipi_done(xs);
  590                         return;
  591                 }
  592 
  593                 /* Get an SCB to use. */
  594                 scb = sea_get_scb(sea, flags);
  595 #ifdef DIAGNOSTIC
  596                 /*
  597                  * This should never happen as we track the resources
  598                  * in the mid-layer.
  599                  */
  600                 if (scb == NULL) {
  601                         scsipi_printaddr(periph);
  602                         printf("unable to allocate scb\n");
  603                         panic("sea_scsipi_request");
  604                 }
  605 #endif
  606 
  607                 scb->flags = SCB_ACTIVE;
  608                 scb->xs = xs;
  609 
  610                 /*
  611                  * Put all the arguments for the xfer in the scb
  612                  */
  613                 scb->datalen = xs->datalen;
  614                 scb->data = xs->data;
  615 
  616 #ifdef SEA_DEBUGQUEUE
  617                 sea_queue_length(sea);
  618 #endif
  619 
  620                 s = splbio();
  621 
  622                 sea_send_scb(sea, scb);
  623 
  624                 if ((flags & XS_CTL_POLL) == 0) {
  625                         callout_reset(&scb->xs->xs_callout,
  626                             mstohz(xs->timeout), sea_timeout, scb);
  627                         splx(s);
  628                         return;
  629                 }
  630 
  631                 splx(s);
  632 
  633                 /*
  634                  * If we can't use interrupts, poll on completion
  635                  */
  636                 if (sea_poll(sea, xs, xs->timeout)) {
  637                         sea_timeout(scb);
  638                         if (sea_poll(sea, xs, 2000))
  639                                 sea_timeout(scb);
  640                 }
  641                 return;
  642 
  643         case ADAPTER_REQ_GROW_RESOURCES:
  644                 sea_grow_scb(sea);
  645                 return;
  646 
  647         case ADAPTER_REQ_SET_XFER_MODE:
  648             {
  649                 struct scsipi_xfer_mode *xm = arg;
  650 
  651                 /*
  652                  * We don't support sync or wide or tagged queueing,
  653                  * so announce that now.
  654                  */
  655                 xm->xm_mode = 0;
  656                 xm->xm_period = 0;
  657                 xm->xm_offset = 0;
  658                 scsipi_async_event(chan, ASYNC_EVENT_XFER_MODE, xm);
  659                 return;
  660             }
  661         }
  662 }
  663 
  664 /*
  665  * Get a free scb. If there are none, see if we can allocate a new one.  If so,
  666  * put it in the hash table too; otherwise return an error or sleep.
  667  */
  668 struct sea_scb *
  669 sea_get_scb(sea, flags)
  670         struct sea_softc *sea;
  671         int flags;
  672 {
  673         int s;
  674         struct sea_scb *scb;
  675 
  676         s = splbio();
  677         if ((scb = TAILQ_FIRST(&sea->free_list)) != NULL)
  678                 TAILQ_REMOVE(&sea->free_list, scb, chain);
  679         splx(s);
  680 
  681         return (scb);
  682 }
  683 
  684 /*
  685  * Try to send this command to the board. Because this board does not use any
  686  * mailboxes, this routine simply adds the command to the queue held by the
  687  * sea_softc structure.
  688  * A check is done to see if the command contains a REQUEST_SENSE command, and
  689  * if so the command is put first in the queue, otherwise the command is added
  690  * to the end of the queue. ?? Not correct ??
  691  */
  692 void
  693 sea_send_scb(sea, scb)
  694         struct sea_softc *sea;
  695         struct sea_scb *scb;
  696 {
  697 
  698         TAILQ_INSERT_TAIL(&sea->ready_list, scb, chain);
  699         /* Try to do some work on the card. */
  700         if (!main_running)
  701                 sea_main();
  702 }
  703 
  704 /*
  705  * Coroutine that runs as long as more work can be done on the seagate host
  706  * adapter in a system.  Both sea_scsi_cmd and sea_intr will try to start it in
  707  * case it is not running.
  708  */
  709 
  710 void
  711 sea_main()
  712 {
  713         struct sea_softc *sea;
  714         struct sea_scb *scb;
  715         int done;
  716         int unit;
  717         int s;
  718 
  719         main_running = 1;
  720 
  721         /*
  722          * This should not be run with interrupts disabled, but use the splx
  723          * code instead.
  724          */
  725 loop:
  726         done = 1;
  727         for (unit = 0; unit < sea_cd.cd_ndevs; unit++) {
  728                 sea = device_lookup(&sea_cd, unit);
  729                 if (!sea)
  730                         continue;
  731                 s = splbio();
  732                 if (!sea->nexus) {
  733                         /*
  734                          * Search through the ready_list for a command
  735                          * destined for a target that's not busy.
  736                          */
  737                         for (scb = sea->ready_list.tqh_first; scb;
  738                             scb = scb->chain.tqe_next) {
  739                                 if (!(sea->busy[scb->xs->xs_periph->periph_target] &
  740                                     (1 << scb->xs->xs_periph->periph_lun))) {
  741                                         TAILQ_REMOVE(&sea->ready_list, scb,
  742                                             chain);
  743             
  744                                         /* Re-enable interrupts. */
  745                                         splx(s);
  746 
  747                                         /*
  748                                          * Attempt to establish an I_T_L nexus.
  749                                          * On success, sea->nexus is set.
  750                                          * On failure, we must add the command
  751                                          * back to the issue queue so we can
  752                                          * keep trying.
  753                                          */
  754 
  755                                         /*
  756                                          * REQUEST_SENSE commands are issued
  757                                          * without tagged queueing, even on
  758                                          * SCSI-II devices because the
  759                                          * contingent alligence condition
  760                                          * exists for the entire unit.
  761                                          */
  762 
  763                                         /*
  764                                          * First check that if any device has
  765                                          * tried a reconnect while we have done
  766                                          * other things with interrupts
  767                                          * disabled.
  768                                          */
  769 
  770                                         if ((STATUS & (STAT_SEL | STAT_IO)) ==
  771                                             (STAT_SEL | STAT_IO)) {
  772                                                 sea_reselect(sea);
  773                                                 break;
  774                                         }
  775                                         if (sea_select(sea, scb)) {
  776                                                 s = splbio();
  777                                                 TAILQ_INSERT_HEAD(&sea->ready_list,
  778                                                     scb, chain);
  779                                                 splx(s);
  780                                         } else
  781                                                 break;
  782                                 } /* if target/lun is not busy */
  783                         } /* for scb */
  784                         if (!sea->nexus) {
  785                                 /* check for reselection phase */
  786                                 if ((STATUS & (STAT_SEL | STAT_IO)) ==
  787                                     (STAT_SEL | STAT_IO)) {
  788                                         sea_reselect(sea);
  789                                 }
  790                         }
  791                 } /* if (!sea->nexus) */
  792       
  793                 splx(s);
  794                 if (sea->nexus) {       /* we are connected. Do the task */
  795                         sea_information_transfer(sea);
  796                         done = 0;
  797                 } else
  798                         break;
  799         } /* for instance */
  800 
  801         if (!done)
  802                 goto loop;
  803 
  804         main_running = 0;
  805 }
  806 
  807 /*
  808  * Allocate an scb and add it to the free list.
  809  * We are called at splbio.
  810  */
  811 void
  812 sea_grow_scb(sea)
  813         struct sea_softc *sea;
  814 {
  815         struct sea_scb *scb;
  816 
  817         if (sea->numscbs == SEA_SCB_MAX) {
  818                 sea->sc_channel.chan_flags &= ~SCSIPI_CHAN_CANGROW;
  819                 return;
  820         }
  821 
  822         scb = malloc(sizeof(struct sea_scb), M_DEVBUF, M_NOWAIT|M_ZERO);
  823         if (scb == NULL)
  824                 return;
  825 
  826         TAILQ_INSERT_TAIL(&sea->free_list, scb, chain);
  827         sea->numscbs++;
  828         sea->sc_adapter.adapt_openings++;
  829 }
  830 void
  831 sea_free_scb(sea, scb, flags)
  832         struct sea_softc *sea;
  833         struct sea_scb *scb;
  834         int flags;
  835 {
  836         int s;
  837 
  838         s = splbio();
  839         scb->flags = SCB_FREE;
  840         TAILQ_INSERT_HEAD(&sea->free_list, scb, chain);
  841         splx(s);
  842 }
  843 
  844 void
  845 sea_timeout(arg)
  846         void *arg;
  847 {
  848         struct sea_scb *scb = arg;
  849         struct scsipi_xfer *xs = scb->xs;
  850         struct scsipi_periph *periph = xs->xs_periph;
  851         struct sea_softc *sea =
  852             (void *)periph->periph_channel->chan_adapter->adapt_dev;
  853         int s;
  854 
  855         scsipi_printaddr(periph);
  856         printf("timed out");
  857 
  858         s = splbio();
  859 
  860         /*
  861          * If it has been through before, then
  862          * a previous abort has failed, don't
  863          * try abort again
  864          */
  865         if (scb->flags & SCB_ABORTED) {
  866                 /* abort timed out */
  867                 printf(" AGAIN\n");
  868                 scb->xs->xs_retries = 0;
  869                 scb->flags |= SCB_ABORTED;
  870                 sea_done(sea, scb);
  871         } else {
  872                 /* abort the operation that has timed out */
  873                 printf("\n");
  874                 scb->flags |= SCB_ABORTED;
  875                 sea_abort(sea, scb);
  876                 /* 2 secs for the abort */
  877                 if ((xs->xs_control & XS_CTL_POLL) == 0)
  878                         callout_reset(&scb->xs->xs_callout, 2 * hz,
  879                             sea_timeout, scb);
  880         }
  881 
  882         splx(s);
  883 }
  884  
  885 void
  886 sea_reselect(sea)
  887         struct sea_softc *sea;
  888 {
  889         u_char target_mask;
  890         int i;
  891         u_char lun, phase;
  892         u_char msg[3];
  893         int len;
  894         u_char *data;
  895         struct sea_scb *scb;
  896         int abort = 0;
  897   
  898         if (!((target_mask = STATUS) & STAT_SEL)) {
  899                 printf("%s: wrong state 0x%x\n", sea->sc_dev.dv_xname,
  900                     target_mask);
  901                 return;
  902         }
  903 
  904         /* wait for a device to win the reselection phase */
  905         /* signals this by asserting the I/O signal */
  906         for (i = 10; i && (STATUS & (STAT_SEL | STAT_IO | STAT_BSY)) !=
  907             (STAT_SEL | STAT_IO | 0); i--);
  908         /* !! Check for timeout here */
  909         /* the data bus contains original initiator id ORed with target id */
  910         target_mask = DATA;
  911         /* see that we really are the initiator */
  912         if (!(target_mask & sea->our_id_mask)) {
  913                 printf("%s: polled reselection was not for me: 0x%x\n",
  914                     sea->sc_dev.dv_xname, target_mask);
  915                 return;
  916         }
  917         /* find target who won */
  918         target_mask &= ~sea->our_id_mask;
  919         /* host responds by asserting the BSY signal */
  920         CONTROL = BASE_CMD | CMD_DRVR_ENABLE | CMD_BSY;
  921         /* target should respond by deasserting the SEL signal */
  922         for (i = 50000; i && (STATUS & STAT_SEL); i++);
  923         /* remove the busy status */
  924         CONTROL = BASE_CMD | CMD_DRVR_ENABLE;
  925         /* we are connected. Now we wait for the MSGIN condition */
  926         for (i = 50000; i && !(STATUS & STAT_REQ); i--);
  927         /* !! Add timeout check here */
  928         /* hope we get an IDENTIFY message */
  929         len = 3;
  930         data = msg;
  931         phase = PH_MSGIN;
  932         sea_transfer_pio(sea, &phase, &len, &data); 
  933 
  934         if (!MSG_ISIDENTIFY(msg[0])) {
  935                 printf("%s: expecting IDENTIFY message, got 0x%x\n",
  936                     sea->sc_dev.dv_xname, msg[0]);
  937                 abort = 1;
  938                 scb = NULL;
  939         } else {
  940                 lun = msg[0] & 0x07;
  941 
  942                 /*
  943                  * Find the command corresponding to the I_T_L or I_T_L_Q nexus
  944                  * we just reestablished, and remove it from the disconnected
  945                  * queue.
  946                  */
  947                 for (scb = sea->nexus_list.tqh_first; scb;
  948                     scb = scb->chain.tqe_next)
  949                         if (target_mask == (1 << scb->xs->xs_periph->periph_target) &&
  950                             lun == scb->xs->xs_periph->periph_lun) {
  951                                 TAILQ_REMOVE(&sea->nexus_list, scb,
  952                                     chain);
  953                                 break;
  954                         }
  955                 if (!scb) {
  956                         printf("%s: target %02x lun %d not disconnected\n",
  957                             sea->sc_dev.dv_xname, target_mask, lun);
  958                         /*
  959                          * Since we have an established nexus that we can't do
  960                          * anything with, we must abort it.
  961                          */
  962                         abort = 1;
  963                 }
  964         }
  965 
  966         if (abort) {
  967                 msg[0] = MSG_ABORT;
  968                 len = 1;
  969                 data = msg;
  970                 phase = PH_MSGOUT;
  971                 CONTROL = BASE_CMD | CMD_ATTN;
  972                 sea_transfer_pio(sea, &phase, &len, &data);
  973         } else
  974                 sea->nexus = scb;
  975 
  976         return;
  977 }
  978 
  979 /*
  980  * Transfer data in given phase using polled I/O.
  981  */
  982 int
  983 sea_transfer_pio(sea, phase, count, data)
  984         struct sea_softc *sea;
  985         u_char *phase;
  986         int *count;
  987         u_char **data;
  988 {
  989         u_char p = *phase, tmp;
  990         int c = *count;
  991         u_char *d = *data;
  992         int timeout;
  993 
  994         do {
  995                 /*
  996                  * Wait for assertion of REQ, after which the phase bits will
  997                  * be valid.
  998                  */
  999                 for (timeout = 0; timeout < 50000; timeout++)
 1000                         if ((tmp = STATUS) & STAT_REQ)
 1001                                 break;
 1002                 if (!(tmp & STAT_REQ)) {
 1003                         printf("%s: timeout waiting for STAT_REQ\n",
 1004                             sea->sc_dev.dv_xname);
 1005                         break;
 1006                 }
 1007 
 1008                 /*
 1009                  * Check for phase mismatch.  Reached if the target decides
 1010                  * that it has finished the transfer.
 1011                  */
 1012                 if (sea->type == FDOMAIN840)
 1013                         tmp = ((tmp & 0x08) >> 2) |
 1014                               ((tmp & 0x02) << 2) |
 1015                                (tmp & 0xf5);
 1016                 if ((tmp & PH_MASK) != p)
 1017                         break;
 1018 
 1019                 /* Do actual transfer from SCSI bus to/from memory. */
 1020                 if (!(p & STAT_IO))
 1021                         DATA = *d;
 1022                 else
 1023                         *d = DATA;
 1024                 ++d;
 1025 
 1026                 /*
 1027                  * The SCSI standard suggests that in MSGOUT phase, the
 1028                  * initiator should drop ATN on the last byte of the message
 1029                  * phase after REQ has been asserted for the handshake but
 1030                  * before the initiator raises ACK.
 1031                  * Don't know how to accomplish this on the ST01/02.
 1032                  */
 1033 
 1034 #if 0
 1035                 /*
 1036                  * XXX
 1037                  * The st01 code doesn't wait for STAT_REQ to be deasserted.
 1038                  * Is this ok?
 1039                  */
 1040                 for (timeout = 0; timeout < 200000L; timeout++)
 1041                         if (!(STATUS & STAT_REQ))
 1042                                 break;
 1043                 if (STATUS & STAT_REQ)
 1044                         printf("%s: timeout on wait for !STAT_REQ",
 1045                             sea->sc_dev.dv_xname);
 1046 #endif
 1047         } while (--c);
 1048 
 1049         *count = c;
 1050         *data = d;
 1051         tmp = STATUS;
 1052         if (tmp & STAT_REQ)
 1053                 *phase = tmp & PH_MASK;
 1054         else
 1055                 *phase = PH_INVALID;
 1056 
 1057         if (c && (*phase != p))
 1058                 return -1;
 1059         return 0;
 1060 }
 1061 
 1062 /*
 1063  * Establish I_T_L or I_T_L_Q nexus for new or existing command including
 1064  * ARBITRATION, SELECTION, and initial message out for IDENTIFY and queue
 1065  * messages.  Return -1 if selection could not execute for some reason, 0 if
 1066  * selection succeded or failed because the target did not respond.
 1067  */
 1068 int
 1069 sea_select(sea, scb)
 1070         struct sea_softc *sea;
 1071         struct sea_scb *scb;
 1072 {
 1073         u_char msg[3], phase;
 1074         u_char *data;
 1075         int len;
 1076         int timeout;
 1077 
 1078         CONTROL = BASE_CMD;
 1079         DATA = sea->our_id_mask;
 1080         CONTROL = (BASE_CMD & ~CMD_INTR) | CMD_START_ARB;
 1081 
 1082         /* wait for arbitration to complete */
 1083         for (timeout = 0; timeout < 3000000L; timeout++)
 1084                 if (STATUS & STAT_ARB_CMPL)
 1085                         break;
 1086         if (!(STATUS & STAT_ARB_CMPL)) {
 1087                 if (STATUS & STAT_SEL) {
 1088                         printf("%s: arbitration lost\n", sea->sc_dev.dv_xname);
 1089                         scb->flags |= SCB_ERROR;
 1090                 } else {
 1091                         printf("%s: arbitration timeout\n",
 1092                             sea->sc_dev.dv_xname);
 1093                         scb->flags |= SCB_TIMEOUT;
 1094                 }
 1095                 CONTROL = BASE_CMD;
 1096                 return -1;
 1097         }
 1098 
 1099         delay(2);
 1100         DATA = (u_char)((1 << scb->xs->xs_periph->periph_target) |
 1101                 sea->our_id_mask);
 1102         CONTROL =
 1103 #ifdef SEA_NOMSGS
 1104             (BASE_CMD & ~CMD_INTR) | CMD_DRVR_ENABLE | CMD_SEL;
 1105 #else
 1106             (BASE_CMD & ~CMD_INTR) | CMD_DRVR_ENABLE | CMD_SEL | CMD_ATTN;
 1107 #endif
 1108         delay(1); 
 1109 
 1110         /* wait for a bsy from target */
 1111         for (timeout = 0; timeout < 2000000L; timeout++)
 1112                 if (STATUS & STAT_BSY)
 1113                         break;
 1114         if (!(STATUS & STAT_BSY)) {
 1115                 /* should return some error to the higher level driver */
 1116                 CONTROL = BASE_CMD;
 1117                 scb->flags |= SCB_TIMEOUT;
 1118                 return 0;
 1119         }
 1120 
 1121         /* Try to make the target to take a message from us */
 1122 #ifdef SEA_NOMSGS
 1123         CONTROL = (BASE_CMD & ~CMD_INTR) | CMD_DRVR_ENABLE;
 1124 #else
 1125         CONTROL = (BASE_CMD & ~CMD_INTR) | CMD_DRVR_ENABLE | CMD_ATTN;
 1126 #endif
 1127         delay(1);
 1128   
 1129         /* should start a msg_out phase */
 1130         for (timeout = 0; timeout < 2000000L; timeout++)
 1131                 if (STATUS & STAT_REQ)
 1132                         break;
 1133         /* Remove ATN. */
 1134         CONTROL = BASE_CMD | CMD_DRVR_ENABLE;
 1135         if (!(STATUS & STAT_REQ)) {
 1136                 /*
 1137                  * This should not be taken as an error, but more like an
 1138                  * unsupported feature!  Should set a flag indicating that the
 1139                  * target don't support messages, and continue without failure.
 1140                  * (THIS IS NOT AN ERROR!)
 1141                  */
 1142         } else {
 1143                 msg[0] = MSG_IDENTIFY(scb->xs->xs_periph->periph_lun, 1);
 1144                 len = 1;
 1145                 data = msg;
 1146                 phase = PH_MSGOUT;
 1147                 /* Should do test on result of sea_transfer_pio(). */
 1148                 sea_transfer_pio(sea, &phase, &len, &data);
 1149         }
 1150         if (!(STATUS & STAT_BSY))
 1151                 printf("%s: after successful arbitrate: no STAT_BSY!\n",
 1152                     sea->sc_dev.dv_xname);
 1153   
 1154         sea->nexus = scb;
 1155         sea->busy[scb->xs->xs_periph->periph_target] |=
 1156             1 << scb->xs->xs_periph->periph_lun;
 1157         /* This assignment should depend on possibility to send a message to target. */
 1158         CONTROL = BASE_CMD | CMD_DRVR_ENABLE;
 1159         /* XXX Reset pointer in command? */
 1160         return 0;
 1161 }
 1162 
 1163 /*
 1164  * Send an abort to the target.  Return 1 success, 0 on failure.
 1165  */
 1166 int
 1167 sea_abort(sea, scb)
 1168         struct sea_softc *sea;
 1169         struct sea_scb *scb;
 1170 {
 1171         struct sea_scb *tmp;
 1172         u_char msg, phase, *msgptr;
 1173         int len;
 1174 
 1175         /*
 1176          * If the command hasn't been issued yet, we simply remove it from the
 1177          * issue queue
 1178          * XXX Could avoid this loop.
 1179          */
 1180         for (tmp = sea->ready_list.tqh_first; tmp; tmp = tmp->chain.tqe_next)
 1181                 if (scb == tmp) {
 1182                         TAILQ_REMOVE(&sea->ready_list, scb, chain);
 1183                         /* XXX Set some type of error result for operation. */
 1184                         return 1;
 1185                 }
 1186 
 1187         /*
 1188          * If any commands are connected, we're going to fail the abort and let
 1189          * the high level SCSI driver retry at a later time or issue a reset.
 1190          */
 1191         if (sea->nexus)
 1192                 return 0;
 1193 
 1194         /*
 1195          * If the command is currently disconnected from the bus, and there are
 1196          * no connected commands, we reconnect the I_T_L or I_T_L_Q nexus
 1197          * associated with it, go into message out, and send an abort message.
 1198          */
 1199         for (tmp = sea->nexus_list.tqh_first; tmp;
 1200             tmp = tmp->chain.tqe_next)
 1201                 if (scb == tmp) {
 1202                         if (sea_select(sea, scb))
 1203                                 return 0;
 1204 
 1205                         msg = MSG_ABORT;
 1206                         msgptr = &msg;
 1207                         len = 1;
 1208                         phase = PH_MSGOUT;
 1209                         CONTROL = BASE_CMD | CMD_ATTN;
 1210                         sea_transfer_pio(sea, &phase, &len, &msgptr);
 1211 
 1212                         for (tmp = sea->nexus_list.tqh_first; tmp;
 1213                             tmp = tmp->chain.tqe_next)
 1214                                 if (scb == tmp) {
 1215                                         TAILQ_REMOVE(&sea->nexus_list,
 1216                                             scb, chain);
 1217                                         /* XXX Set some type of error result
 1218                                            for the operation. */
 1219                                         return 1;
 1220                                 }
 1221                 }
 1222 
 1223         /* Command not found in any queue; race condition? */
 1224         return 1;
 1225 }
 1226 
 1227 void
 1228 sea_done(sea, scb)
 1229         struct sea_softc *sea;
 1230         struct sea_scb *scb;
 1231 {
 1232         struct scsipi_xfer *xs = scb->xs;
 1233 
 1234         callout_stop(&scb->xs->xs_callout);
 1235 
 1236         xs->resid = scb->datalen;
 1237 
 1238         /* XXXX need to get status */
 1239         if (scb->flags == SCB_ACTIVE) {
 1240                 xs->resid = 0;
 1241         } else {
 1242                 if (scb->flags & (SCB_TIMEOUT | SCB_ABORTED))
 1243                         xs->error = XS_TIMEOUT;
 1244                 if (scb->flags & SCB_ERROR)
 1245                         xs->error = XS_DRIVER_STUFFUP;
 1246         }
 1247         sea_free_scb(sea, scb, xs->xs_control);
 1248         scsipi_done(xs);
 1249 }
 1250 
 1251 /*
 1252  * Wait for completion of command in polled mode.
 1253  */
 1254 int
 1255 sea_poll(sea, xs, count)
 1256         struct sea_softc *sea;
 1257         struct scsipi_xfer *xs;
 1258         int count;
 1259 {
 1260         int s;
 1261 
 1262         while (count) {
 1263                 /* try to do something */
 1264                 s = splbio();
 1265                 if (!main_running)
 1266                         sea_main();
 1267                 splx(s);
 1268                 if (xs->xs_status & XS_STS_DONE)
 1269                         return 0;
 1270                 delay(1000);
 1271                 count--;
 1272         }
 1273         return 1;
 1274 }
 1275 
 1276 /*
 1277  * Do the transfer.  We know we are connected.  Update the flags, and call
 1278  * sea_done() when task accomplished.  Dialog controlled by the target.
 1279  */
 1280 void
 1281 sea_information_transfer(sea)
 1282         struct sea_softc *sea;
 1283 {
 1284         int timeout;
 1285         u_char msgout = MSG_NOOP;
 1286         int len;
 1287         int s;
 1288         u_char *data;
 1289         u_char phase, tmp, old_phase = PH_INVALID;
 1290         struct sea_scb *scb = sea->nexus;
 1291         int loop;
 1292 
 1293         for (timeout = 0; timeout < 10000000L; timeout++) {
 1294                 tmp = STATUS;
 1295                 if (tmp & STAT_PARITY)
 1296                         printf("%s: parity error detected\n",
 1297                             sea->sc_dev.dv_xname);
 1298                 if (!(tmp & STAT_BSY)) {
 1299                         for (loop = 0; loop < 20; loop++)
 1300                                 if ((tmp = STATUS) & STAT_BSY)
 1301                                         break;
 1302                         if (!(tmp & STAT_BSY)) {
 1303                                 printf("%s: !STAT_BSY unit in data transfer!\n",
 1304                                     sea->sc_dev.dv_xname);
 1305                                 s = splbio();
 1306                                 sea->nexus = NULL;
 1307                                 scb->flags = SCB_ERROR;
 1308                                 splx(s);
 1309                                 sea_done(sea, scb);
 1310                                 return;
 1311                         }
 1312                 }
 1313 
 1314                 /* we only have a valid SCSI phase when REQ is asserted */
 1315                 if (!(tmp & STAT_REQ))
 1316                         continue;
 1317 
 1318                 if (sea->type == FDOMAIN840)
 1319                         tmp = ((tmp & 0x08) >> 2) |
 1320                               ((tmp & 0x02) << 2) |
 1321                                (tmp & 0xf5);
 1322                 phase = tmp & PH_MASK;
 1323                 if (phase != old_phase)
 1324                         old_phase = phase;
 1325 
 1326                 switch (phase) {
 1327                 case PH_DATAOUT:
 1328 #ifdef SEA_NODATAOUT
 1329                         printf("%s: SEA_NODATAOUT set, attempted DATAOUT aborted\n",
 1330                             sea->sc_dev.dv_xname);
 1331                         msgout = MSG_ABORT;
 1332                         CONTROL = BASE_CMD | CMD_ATTN;
 1333                         break;
 1334 #endif
 1335                 case PH_DATAIN:
 1336                         if (!scb->data)
 1337                                 printf("no data address!\n");
 1338 #ifdef SEA_BLINDTRANSFER
 1339                         if (scb->datalen && !(scb->datalen % BLOCK_SIZE)) {
 1340                                 while (scb->datalen) {
 1341                                         for (loop = 0; loop < 50000; loop++)
 1342                                                 if ((tmp = STATUS) & STAT_REQ)
 1343                                                         break;
 1344                                         if (!(tmp & STAT_REQ)) {
 1345                                                 printf("%s: timeout waiting for STAT_REQ\n",
 1346                                                     sea->sc_dev.dv_xname);
 1347                                                 /* XXX Do something? */
 1348                                         }
 1349                                         if (sea->type == FDOMAIN840)
 1350                                                 tmp = ((tmp & 0x08) >> 2) |
 1351                                                       ((tmp & 0x02) << 2) |
 1352                                                        (tmp & 0xf5);
 1353                                         if ((tmp & PH_MASK) != phase)
 1354                                                 break;
 1355                                         if (!(phase & STAT_IO)) {
 1356 #ifdef SEA_ASSEMBLER
 1357                                                 caddr_t junk;
 1358                                                 __asm("cld\n\t\
 1359                                                     rep\n\t\
 1360                                                     movsl" :
 1361                                                     "=S" (scb->data),
 1362                                                     "=c" (len),
 1363                                                     "=D" (junk) :
 1364                                                     "" (scb->data),
 1365                                                     "1" (BLOCK_SIZE >> 2),
 1366                                                     "2" (sea->maddr_dr));
 1367 #else
 1368                                                 for (len = BLOCK_SIZE;
 1369                                                     len; len--)
 1370                                                         DATA = *(scb->data++);
 1371 #endif
 1372                                         } else {
 1373 #ifdef SEA_ASSEMBLER
 1374                                                 caddr_t junk;
 1375                                                 __asm("cld\n\t\
 1376                                                     rep\n\t\
 1377                                                     movsl" :
 1378                                                     "=D" (scb->data),
 1379                                                     "=c" (len),
 1380                                                     "=S" (junk) :
 1381                                                     "" (scb->data),
 1382                                                     "1" (BLOCK_SIZE >> 2),
 1383                                                     "2" (sea->maddr_dr));
 1384 #else
 1385                                                 for (len = BLOCK_SIZE;
 1386                                                     len; len--)
 1387                                                         *(scb->data++) = DATA;
 1388 #endif
 1389                                         }
 1390                                         scb->datalen -= BLOCK_SIZE;
 1391                                 }
 1392                         }
 1393 #endif 
 1394                         if (scb->datalen)
 1395                                 sea_transfer_pio(sea, &phase, &scb->datalen,
 1396                                     &scb->data);
 1397                         break;
 1398                 case PH_MSGIN:
 1399                         /* Multibyte messages should not be present here. */
 1400                         len = 1;
 1401                         data = &tmp;
 1402                         sea_transfer_pio(sea, &phase, &len, &data);
 1403                         /* scb->MessageIn = tmp; */
 1404 
 1405                         switch (tmp) {
 1406                         case MSG_ABORT:
 1407                                 scb->flags = SCB_ABORTED;
 1408                                 printf("sea: command aborted by target\n");
 1409                                 CONTROL = BASE_CMD;
 1410                                 sea_done(sea, scb);
 1411                                 return;
 1412                         case MSG_CMDCOMPLETE:
 1413                                 s = splbio();
 1414                                 sea->nexus = NULL;
 1415                                 splx(s);
 1416                                 sea->busy[scb->xs->xs_periph->periph_target] &= 
 1417                                     ~(1 << scb->xs->xs_periph->periph_lun);
 1418                                 CONTROL = BASE_CMD;
 1419                                 sea_done(sea, scb);
 1420                                 return;
 1421                         case MSG_MESSAGE_REJECT:
 1422                                 printf("%s: message_reject received\n",
 1423                                     sea->sc_dev.dv_xname);
 1424                                 break;
 1425                         case MSG_DISCONNECT:
 1426                                 s = splbio();
 1427                                 TAILQ_INSERT_TAIL(&sea->nexus_list,
 1428                                     scb, chain);
 1429                                 sea->nexus = NULL;
 1430                                 CONTROL = BASE_CMD;
 1431                                 splx(s);
 1432                                 return;
 1433                         case MSG_SAVEDATAPOINTER:
 1434                         case MSG_RESTOREPOINTERS:
 1435                                 /* save/restore of pointers are ignored */
 1436                                 break;
 1437                         default:
 1438                                 /*
 1439                                  * This should be handled in the pio data
 1440                                  * transfer phase, as the ATN should be raised
 1441                                  * before ACK goes false when rejecting a
 1442                                  * message.
 1443                                  */
 1444                                 printf("%s: unknown message in: %x\n",
 1445                                     sea->sc_dev.dv_xname, tmp);
 1446                                 break;
 1447                         } /* switch (tmp) */
 1448                         break;
 1449                 case PH_MSGOUT:
 1450                         len = 1;
 1451                         data = &msgout;
 1452                         /* sea->last_message = msgout; */
 1453                         sea_transfer_pio(sea, &phase, &len, &data);
 1454                         if (msgout == MSG_ABORT) {
 1455                                 printf("%s: sent message abort to target\n",
 1456                                     sea->sc_dev.dv_xname);
 1457                                 s = splbio();
 1458                                 sea->busy[scb->xs->xs_periph->periph_target] &= 
 1459                                     ~(1 << scb->xs->xs_periph->periph_lun);
 1460                                 sea->nexus = NULL;
 1461                                 scb->flags = SCB_ABORTED;
 1462                                 splx(s); 
 1463                                 /* enable interrupt from scsi */
 1464                                 sea_done(sea, scb);
 1465                                 return;
 1466                         }
 1467                         msgout = MSG_NOOP;
 1468                         break;
 1469                 case PH_CMD:
 1470                         len = scb->xs->cmdlen;
 1471                         data = (char *) scb->xs->cmd;
 1472                         sea_transfer_pio(sea, &phase, &len, &data);
 1473                         break;
 1474                 case PH_STAT:
 1475                         len = 1;
 1476                         data = &tmp;
 1477                         sea_transfer_pio(sea, &phase, &len, &data);
 1478                         scb->xs->status = tmp;
 1479                         break;
 1480                 default:
 1481                         printf("sea: unknown phase\n");
 1482                 } /* switch (phase) */
 1483         } /* for (...) */
 1484 
 1485         /* If we get here we have got a timeout! */
 1486         printf("%s: timeout in data transfer\n", sea->sc_dev.dv_xname);
 1487         scb->flags = SCB_TIMEOUT;
 1488         /* XXX Should I clear scsi-bus state? */
 1489         sea_done(sea, scb);
 1490 }

Cache object: e4571170933611d8514f42bbb4afc0ee


[ 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.