root/dev/eisa/aha1742.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ahb_send_mbox
  2. ahb_poll
  3. ahb_send_immed
  4. ahbmatch
  5. ahbprint
  6. ahbattach
  7. ahbintr
  8. ahb_done
  9. ahb_free_ecb
  10. ahb_init_ecb
  11. ahb_reset_ecb
  12. ahb_get_ecb
  13. ahb_ecb_phys_kv
  14. ahb_find
  15. ahb_init
  16. ahbminphys
  17. ahb_scsi_cmd
  18. ahb_timeout
  19. ahb_print_ecb
  20. ahb_print_active_ecb

    1 /*      $OpenBSD: aha1742.c,v 1.25 2007/05/08 16:03:20 deraadt Exp $    */
    2 /*      $NetBSD: aha1742.c,v 1.61 1996/05/12 23:40:01 mycroft Exp $     */
    3 
    4 /*
    5  * Copyright (c) 1994 Charles Hannum.  All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. All advertising materials mentioning features or use of this software
   16  *    must display the following acknowledgement:
   17  *      This product includes software developed by Charles Hannum.
   18  * 4. The name of the author may not be used to endorse or promote products
   19  *    derived from this software without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 /*
   34  * Originally written by Julian Elischer (julian@tfs.com)
   35  * for TRW Financial Systems for use under the MACH(2.5) operating system.
   36  *
   37  * TRW Financial Systems, in accordance with their agreement with Carnegie
   38  * Mellon University, makes this software available to CMU to distribute
   39  * or use in any manner that they see fit as long as this message is kept with
   40  * the software. For this reason TFS also grants any other persons or
   41  * organisations permission to use or modify this software.
   42  *
   43  * TFS supplies this software to be publicly redistributed
   44  * on the understanding that TFS is not responsible for the correct
   45  * functioning of this software in any circumstances.
   46  *
   47  * commenced: Sun Sep 27 18:14:01 PDT 1992
   48  */
   49 
   50 #include <sys/types.h>
   51 #include <sys/param.h>
   52 #include <sys/systm.h>
   53 #include <sys/kernel.h>
   54 #include <sys/errno.h>
   55 #include <sys/ioctl.h>
   56 #include <sys/device.h>
   57 #include <sys/malloc.h>
   58 #include <sys/buf.h>
   59 #include <sys/proc.h>
   60 #include <sys/user.h>
   61 
   62 #include <machine/bus.h>
   63 #include <machine/intr.h>
   64 
   65 #include <dev/eisa/eisareg.h>
   66 #include <dev/eisa/eisavar.h>
   67 #include <dev/eisa/eisadevs.h>
   68 
   69 #include <scsi/scsi_all.h>
   70 #include <scsi/scsiconf.h>
   71 
   72 #ifndef DDB
   73 #define Debugger() panic("should call debugger here (aha1742.c)")
   74 #endif /* ! DDB */
   75 
   76 typedef u_long physaddr;
   77 typedef u_long physlen;
   78 
   79 #define KVTOPHYS(x)     kvtop((caddr_t)x)
   80 
   81 #define AHB_ECB_MAX     32      /* store up to 32 ECBs at one time */
   82 #define ECB_HASH_SIZE   32      /* hash table size for phystokv */
   83 #define ECB_HASH_SHIFT  9
   84 #define ECB_HASH(x)     ((((long)(x))>>ECB_HASH_SHIFT) & (ECB_HASH_SIZE - 1))
   85 
   86 #define AHB_NSEG        33      /* number of dma segments supported */
   87 
   88 /*
   89  * EISA registers (offset from slot base)
   90  */
   91 #define EISA_VENDOR             0x0c80  /* vendor ID (2 ports) */
   92 #define EISA_MODEL              0x0c82  /* model number (2 ports) */
   93 #define EISA_CONTROL            0x0c84
   94 #define  EISA_RESET             0x04
   95 #define  EISA_ERROR             0x02
   96 #define  EISA_ENABLE            0x01
   97 
   98 /*
   99  * AHA1740 EISA board mode registers (Offset from slot base)
  100  */
  101 #define PORTADDR        0xCC0
  102 #define  PORTADDR_ENHANCED      0x80
  103 #define BIOSADDR        0xCC1
  104 #define INTDEF          0xCC2
  105 #define SCSIDEF         0xCC3
  106 #define BUSDEF          0xCC4
  107 #define RESV0           0xCC5
  108 #define RESV1           0xCC6
  109 #define RESV2           0xCC7
  110 /**** bit definitions for INTDEF ****/
  111 #define INT9    0x00
  112 #define INT10   0x01
  113 #define INT11   0x02
  114 #define INT12   0x03
  115 #define INT14   0x05
  116 #define INT15   0x06
  117 #define INTHIGH 0x08            /* int high=ACTIVE (else edge) */
  118 #define INTEN   0x10
  119 /**** bit definitions for SCSIDEF ****/
  120 #define HSCSIID 0x0F            /* our SCSI ID */
  121 #define RSTPWR  0x10            /* reset scsi bus on power up or reset */
  122 /**** bit definitions for BUSDEF ****/
  123 #define B0uS    0x00            /* give up bus immediately */
  124 #define B4uS    0x01            /* delay 4uSec. */
  125 #define B8uS    0x02
  126 
  127 /*
  128  * AHA1740 ENHANCED mode mailbox control regs (Offset from slot base)
  129  */
  130 #define MBOXOUT0        0xCD0
  131 #define MBOXOUT1        0xCD1
  132 #define MBOXOUT2        0xCD2
  133 #define MBOXOUT3        0xCD3
  134 
  135 #define ATTN            0xCD4
  136 #define G2CNTRL         0xCD5
  137 #define G2INTST         0xCD6
  138 #define G2STAT          0xCD7
  139 
  140 #define MBOXIN0         0xCD8
  141 #define MBOXIN1         0xCD9
  142 #define MBOXIN2         0xCDA
  143 #define MBOXIN3         0xCDB
  144 
  145 #define G2STAT2         0xCDC
  146 
  147 /*
  148  * Bit definitions for the 5 control/status registers
  149  */
  150 #define ATTN_TARGET             0x0F
  151 #define ATTN_OPCODE             0xF0
  152 #define  OP_IMMED               0x10
  153 #define   AHB_TARG_RESET        0x80
  154 #define  OP_START_ECB           0x40
  155 #define  OP_ABORT_ECB           0x50
  156 
  157 #define G2CNTRL_SET_HOST_READY  0x20
  158 #define G2CNTRL_CLEAR_EISA_INT  0x40
  159 #define G2CNTRL_HARD_RESET      0x80
  160 
  161 #define G2INTST_TARGET          0x0F
  162 #define G2INTST_INT_STAT        0xF0
  163 #define  AHB_ECB_OK             0x10
  164 #define  AHB_ECB_RECOVERED      0x50
  165 #define  AHB_HW_ERR             0x70
  166 #define  AHB_IMMED_OK           0xA0
  167 #define  AHB_ECB_ERR            0xC0
  168 #define  AHB_ASN                0xD0    /* for target mode */
  169 #define  AHB_IMMED_ERR          0xE0
  170 
  171 #define G2STAT_BUSY             0x01
  172 #define G2STAT_INT_PEND         0x02
  173 #define G2STAT_MBOX_EMPTY       0x04
  174 
  175 #define G2STAT2_HOST_READY      0x01
  176 
  177 struct ahb_dma_seg {
  178         physaddr seg_addr;
  179         physlen seg_len;
  180 };
  181 
  182 struct ahb_ecb_status {
  183         u_short status;
  184 #define ST_DON  0x0001
  185 #define ST_DU   0x0002
  186 #define ST_QF   0x0008
  187 #define ST_SC   0x0010
  188 #define ST_DO   0x0020
  189 #define ST_CH   0x0040
  190 #define ST_INT  0x0080
  191 #define ST_ASA  0x0100
  192 #define ST_SNS  0x0200
  193 #define ST_INI  0x0800
  194 #define ST_ME   0x1000
  195 #define ST_ECA  0x4000
  196         u_char  host_stat;
  197 #define HS_OK                   0x00
  198 #define HS_CMD_ABORTED_HOST     0x04
  199 #define HS_CMD_ABORTED_ADAPTER  0x05
  200 #define HS_TIMED_OUT            0x11
  201 #define HS_HARDWARE_ERR         0x20
  202 #define HS_SCSI_RESET_ADAPTER   0x22
  203 #define HS_SCSI_RESET_INCOMING  0x23
  204         u_char  target_stat;
  205         u_long  resid_count;
  206         u_long  resid_addr;
  207         u_short addit_status;
  208         u_char  sense_len;
  209         u_char  unused[9];
  210         u_char  cdb[6];
  211 };
  212 
  213 struct ahb_ecb {
  214         u_char  opcode;
  215 #define ECB_SCSI_OP     0x01
  216                 u_char:4;
  217         u_char  options:3;
  218                 u_char:1;
  219         short   opt1;
  220 #define ECB_CNE 0x0001
  221 #define ECB_DI  0x0080
  222 #define ECB_SES 0x0400
  223 #define ECB_S_G 0x1000
  224 #define ECB_DSB 0x4000
  225 #define ECB_ARS 0x8000
  226         short   opt2;
  227 #define ECB_LUN 0x0007
  228 #define ECB_TAG 0x0008
  229 #define ECB_TT  0x0030
  230 #define ECB_ND  0x0040
  231 #define ECB_DAT 0x0100
  232 #define ECB_DIR 0x0200
  233 #define ECB_ST  0x0400
  234 #define ECB_CHK 0x0800
  235 #define ECB_REC 0x4000
  236 #define ECB_NRB 0x8000
  237         u_short unused1;
  238         physaddr data_addr;
  239         physlen  data_length;
  240         physaddr status;
  241         physaddr link_addr;
  242         short   unused2;
  243         short   unused3;
  244         physaddr sense_ptr;
  245         u_char  req_sense_length;
  246         u_char  scsi_cmd_length;
  247         short   cksum;
  248         struct scsi_generic scsi_cmd;
  249         /*-----------------end of hardware supported fields----------------*/
  250         TAILQ_ENTRY(ahb_ecb) chain;
  251         struct ahb_ecb *nexthash;
  252         long hashkey;
  253         struct scsi_xfer *xs;   /* the scsi_xfer for this cmd */
  254         int flags;
  255 #define ECB_FREE        0
  256 #define ECB_ACTIVE      1
  257 #define ECB_ABORTED     2
  258 #define ECB_IMMED       4
  259 #define ECB_IMMED_FAIL  8
  260         struct ahb_dma_seg ahb_dma[AHB_NSEG];
  261         struct ahb_ecb_status ecb_status;
  262         struct scsi_sense_data ecb_sense;
  263 };
  264 
  265 struct ahb_softc {
  266         struct device sc_dev;
  267         bus_space_tag_t sc_iot;
  268         eisa_chipset_tag_t sc_ec;
  269 
  270         bus_space_handle_t sc_ioh;
  271         int sc_irq;
  272         void *sc_ih;
  273 
  274         struct ahb_ecb *immed_ecb;      /* an outstanding immediete command */
  275         struct ahb_ecb *ecbhash[ECB_HASH_SIZE];
  276         TAILQ_HEAD(, ahb_ecb) free_ecb;
  277         int numecbs;
  278         int ahb_scsi_dev;               /* our scsi id */
  279         struct scsi_link sc_link;
  280 };
  281 
  282 void ahb_send_mbox(struct ahb_softc *, int, struct ahb_ecb *);
  283 int ahb_poll(struct ahb_softc *, struct scsi_xfer *, int);
  284 void ahb_send_immed(struct ahb_softc *, int, u_long);
  285 int ahbintr(void *);
  286 void ahb_done(struct ahb_softc *, struct ahb_ecb *);
  287 void ahb_free_ecb(struct ahb_softc *, struct ahb_ecb *, int);
  288 struct ahb_ecb *ahb_get_ecb(struct ahb_softc *, int);
  289 struct ahb_ecb *ahb_ecb_phys_kv(struct ahb_softc *, physaddr);
  290 int ahb_find(bus_space_tag_t, bus_space_handle_t, struct ahb_softc *);
  291 void ahb_init(struct ahb_softc *);
  292 void ahbminphys(struct buf *);
  293 int ahb_scsi_cmd(struct scsi_xfer *);
  294 void ahb_timeout(void *);
  295 void ahb_print_ecb(struct ahb_ecb *);
  296 void ahb_print_active_ecb(struct ahb_softc *);
  297 int ahbprint(void *, const char *);
  298 
  299 #define MAX_SLOTS       15
  300 
  301 #ifdef  AHBDEBUG
  302 int     ahb_debug = 0;
  303 #endif /* AHBDEBUG */
  304 #define AHB_SHOWECBS 0x01
  305 #define AHB_SHOWINTS 0x02
  306 #define AHB_SHOWCMDS 0x04
  307 #define AHB_SHOWMISC 0x08
  308 
  309 struct scsi_adapter ahb_switch = {
  310         ahb_scsi_cmd,
  311         ahbminphys,
  312         0,
  313         0,
  314 };
  315 
  316 /* the below structure is so we have a default dev struct for our link struct */
  317 struct scsi_device ahb_dev = {
  318         NULL,                   /* Use default error handler */
  319         NULL,                   /* have a queue, served by this */
  320         NULL,                   /* have no async handler */
  321         NULL,                   /* Use default 'done' routine */
  322 };
  323 
  324 int     ahbmatch(struct device *, void *, void *);
  325 void    ahbattach(struct device *, struct device *, void *);
  326 
  327 struct cfattach ahb_ca = {
  328         sizeof(struct ahb_softc), ahbmatch, ahbattach
  329 };
  330 
  331 struct cfdriver ahb_cd = {
  332         NULL, "ahb", DV_DULL
  333 };
  334 
  335 /*
  336  * Function to send a command out through a mailbox
  337  */
  338 void
  339 ahb_send_mbox(sc, opcode, ecb)
  340         struct ahb_softc *sc;
  341         int opcode;
  342         struct ahb_ecb *ecb;
  343 {
  344         bus_space_tag_t iot = sc->sc_iot;
  345         bus_space_handle_t ioh = sc->sc_ioh;
  346         int wait = 300; /* 1ms should be enough */
  347 
  348         while (--wait) {
  349                 if ((bus_space_read_1(iot, ioh, G2STAT) &
  350                     (G2STAT_BUSY | G2STAT_MBOX_EMPTY)) == (G2STAT_MBOX_EMPTY))
  351                         break;
  352                 delay(10);
  353         }
  354         if (!wait) {
  355                 printf("%s: board not responding\n", sc->sc_dev.dv_xname);
  356                 Debugger();
  357         }
  358 
  359         /* don't know this will work */
  360         bus_space_write_4(iot, ioh, MBOXOUT0, KVTOPHYS(ecb));
  361         bus_space_write_1(iot, ioh, ATTN, opcode | ecb->xs->sc_link->target);
  362 }
  363 
  364 /*
  365  * Function to poll for command completion when in poll mode
  366  */
  367 int
  368 ahb_poll(sc, xs, count)
  369         struct ahb_softc *sc;
  370         struct scsi_xfer *xs;
  371         int count;
  372 {                               /* in msec  */
  373         bus_space_tag_t iot = sc->sc_iot;
  374         bus_space_handle_t ioh = sc->sc_ioh;
  375 
  376         while (count) {
  377                 /*
  378                  * If we had interrupts enabled, would we
  379                  * have got an interrupt?
  380                  */
  381                 if (bus_space_read_1(iot, ioh, G2STAT) & G2STAT_INT_PEND)
  382                         ahbintr(sc);
  383                 if (xs->flags & ITSDONE)
  384                         return 0;
  385                 delay(1000);
  386                 count--;
  387         }
  388         return 1;
  389 }
  390 
  391 /*
  392  * Function to  send an immediate type command to the adapter
  393  */
  394 void
  395 ahb_send_immed(sc, target, cmd)
  396         struct ahb_softc *sc;
  397         int target;
  398         u_long cmd;
  399 {
  400         bus_space_tag_t iot = sc->sc_iot;
  401         bus_space_handle_t ioh = sc->sc_ioh;
  402         int wait = 100; /* 1 ms enough? */
  403 
  404         while (--wait) {
  405                 if ((bus_space_read_1(iot, ioh, G2STAT) &
  406                     (G2STAT_BUSY | G2STAT_MBOX_EMPTY)) == (G2STAT_MBOX_EMPTY))
  407                         break;
  408                 delay(10);
  409         }
  410         if (!wait) {
  411                 printf("%s: board not responding\n", sc->sc_dev.dv_xname);
  412                 Debugger();
  413         }
  414 
  415         /* don't know this will work */
  416         bus_space_write_4(iot, ioh, MBOXOUT0, cmd);
  417         bus_space_write_1(iot, ioh, G2CNTRL, G2CNTRL_SET_HOST_READY);
  418         bus_space_write_1(iot, ioh, ATTN, OP_IMMED | target);
  419 }
  420 
  421 /*
  422  * Check the slots looking for a board we recognise
  423  * If we find one, note its address (slot) and call
  424  * the actual probe routine to check it out.
  425  */
  426 int
  427 ahbmatch(parent, match, aux)
  428         struct device *parent;
  429         void *match, *aux;
  430 {
  431         struct eisa_attach_args *ea = aux;
  432         bus_space_tag_t iot = ea->ea_iot;
  433         bus_space_handle_t ioh;
  434         int rv;
  435 
  436         /* must match one of our known ID strings */
  437         if (strcmp(ea->ea_idstring, "ADP0000") &&
  438             strcmp(ea->ea_idstring, "ADP0001") &&
  439             strcmp(ea->ea_idstring, "ADP0002") &&
  440             strcmp(ea->ea_idstring, "ADP0400"))
  441                 return (0);
  442 
  443         if (bus_space_map(iot, EISA_SLOT_ADDR(ea->ea_slot), EISA_SLOT_SIZE, 0,
  444             &ioh))
  445                 return (0);
  446 
  447 #ifdef notyet
  448         /* This won't compile as-is, anyway. */
  449         bus_space_write_1(iot, ioh, EISA_CONTROL, EISA_ENABLE | EISA_RESET);
  450         delay(10);
  451         bus_space_write_1(iot, ioh, EISA_CONTROL, EISA_ENABLE);
  452         /* Wait for reset? */
  453         delay(1000);
  454 #endif
  455 
  456         rv = !ahb_find(iot, ioh, NULL);
  457 
  458         bus_space_unmap(ea->ea_iot, ioh, EISA_SLOT_SIZE);
  459 
  460         return (rv);
  461 }
  462 
  463 int
  464 ahbprint(aux, name)
  465         void *aux;
  466         const char *name;
  467 {
  468         return UNCONF;
  469 }
  470 
  471 /*
  472  * Attach all the sub-devices we can find
  473  */
  474 void
  475 ahbattach(parent, self, aux)
  476         struct device *parent, *self;
  477         void *aux;
  478 {
  479         struct eisa_attach_args *ea = aux;
  480         struct ahb_softc *sc = (void *)self;
  481         struct scsibus_attach_args saa;
  482         bus_space_tag_t iot = ea->ea_iot;
  483         bus_space_handle_t ioh;
  484         eisa_chipset_tag_t ec = ea->ea_ec;
  485         eisa_intr_handle_t ih;
  486         const char *model, *intrstr;
  487 
  488         sc->sc_iot = iot;
  489         sc->sc_ec = ec;
  490 
  491         if (bus_space_map(iot, EISA_SLOT_ADDR(ea->ea_slot), EISA_SLOT_SIZE, 0,
  492             &ioh))
  493                 panic("ahbattach: could not map I/O addresses");
  494         sc->sc_ioh = ioh;
  495         if (ahb_find(iot, ioh, sc))
  496                 panic("ahbattach: ahb_find failed!");
  497 
  498         ahb_init(sc);
  499         TAILQ_INIT(&sc->free_ecb);
  500 
  501         /*
  502          * fill in the prototype scsi_link.
  503          */
  504         sc->sc_link.adapter_softc = sc;
  505         sc->sc_link.adapter_target = sc->ahb_scsi_dev;
  506         sc->sc_link.adapter = &ahb_switch;
  507         sc->sc_link.device = &ahb_dev;
  508         sc->sc_link.openings = 2;
  509 
  510         if (!strcmp(ea->ea_idstring, "ADP0000"))
  511                 model = EISA_PRODUCT_ADP0000;
  512         else if (!strcmp(ea->ea_idstring, "ADP0001"))
  513                 model = EISA_PRODUCT_ADP0001;
  514         else if (!strcmp(ea->ea_idstring, "ADP0002"))
  515                 model = EISA_PRODUCT_ADP0002;
  516         else if (!strcmp(ea->ea_idstring, "ADP0400"))
  517                 model = EISA_PRODUCT_ADP0400;
  518         else
  519                 model = "unknown model!";
  520         printf(": <%s> ", model);
  521 
  522         if (eisa_intr_map(ec, sc->sc_irq, &ih)) {
  523                 printf("%s: couldn't map interrupt (%d)\n",
  524                     sc->sc_dev.dv_xname, sc->sc_irq);
  525                 return;
  526         }
  527         intrstr = eisa_intr_string(ec, ih);
  528         sc->sc_ih = eisa_intr_establish(ec, ih, IST_LEVEL, IPL_BIO,
  529             ahbintr, sc, sc->sc_dev.dv_xname);
  530         if (sc->sc_ih == NULL) {
  531                 printf("%s: couldn't establish interrupt",
  532                     sc->sc_dev.dv_xname);
  533                 if (intrstr != NULL)
  534                         printf(" at %s", intrstr);
  535                 printf("\n");
  536                 return;
  537         }
  538         if (intrstr != NULL)
  539                 printf("%s\n", intrstr);
  540 
  541         bzero(&saa, sizeof(saa));
  542         saa.saa_sc_link = &sc->sc_link;
  543 
  544         /*
  545          * ask the adapter what subunits are present
  546          */
  547         config_found(self, &saa, ahbprint);
  548 }
  549 
  550 /*
  551  * Catch an interrupt from the adaptor
  552  */
  553 int
  554 ahbintr(arg)
  555         void *arg;
  556 {
  557         struct ahb_softc *sc = arg;
  558         bus_space_tag_t iot = sc->sc_iot;
  559         bus_space_handle_t ioh = sc->sc_ioh;
  560         struct ahb_ecb *ecb;
  561         u_char ahbstat;
  562         u_long mboxval;
  563 
  564 #ifdef  AHBDEBUG
  565         printf("%s: ahbintr ", sc->sc_dev.dv_xname);
  566 #endif /* AHBDEBUG */
  567 
  568         if ((bus_space_read_1(iot, ioh, G2STAT) & G2STAT_INT_PEND) == 0)
  569                 return 0;
  570 
  571         for (;;) {
  572                 /*
  573                  * First get all the information and then
  574                  * acknowledge the interrupt
  575                  */
  576                 ahbstat = bus_space_read_1(iot, ioh, G2INTST);
  577                 mboxval = bus_space_read_4(iot, ioh, MBOXIN0);
  578                 bus_space_write_1(iot, ioh, G2CNTRL, G2CNTRL_CLEAR_EISA_INT);
  579 
  580 #ifdef  AHBDEBUG
  581                 printf("status = 0x%x ", ahbstat);
  582 #endif /*AHBDEBUG */
  583 
  584                 /*
  585                  * Process the completed operation
  586                  */
  587                 switch (ahbstat & G2INTST_INT_STAT) {
  588                 case AHB_ECB_OK:
  589                 case AHB_ECB_RECOVERED:
  590                 case AHB_ECB_ERR:
  591                         ecb = ahb_ecb_phys_kv(sc, mboxval);
  592                         if (!ecb) {
  593                                 printf("%s: BAD ECB RETURNED!\n",
  594                                     sc->sc_dev.dv_xname);
  595                                 continue;       /* whatever it was, it'll timeout */
  596                         }
  597                         break;
  598 
  599                 case AHB_IMMED_ERR:
  600                         ecb->flags |= ECB_IMMED_FAIL;
  601                 case AHB_IMMED_OK:
  602                         ecb = sc->immed_ecb;
  603                         sc->immed_ecb = 0;
  604                         break;
  605 
  606                 default:
  607                         printf("%s: unexpected interrupt %x\n",
  608                             sc->sc_dev.dv_xname, ahbstat);
  609                         ecb = 0;
  610                         break;
  611                 }
  612                 if (ecb) {
  613 #ifdef  AHBDEBUG
  614                         if (ahb_debug & AHB_SHOWCMDS)
  615                                 show_scsi_cmd(ecb->xs);
  616                         if ((ahb_debug & AHB_SHOWECBS) && ecb)
  617                                 printf("<int ecb(%x)>", ecb);
  618 #endif /*AHBDEBUG */
  619                         timeout_del(&ecb->xs->stimeout);
  620                         ahb_done(sc, ecb);
  621                 }
  622 
  623                 if ((bus_space_read_1(iot, ioh, G2STAT) & G2STAT_INT_PEND) ==
  624                     0)
  625                         return 1;
  626         }
  627 }
  628 
  629 /*
  630  * We have a ecb which has been processed by the adaptor, now we look to see
  631  * how the operation went.
  632  */
  633 void
  634 ahb_done(sc, ecb)
  635         struct ahb_softc *sc;
  636         struct ahb_ecb *ecb;
  637 {
  638         struct ahb_ecb_status *stat = &ecb->ecb_status;
  639         struct scsi_sense_data *s1, *s2;
  640         struct scsi_xfer *xs = ecb->xs;
  641 
  642         SC_DEBUG(xs->sc_link, SDEV_DB2, ("ahb_done\n"));
  643         /*
  644          * Otherwise, put the results of the operation
  645          * into the xfer and call whoever started it
  646          */
  647         if (ecb->flags & ECB_IMMED) {
  648                 if (ecb->flags & ECB_IMMED_FAIL)
  649                         xs->error = XS_DRIVER_STUFFUP;
  650                 goto done;
  651         }
  652         if (xs->error == XS_NOERROR) {
  653                 if (stat->host_stat != HS_OK) {
  654                         switch (stat->host_stat) {
  655                         case HS_SCSI_RESET_ADAPTER:
  656                                 break;
  657                         case HS_SCSI_RESET_INCOMING:
  658                                 break;
  659                         case HS_CMD_ABORTED_HOST:
  660                         case HS_CMD_ABORTED_ADAPTER:
  661                                 xs->error = XS_DRIVER_STUFFUP;
  662                                 break;
  663                         case HS_TIMED_OUT:      /* No response */
  664                                 xs->error = XS_SELTIMEOUT;
  665                                 break;
  666                         default:        /* Other scsi protocol messes */
  667                                 printf("%s: host_stat %x\n",
  668                                     sc->sc_dev.dv_xname, stat->host_stat);
  669                                 xs->error = XS_DRIVER_STUFFUP;
  670                         }
  671                 } else if (stat->target_stat != SCSI_OK) {
  672                         switch (stat->target_stat) {
  673                         case SCSI_CHECK:
  674                                 s1 = &ecb->ecb_sense;
  675                                 s2 = &xs->sense;
  676                                 *s2 = *s1;
  677                                 xs->error = XS_SENSE;
  678                                 break;
  679                         case SCSI_BUSY:
  680                                 xs->error = XS_BUSY;
  681                                 break;
  682                         default:
  683                                 printf("%s: target_stat %x\n",
  684                                     sc->sc_dev.dv_xname, stat->target_stat);
  685                                 xs->error = XS_DRIVER_STUFFUP;
  686                         }
  687                 } else
  688                         xs->resid = 0;
  689         }
  690 done:
  691         xs->flags |= ITSDONE;
  692         ahb_free_ecb(sc, ecb, xs->flags);
  693         scsi_done(xs);
  694 }
  695 
  696 /*
  697  * A ecb (and hence a mbx-out is put onto the
  698  * free list.
  699  */
  700 void
  701 ahb_free_ecb(sc, ecb, flags)
  702         struct ahb_softc *sc;
  703         struct ahb_ecb *ecb;
  704         int flags;
  705 {
  706         int s;
  707 
  708         s = splbio();
  709 
  710         ecb->flags = ECB_FREE;
  711         TAILQ_INSERT_HEAD(&sc->free_ecb, ecb, chain);
  712 
  713         /*
  714          * If there were none, wake anybody waiting for one to come free,
  715          * starting with queued entries.
  716          */
  717         if (TAILQ_NEXT(ecb, chain) == NULL)
  718                 wakeup(&sc->free_ecb);
  719 
  720         splx(s);
  721 }
  722 
  723 static inline void ahb_init_ecb(struct ahb_softc *, struct ahb_ecb *);
  724 
  725 static inline void
  726 ahb_init_ecb(sc, ecb)
  727         struct ahb_softc *sc;
  728         struct ahb_ecb *ecb;
  729 {
  730         int hashnum;
  731 
  732         bzero(ecb, sizeof(struct ahb_ecb));
  733         /*
  734          * put in the phystokv hash table
  735          * Never gets taken out.
  736          */
  737         ecb->hashkey = KVTOPHYS(ecb);
  738         hashnum = ECB_HASH(ecb->hashkey);
  739         ecb->nexthash = sc->ecbhash[hashnum];
  740         sc->ecbhash[hashnum] = ecb;
  741 }
  742 
  743 static inline void ahb_reset_ecb(struct ahb_softc *, struct ahb_ecb *);
  744 
  745 static inline void
  746 ahb_reset_ecb(sc, ecb)
  747         struct ahb_softc *sc;
  748         struct ahb_ecb *ecb;
  749 {
  750 
  751 }
  752 
  753 /*
  754  * Get a free ecb
  755  *
  756  * If there are none, see if we can allocate a new one. If so, put it in the
  757  * hash table too otherwise either return an error or sleep.
  758  */
  759 struct ahb_ecb *
  760 ahb_get_ecb(sc, flags)
  761         struct ahb_softc *sc;
  762         int flags;
  763 {
  764         struct ahb_ecb *ecb;
  765         int s;
  766 
  767         s = splbio();
  768 
  769         /*
  770          * If we can and have to, sleep waiting for one to come free
  771          * but only if we can't allocate a new one.
  772          */
  773         for (;;) {
  774                 ecb = TAILQ_FIRST(&sc->free_ecb);
  775                 if (ecb) {
  776                         TAILQ_REMOVE(&sc->free_ecb, ecb, chain);
  777                         break;
  778                 }
  779                 if (sc->numecbs < AHB_ECB_MAX) {
  780                         ecb = (struct ahb_ecb *) malloc(sizeof(struct ahb_ecb),
  781                             M_TEMP, M_NOWAIT);
  782                         if (ecb) {
  783                                 ahb_init_ecb(sc, ecb);
  784                                 sc->numecbs++;
  785                         } else {
  786                                 printf("%s: can't malloc ecb\n",
  787                                     sc->sc_dev.dv_xname);
  788                                 goto out;
  789                         }
  790                         break;
  791                 }
  792                 if ((flags & SCSI_NOSLEEP) != 0)
  793                         goto out;
  794                 tsleep(&sc->free_ecb, PRIBIO, "ahbecb", 0);
  795         }
  796 
  797         ahb_reset_ecb(sc, ecb);
  798         ecb->flags = ECB_ACTIVE;
  799 
  800 out:
  801         splx(s);
  802         return ecb;
  803 }
  804 
  805 /*
  806  * given a physical address, find the ecb that it corresponds to.
  807  */
  808 struct ahb_ecb *
  809 ahb_ecb_phys_kv(sc, ecb_phys)
  810         struct ahb_softc *sc;
  811         physaddr ecb_phys;
  812 {
  813         int hashnum = ECB_HASH(ecb_phys);
  814         struct ahb_ecb *ecb = sc->ecbhash[hashnum];
  815 
  816         while (ecb) {
  817                 if (ecb->hashkey == ecb_phys)
  818                         break;
  819                 ecb = ecb->nexthash;
  820         }
  821         return ecb;
  822 }
  823 
  824 /*
  825  * Start the board, ready for normal operation
  826  */
  827 int
  828 ahb_find(iot, ioh, sc)
  829         bus_space_tag_t iot;
  830         bus_space_handle_t ioh;
  831         struct ahb_softc *sc;
  832 {
  833         u_char intdef;
  834         int i, irq, busid;
  835         int wait = 1000;        /* 1 sec enough? */
  836 
  837         bus_space_write_1(iot, ioh, PORTADDR, PORTADDR_ENHANCED);
  838 
  839 #define NO_NO 1
  840 #ifdef NO_NO
  841         /*
  842          * reset board, If it doesn't respond, assume
  843          * that it's not there.. good for the probe
  844          */
  845         bus_space_write_1(iot, ioh, G2CNTRL, G2CNTRL_HARD_RESET);
  846         delay(1000);
  847         bus_space_write_1(iot, ioh, G2CNTRL, 0);
  848         delay(10000);
  849         while (--wait) {
  850                 if ((bus_space_read_1(iot, ioh, G2STAT) & G2STAT_BUSY) == 0)
  851                         break;
  852                 delay(1000);
  853         }
  854         if (!wait) {
  855 #ifdef AHBDEBUG
  856                 if (ahb_debug & AHB_SHOWMISC)
  857                         printf("ahb_find: No answer from aha1742 board\n");
  858 #endif /*AHBDEBUG */
  859                 return ENXIO;
  860         }
  861         i = bus_space_read_1(iot, ioh, MBOXIN0);
  862         if (i) {
  863                 printf("self test failed, val = 0x%x\n", i);
  864                 return EIO;
  865         }
  866 
  867         /* Set it again, just to be sure. */
  868         bus_space_write_1(iot, ioh, PORTADDR, PORTADDR_ENHANCED);
  869 #endif
  870 
  871         while (bus_space_read_1(iot, ioh, G2STAT) & G2STAT_INT_PEND) {
  872                 printf(".");
  873                 bus_space_write_1(iot, ioh, G2CNTRL, G2CNTRL_CLEAR_EISA_INT);
  874                 delay(10000);
  875         }
  876 
  877         intdef = bus_space_read_1(iot, ioh, INTDEF);
  878         switch (intdef & 0x07) {
  879         case INT9:
  880                 irq = 9;
  881                 break;
  882         case INT10:
  883                 irq = 10;
  884                 break;
  885         case INT11:
  886                 irq = 11;
  887                 break;
  888         case INT12:
  889                 irq = 12;
  890                 break;
  891         case INT14:
  892                 irq = 14;
  893                 break;
  894         case INT15:
  895                 irq = 15;
  896                 break;
  897         default:
  898                 printf("illegal int setting %x\n", intdef);
  899                 return EIO;
  900         }
  901 
  902         /* make sure we can interrupt */
  903         bus_space_write_1(iot, ioh, INTDEF, (intdef | INTEN));
  904 
  905         /* who are we on the scsi bus? */
  906         busid = (bus_space_read_1(iot, ioh, SCSIDEF) & HSCSIID);
  907 
  908         /* if we want to fill in softc, do so now */
  909         if (sc != NULL) {
  910                 sc->sc_irq = irq;
  911                 sc->ahb_scsi_dev = busid;
  912         }
  913 
  914         /*
  915          * Note that we are going and return (to probe)
  916          */
  917         return 0;
  918 }
  919 
  920 void
  921 ahb_init(sc)
  922         struct ahb_softc *sc;
  923 {
  924 
  925 }
  926 
  927 void
  928 ahbminphys(bp)
  929         struct buf *bp;
  930 {
  931 
  932         if (bp->b_bcount > ((AHB_NSEG - 1) << PGSHIFT))
  933                 bp->b_bcount = ((AHB_NSEG - 1) << PGSHIFT);
  934         minphys(bp);
  935 }
  936 
  937 /*
  938  * start a scsi operation given the command and the data address.  Also needs
  939  * the unit, target and lu.
  940  */
  941 int
  942 ahb_scsi_cmd(xs)
  943         struct scsi_xfer *xs;
  944 {
  945         struct scsi_link *sc_link = xs->sc_link;
  946         struct ahb_softc *sc = sc_link->adapter_softc;
  947         struct ahb_ecb *ecb;
  948         struct ahb_dma_seg *sg;
  949         int seg;                /* scatter gather seg being worked on */
  950         u_long thiskv, thisphys, nextphys;
  951         int bytes_this_seg, bytes_this_page, datalen, flags;
  952 #ifdef TFS
  953         struct iovec *iovp;
  954 #endif
  955         int s;
  956 
  957         SC_DEBUG(sc_link, SDEV_DB2, ("ahb_scsi_cmd\n"));
  958         /*
  959          * get a ecb (mbox-out) to use. If the transfer
  960          * is from a buf (possibly from interrupt time)
  961          * then we can't allow it to sleep
  962          */
  963         flags = xs->flags;
  964         if (flags & ITSDONE) {
  965                 printf("%s: done?\n", sc->sc_dev.dv_xname);
  966                 xs->flags &= ~ITSDONE;
  967         }
  968         if ((ecb = ahb_get_ecb(sc, flags)) == NULL) {
  969                 return TRY_AGAIN_LATER;
  970         }
  971         ecb->xs = xs;
  972         timeout_set(&ecb->xs->stimeout, ahb_timeout, ecb);
  973 
  974         /*
  975          * If it's a reset, we need to do an 'immediate'
  976          * command, and store its ecb for later
  977          * if there is already an immediate waiting,
  978          * then WE must wait
  979          */
  980         if (flags & SCSI_RESET) {
  981                 ecb->flags |= ECB_IMMED;
  982                 if (sc->immed_ecb)
  983                         return TRY_AGAIN_LATER;
  984                 sc->immed_ecb = ecb;
  985 
  986                 s = splbio();
  987 
  988                 ahb_send_immed(sc, sc_link->target, AHB_TARG_RESET);
  989 
  990                 if ((flags & SCSI_POLL) == 0) {
  991                         splx(s);
  992                         timeout_add(&ecb->xs->stimeout, (xs->timeout * hz) / 1000);
  993                         return SUCCESSFULLY_QUEUED;
  994                 }
  995 
  996                 splx(s);
  997 
  998                 /*
  999                  * If we can't use interrupts, poll on completion
 1000                  */
 1001                 if (ahb_poll(sc, xs, xs->timeout))
 1002                         ahb_timeout(ecb);
 1003                 return COMPLETE;
 1004         }
 1005 
 1006         /*
 1007          * Put all the arguments for the xfer in the ecb
 1008          */
 1009         ecb->opcode = ECB_SCSI_OP;
 1010         ecb->opt1 = ECB_SES | ECB_DSB | ECB_ARS;
 1011         if (xs->datalen)
 1012                 ecb->opt1 |= ECB_S_G;
 1013         ecb->opt2 = sc_link->lun | ECB_NRB;
 1014         ecb->scsi_cmd_length = xs->cmdlen;
 1015         ecb->sense_ptr = KVTOPHYS(&ecb->ecb_sense);
 1016         ecb->req_sense_length = sizeof(ecb->ecb_sense);
 1017         ecb->status = KVTOPHYS(&ecb->ecb_status);
 1018         ecb->ecb_status.host_stat = 0x00;
 1019         ecb->ecb_status.target_stat = 0x00;
 1020 
 1021         if (xs->datalen && (flags & SCSI_RESET) == 0) {
 1022                 ecb->data_addr = KVTOPHYS(ecb->ahb_dma);
 1023                 sg = ecb->ahb_dma;
 1024                 seg = 0;
 1025 #ifdef  TFS
 1026                 if (flags & SCSI_DATA_UIO) {
 1027                         iovp = ((struct uio *) xs->data)->uio_iov;
 1028                         datalen = ((struct uio *) xs->data)->uio_iovcnt;
 1029                         xs->datalen = 0;
 1030                         while (datalen && seg < AHB_NSEG) {
 1031                                 sg->seg_addr = (physaddr)iovp->iov_base;
 1032                                 sg->seg_len = iovp->iov_len;
 1033                                 xs->datalen += iovp->iov_len;
 1034                                 SC_DEBUGN(sc_link, SDEV_DB4, ("(0x%x@0x%x)",
 1035                                     iovp->iov_len, iovp->iov_base));
 1036                                 sg++;
 1037                                 iovp++;
 1038                                 seg++;
 1039                                 datalen--;
 1040                         }
 1041                 }
 1042                 else
 1043 #endif /*TFS */
 1044                 {
 1045                         /*
 1046                          * Set up the scatter gather block
 1047                          */
 1048                         SC_DEBUG(sc_link, SDEV_DB4,
 1049                             ("%d @0x%x:- ", xs->datalen, xs->data));
 1050                         datalen = xs->datalen;
 1051                         thiskv = (long) xs->data;
 1052                         thisphys = KVTOPHYS(thiskv);
 1053 
 1054                         while (datalen && seg < AHB_NSEG) {
 1055                                 bytes_this_seg = 0;
 1056 
 1057                                 /* put in the base address */
 1058                                 sg->seg_addr = thisphys;
 1059 
 1060                                 SC_DEBUGN(sc_link, SDEV_DB4, ("0x%x", thisphys));
 1061 
 1062                                 /* do it at least once */
 1063                                 nextphys = thisphys;
 1064                                 while (datalen && thisphys == nextphys) {
 1065                                         /*
 1066                                          * This page is contiguous (physically)
 1067                                          * with the last, just extend the
 1068                                          * length
 1069                                          */
 1070                                         /* how far to the end of the page */
 1071                                         nextphys = (thisphys & ~PGOFSET) + NBPG;
 1072                                         bytes_this_page = nextphys - thisphys;
 1073                                         /**** or the data ****/
 1074                                         bytes_this_page = min(bytes_this_page,
 1075                                                               datalen);
 1076                                         bytes_this_seg += bytes_this_page;
 1077                                         datalen -= bytes_this_page;
 1078 
 1079                                         /* get more ready for the next page */
 1080                                         thiskv = (thiskv & ~PGOFSET) + NBPG;
 1081                                         if (datalen)
 1082                                                 thisphys = KVTOPHYS(thiskv);
 1083                                 }
 1084                                 /*
 1085                                  * next page isn't contiguous, finish the seg
 1086                                  */
 1087                                 SC_DEBUGN(sc_link, SDEV_DB4,
 1088                                     ("(0x%x)", bytes_this_seg));
 1089                                 sg->seg_len = bytes_this_seg;
 1090                                 sg++;
 1091                                 seg++;
 1092                         }
 1093                 }
 1094                 /*end of iov/kv decision */
 1095                 ecb->data_length = seg * sizeof(struct ahb_dma_seg);
 1096                 SC_DEBUGN(sc_link, SDEV_DB4, ("\n"));
 1097                 if (datalen) {
 1098                         /*
 1099                          * there's still data, must have run out of segs!
 1100                          */
 1101                         printf("%s: ahb_scsi_cmd, more than %d dma segs\n",
 1102                             sc->sc_dev.dv_xname, AHB_NSEG);
 1103                         xs->error = XS_DRIVER_STUFFUP;
 1104                         ahb_free_ecb(sc, ecb, flags);
 1105                         return COMPLETE;
 1106                 }
 1107         } else {        /* No data xfer, use non S/G values */
 1108                 ecb->data_addr = (physaddr)0;
 1109                 ecb->data_length = 0;
 1110         }
 1111         ecb->link_addr = (physaddr)0;
 1112 
 1113         /*
 1114          * Put the scsi command in the ecb and start it
 1115          */
 1116         if ((flags & SCSI_RESET) == 0)
 1117                 bcopy(xs->cmd, &ecb->scsi_cmd, ecb->scsi_cmd_length);
 1118 
 1119         s = splbio();
 1120 
 1121         ahb_send_mbox(sc, OP_START_ECB, ecb);
 1122 
 1123         /*
 1124          * Usually return SUCCESSFULLY QUEUED
 1125          */
 1126         if ((flags & SCSI_POLL) == 0) {
 1127                 splx(s);
 1128                 timeout_add(&ecb->xs->stimeout, (xs->timeout * hz) / 1000);
 1129                 return SUCCESSFULLY_QUEUED;
 1130         }
 1131 
 1132         splx(s);
 1133 
 1134         /*
 1135          * If we can't use interrupts, poll on completion
 1136          */
 1137         if (ahb_poll(sc, xs, xs->timeout)) {
 1138                 ahb_timeout(ecb);
 1139                 if (ahb_poll(sc, xs, 2000))
 1140                         ahb_timeout(ecb);
 1141         }
 1142         return COMPLETE;
 1143 }
 1144 
 1145 void
 1146 ahb_timeout(arg)
 1147         void *arg;
 1148 {
 1149         struct ahb_ecb *ecb = arg;
 1150         struct scsi_xfer *xs = ecb->xs;
 1151         struct scsi_link *sc_link = xs->sc_link;
 1152         struct ahb_softc *sc = sc_link->adapter_softc;
 1153         int s;
 1154 
 1155         sc_print_addr(sc_link);
 1156         printf("timed out");
 1157 
 1158         s = splbio();
 1159 
 1160         if (ecb->flags & ECB_IMMED) {
 1161                 printf("\n");
 1162                 ecb->xs->retries = 0;   /* I MEAN IT ! */
 1163                 ecb->flags |= ECB_IMMED_FAIL;
 1164                 ahb_done(sc, ecb);
 1165                 splx(s);
 1166                 return;
 1167         }
 1168 
 1169         /*
 1170          * If it has been through before, then
 1171          * a previous abort has failed, don't
 1172          * try abort again
 1173          */
 1174         if (ecb->flags == ECB_ABORTED) {
 1175                 /* abort timed out */
 1176                 printf(" AGAIN\n");
 1177                 ecb->xs->retries = 0;   /* I MEAN IT ! */
 1178                 ahb_done(sc, ecb);
 1179         } else {
 1180                 /* abort the operation that has timed out */
 1181                 printf("\n");
 1182                 ecb->xs->error = XS_TIMEOUT;
 1183                 ecb->flags = ECB_ABORTED;
 1184                 ahb_send_mbox(sc, OP_ABORT_ECB, ecb);
 1185                 /* 2 secs for the abort */
 1186                 if ((xs->flags & SCSI_POLL) == 0)
 1187                         timeout_add(&ecb->xs->stimeout, 2 * hz);
 1188         }
 1189 
 1190         splx(s);
 1191 }
 1192 
 1193 #ifdef  AHBDEBUG
 1194 void
 1195 ahb_print_ecb(ecb)
 1196         struct ahb_ecb *ecb;
 1197 {
 1198         printf("ecb:%x op:%x cmdlen:%d senlen:%d\n",
 1199                 ecb, ecb->opcode, ecb->cdblen, ecb->senselen);
 1200         printf("        datlen:%d hstat:%x tstat:%x flags:%x\n",
 1201                 ecb->datalen, ecb->ecb_status.host_stat,
 1202                 ecb->ecb_status.target_stat, ecb->flags);
 1203         show_scsi_cmd(ecb->xs);
 1204 }
 1205 
 1206 void
 1207 ahb_print_active_ecb(sc)
 1208         struct ahb_softc *sc;
 1209 {
 1210         struct ahb_ecb *ecb;
 1211         int i = 0;
 1212 
 1213         while (i++ < ECB_HASH_SIZE) {
 1214                 ecb = sc->ecb_hash_list[i];
 1215                 while (ecb) {
 1216                         if (ecb->flags != ECB_FREE)
 1217                                 ahb_print_ecb(ecb);
 1218                         ecb = ecb->hash_list;
 1219                 }
 1220         }
 1221 }
 1222 #endif /* AHBDEBUG */

/* [<][>][^][v][top][bottom][index][help] */