root/dev/ic/adv.c

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

DEFINITIONS

This source file includes following definitions.
  1. adv_enqueue
  2. adv_dequeue
  3. adv_alloc_ccbs
  4. adv_create_ccbs
  5. adv_free_ccb
  6. adv_reset_ccb
  7. adv_init_ccb
  8. adv_get_ccb
  9. adv_queue_ccb
  10. adv_start_ccbs
  11. adv_alloc_overrunbuf
  12. adv_init
  13. adv_attach
  14. advminphys
  15. adv_scsi_cmd
  16. adv_intr
  17. adv_poll
  18. adv_timeout
  19. adv_watchdog
  20. adv_narrow_isr_callback

    1 /*      $OpenBSD: adv.c,v 1.17 2006/11/29 01:00:47 grange Exp $ */
    2 /*      $NetBSD: adv.c,v 1.6 1998/10/28 20:39:45 dante Exp $    */
    3 
    4 /*
    5  * Generic driver for the Advanced Systems Inc. Narrow SCSI controllers
    6  *
    7  * Copyright (c) 1998 The NetBSD Foundation, Inc.
    8  * All rights reserved.
    9  *
   10  * Author: Baldassare Dante Profeta <dante@mclink.it>
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer.
   17  * 2. Redistributions in binary form must reproduce the above copyright
   18  *    notice, this list of conditions and the following disclaimer in the
   19  *    documentation and/or other materials provided with the distribution.
   20  * 3. All advertising materials mentioning features or use of this software
   21  *    must display the following acknowledgement:
   22  *        This product includes software developed by the NetBSD
   23  *        Foundation, Inc. and its contributors.
   24  * 4. Neither the name of The NetBSD Foundation nor the names of its
   25  *    contributors may be used to endorse or promote products derived
   26  *    from this software without specific prior written permission.
   27  *
   28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   38  * POSSIBILITY OF SUCH DAMAGE.
   39  */
   40 
   41 #include <sys/types.h>
   42 #include <sys/param.h>
   43 #include <sys/systm.h>
   44 #include <sys/kernel.h>
   45 #include <sys/errno.h>
   46 #include <sys/ioctl.h>
   47 #include <sys/device.h>
   48 #include <sys/malloc.h>
   49 #include <sys/buf.h>
   50 #include <sys/proc.h>
   51 #include <sys/user.h>
   52 
   53 #include <machine/bus.h>
   54 #include <machine/intr.h>
   55 
   56 #include <scsi/scsi_all.h>
   57 #include <scsi/scsiconf.h>
   58 
   59 #include <dev/ic/adv.h>
   60 #include <dev/ic/advlib.h>
   61 
   62 #ifndef DDB
   63 #define Debugger()      panic("should call debugger here (adv.c)")
   64 #endif /* ! DDB */
   65 
   66 
   67 /* #define ASC_DEBUG */
   68 
   69 /******************************************************************************/
   70 
   71 
   72 static void adv_enqueue(ASC_SOFTC *, struct scsi_xfer *, int);
   73 static struct scsi_xfer *adv_dequeue(ASC_SOFTC *);
   74 
   75 static int adv_alloc_ccbs(ASC_SOFTC *);
   76 static int adv_create_ccbs(ASC_SOFTC *, ADV_CCB *, int);
   77 static void adv_free_ccb(ASC_SOFTC *, ADV_CCB *);
   78 static void adv_reset_ccb(ADV_CCB *);
   79 static int adv_init_ccb(ASC_SOFTC *, ADV_CCB *);
   80 static ADV_CCB *adv_get_ccb(ASC_SOFTC *, int);
   81 static void adv_queue_ccb(ASC_SOFTC *, ADV_CCB *);
   82 static void adv_start_ccbs(ASC_SOFTC *);
   83 
   84 static u_int8_t *adv_alloc_overrunbuf(char *dvname, bus_dma_tag_t);
   85 
   86 static int adv_scsi_cmd(struct scsi_xfer *);
   87 static void advminphys(struct buf *);
   88 static void adv_narrow_isr_callback(ASC_SOFTC *, ASC_QDONE_INFO *);
   89 
   90 static int adv_poll(ASC_SOFTC *, struct scsi_xfer *, int);
   91 static void adv_timeout(void *);
   92 static void adv_watchdog(void *);
   93 
   94 
   95 /******************************************************************************/
   96 
   97 
   98 struct cfdriver adv_cd = {
   99         NULL, "adv", DV_DULL
  100 };
  101 
  102 
  103 struct scsi_adapter adv_switch =
  104 {
  105         adv_scsi_cmd,           /* called to start/enqueue a SCSI command */
  106         advminphys,             /* to limit the transfer to max device can do */
  107         0,                      /* IT SEEMS IT IS NOT USED YET */
  108         0,                      /* as above... */
  109 };
  110 
  111 
  112 /* the below structure is so we have a default dev struct for out link struct */
  113 struct scsi_device adv_dev =
  114 {
  115         NULL,                   /* Use default error handler */
  116         NULL,                   /* have a queue, served by this */
  117         NULL,                   /* have no async handler */
  118         NULL,                   /* Use default 'done' routine */
  119 };
  120 
  121 
  122 #define ADV_ABORT_TIMEOUT       2000    /* time to wait for abort (mSec) */
  123 #define ADV_WATCH_TIMEOUT       1000    /* time to wait for watchdog (mSec) */
  124 
  125 
  126 /******************************************************************************/
  127 /*                            scsi_xfer queue routines                      */
  128 /******************************************************************************/
  129 
  130 
  131 /*
  132  * Insert a scsi_xfer into the software queue.  We overload xs->free_list
  133  * to avoid having to allocate additional resources (since we're used
  134  * only during resource shortages anyhow.
  135  */
  136 static void
  137 adv_enqueue(sc, xs, infront)
  138         ASC_SOFTC      *sc;
  139         struct scsi_xfer *xs;
  140         int             infront;
  141 {
  142 
  143         if (infront || LIST_EMPTY(&sc->sc_queue)) {
  144                 if (LIST_EMPTY(&sc->sc_queue))
  145                         sc->sc_queuelast = xs;
  146                 LIST_INSERT_HEAD(&sc->sc_queue, xs, free_list);
  147                 return;
  148         }
  149         LIST_INSERT_AFTER(sc->sc_queuelast, xs, free_list);
  150         sc->sc_queuelast = xs;
  151 }
  152 
  153 
  154 /*
  155  * Pull a scsi_xfer off the front of the software queue.
  156  */
  157 static struct scsi_xfer *
  158 adv_dequeue(sc)
  159         ASC_SOFTC      *sc;
  160 {
  161         struct scsi_xfer *xs;
  162 
  163         xs = LIST_FIRST(&sc->sc_queue);
  164         LIST_REMOVE(xs, free_list);
  165 
  166         if (LIST_EMPTY(&sc->sc_queue))
  167                 sc->sc_queuelast = NULL;
  168 
  169         return (xs);
  170 }
  171 
  172 
  173 /******************************************************************************/
  174 /*                             Control Blocks routines                        */
  175 /******************************************************************************/
  176 
  177 
  178 static int
  179 adv_alloc_ccbs(sc)
  180         ASC_SOFTC      *sc;
  181 {
  182         bus_dma_segment_t seg;
  183         int             error, rseg;
  184 
  185         /*
  186          * Allocate the control blocks.
  187          */
  188         if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct adv_control),
  189                            NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
  190                 printf("%s: unable to allocate control structures,"
  191                        " error = %d\n", sc->sc_dev.dv_xname, error);
  192                 return (error);
  193         }
  194         if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
  195                    sizeof(struct adv_control), (caddr_t *) & sc->sc_control,
  196                                  BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
  197                 printf("%s: unable to map control structures, error = %d\n",
  198                        sc->sc_dev.dv_xname, error);
  199                 return (error);
  200         }
  201         /*
  202          * Create and load the DMA map used for the control blocks.
  203          */
  204         if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct adv_control),
  205                            1, sizeof(struct adv_control), 0, BUS_DMA_NOWAIT,
  206                                        &sc->sc_dmamap_control)) != 0) {
  207                 printf("%s: unable to create control DMA map, error = %d\n",
  208                        sc->sc_dev.dv_xname, error);
  209                 return (error);
  210         }
  211         if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_control,
  212                            sc->sc_control, sizeof(struct adv_control), NULL,
  213                                      BUS_DMA_NOWAIT)) != 0) {
  214                 printf("%s: unable to load control DMA map, error = %d\n",
  215                        sc->sc_dev.dv_xname, error);
  216                 return (error);
  217         }
  218         return (0);
  219 }
  220 
  221 
  222 /*
  223  * Create a set of ccbs and add them to the free list.  Called once
  224  * by adv_init().  We return the number of CCBs successfully created.
  225  */
  226 static int
  227 adv_create_ccbs(sc, ccbstore, count)
  228         ASC_SOFTC      *sc;
  229         ADV_CCB        *ccbstore;
  230         int             count;
  231 {
  232         ADV_CCB        *ccb;
  233         int             i, error;
  234 
  235         bzero(ccbstore, sizeof(ADV_CCB) * count);
  236         for (i = 0; i < count; i++) {
  237                 ccb = &ccbstore[i];
  238                 if ((error = adv_init_ccb(sc, ccb)) != 0) {
  239                         printf("%s: unable to initialize ccb, error = %d\n",
  240                                sc->sc_dev.dv_xname, error);
  241                         return (i);
  242                 }
  243                 TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, chain);
  244         }
  245 
  246         return (i);
  247 }
  248 
  249 
  250 /*
  251  * A ccb is put onto the free list.
  252  */
  253 static void
  254 adv_free_ccb(sc, ccb)
  255         ASC_SOFTC      *sc;
  256         ADV_CCB        *ccb;
  257 {
  258         int             s;
  259 
  260         s = splbio();
  261 
  262         adv_reset_ccb(ccb);
  263         TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain);
  264 
  265         /*
  266          * If there were none, wake anybody waiting for one to come free,
  267          * starting with queued entries.
  268          */
  269         if (TAILQ_NEXT(ccb, chain) == NULL)
  270                 wakeup(&sc->sc_free_ccb);
  271 
  272         splx(s);
  273 }
  274 
  275 
  276 static void
  277 adv_reset_ccb(ccb)
  278         ADV_CCB        *ccb;
  279 {
  280 
  281         ccb->flags = 0;
  282 }
  283 
  284 
  285 static int
  286 adv_init_ccb(sc, ccb)
  287         ASC_SOFTC      *sc;
  288         ADV_CCB        *ccb;
  289 {
  290         int             error;
  291 
  292         /*
  293          * Create the DMA map for this CCB.
  294          */
  295         error = bus_dmamap_create(sc->sc_dmat,
  296                                   (ASC_MAX_SG_LIST - 1) * PAGE_SIZE,
  297                          ASC_MAX_SG_LIST, (ASC_MAX_SG_LIST - 1) * PAGE_SIZE,
  298                    0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ccb->dmamap_xfer);
  299         if (error) {
  300                 printf("%s: unable to create DMA map, error = %d\n",
  301                        sc->sc_dev.dv_xname, error);
  302                 return (error);
  303         }
  304         adv_reset_ccb(ccb);
  305         return (0);
  306 }
  307 
  308 
  309 /*
  310  * Get a free ccb
  311  *
  312  * If there are none, see if we can allocate a new one
  313  */
  314 static ADV_CCB *
  315 adv_get_ccb(sc, flags)
  316         ASC_SOFTC      *sc;
  317         int             flags;
  318 {
  319         ADV_CCB        *ccb = 0;
  320         int             s;
  321 
  322         s = splbio();
  323 
  324         /*
  325          * If we can and have to, sleep waiting for one to come free
  326          * but only if we can't allocate a new one.
  327          */
  328         for (;;) {
  329                 ccb = TAILQ_FIRST(&sc->sc_free_ccb);
  330                 if (ccb) {
  331                         TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain);
  332                         break;
  333                 }
  334                 if ((flags & SCSI_NOSLEEP) != 0)
  335                         goto out;
  336 
  337                 tsleep(&sc->sc_free_ccb, PRIBIO, "advccb", 0);
  338         }
  339 
  340         ccb->flags |= CCB_ALLOC;
  341 
  342 out:
  343         splx(s);
  344         return (ccb);
  345 }
  346 
  347 
  348 /*
  349  * Queue a CCB to be sent to the controller, and send it if possible.
  350  */
  351 static void
  352 adv_queue_ccb(sc, ccb)
  353         ASC_SOFTC      *sc;
  354         ADV_CCB        *ccb;
  355 {
  356 
  357         timeout_set(&ccb->xs->stimeout, adv_timeout, ccb);
  358         TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain);
  359 
  360         adv_start_ccbs(sc);
  361 }
  362 
  363 
  364 static void
  365 adv_start_ccbs(sc)
  366         ASC_SOFTC      *sc;
  367 {
  368         ADV_CCB        *ccb;
  369         struct scsi_xfer *xs;
  370 
  371         while ((ccb = TAILQ_FIRST(&sc->sc_waiting_ccb)) != NULL) {
  372 
  373                 xs = ccb->xs;
  374                 if (ccb->flags & CCB_WATCHDOG)
  375                         timeout_del(&xs->stimeout);
  376 
  377                 if (AscExeScsiQueue(sc, &ccb->scsiq) == ASC_BUSY) {
  378                         ccb->flags |= CCB_WATCHDOG;
  379                         timeout_set(&xs->stimeout, adv_watchdog, ccb);
  380                         timeout_add(&xs->stimeout,
  381                                 (ADV_WATCH_TIMEOUT * hz) / 1000);
  382                         break;
  383                 }
  384                 TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain);
  385 
  386                 if ((ccb->xs->flags & SCSI_POLL) == 0) {
  387                         timeout_set(&xs->stimeout, adv_timeout, ccb);
  388                         timeout_add(&xs->stimeout, (ccb->timeout * hz) / 1000);
  389                 }
  390         }
  391 }
  392 
  393 
  394 /******************************************************************************/
  395 /*                      DMA able memory allocation routines                   */
  396 /******************************************************************************/
  397 
  398 
  399 /*
  400  * Allocate a DMA able memory for overrun_buffer.
  401  * This memory can be safely shared among all the AdvanSys boards.
  402  */
  403 u_int8_t       *
  404 adv_alloc_overrunbuf(dvname, dmat)
  405         char           *dvname;
  406         bus_dma_tag_t   dmat;
  407 {
  408         static u_int8_t *overrunbuf = NULL;
  409 
  410         bus_dmamap_t    ovrbuf_dmamap;
  411         bus_dma_segment_t seg;
  412         int             rseg, error;
  413 
  414 
  415         /*
  416          * if an overrun buffer has been already allocated don't allocate it
  417          * again. Instead return the address of the allocated buffer.
  418          */
  419         if (overrunbuf)
  420                 return (overrunbuf);
  421 
  422 
  423         if ((error = bus_dmamem_alloc(dmat, ASC_OVERRUN_BSIZE,
  424                            NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
  425                 printf("%s: unable to allocate overrun buffer, error = %d\n",
  426                        dvname, error);
  427                 return (0);
  428         }
  429         if ((error = bus_dmamem_map(dmat, &seg, rseg, ASC_OVERRUN_BSIZE,
  430         (caddr_t *) & overrunbuf, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
  431                 printf("%s: unable to map overrun buffer, error = %d\n",
  432                        dvname, error);
  433 
  434                 bus_dmamem_free(dmat, &seg, 1);
  435                 return (0);
  436         }
  437         if ((error = bus_dmamap_create(dmat, ASC_OVERRUN_BSIZE, 1,
  438               ASC_OVERRUN_BSIZE, 0, BUS_DMA_NOWAIT, &ovrbuf_dmamap)) != 0) {
  439                 printf("%s: unable to create overrun buffer DMA map,"
  440                        " error = %d\n", dvname, error);
  441 
  442                 bus_dmamem_unmap(dmat, overrunbuf, ASC_OVERRUN_BSIZE);
  443                 bus_dmamem_free(dmat, &seg, 1);
  444                 return (0);
  445         }
  446         if ((error = bus_dmamap_load(dmat, ovrbuf_dmamap, overrunbuf,
  447                            ASC_OVERRUN_BSIZE, NULL, BUS_DMA_NOWAIT)) != 0) {
  448                 printf("%s: unable to load overrun buffer DMA map,"
  449                        " error = %d\n", dvname, error);
  450 
  451                 bus_dmamap_destroy(dmat, ovrbuf_dmamap);
  452                 bus_dmamem_unmap(dmat, overrunbuf, ASC_OVERRUN_BSIZE);
  453                 bus_dmamem_free(dmat, &seg, 1);
  454                 return (0);
  455         }
  456         return (overrunbuf);
  457 }
  458 
  459 
  460 /******************************************************************************/
  461 /*                         SCSI layer interfacing routines                    */
  462 /******************************************************************************/
  463 
  464 
  465 int
  466 adv_init(sc)
  467         ASC_SOFTC      *sc;
  468 {
  469         int             warn;
  470 
  471         if (!AscFindSignature(sc->sc_iot, sc->sc_ioh))
  472                 panic("adv_init: adv_find_signature failed");
  473 
  474         /*
  475          * Read the board configuration
  476          */
  477         AscInitASC_SOFTC(sc);
  478         warn = AscInitFromEEP(sc);
  479         if (warn) {
  480                 printf("%s -get: ", sc->sc_dev.dv_xname);
  481                 switch (warn) {
  482                 case -1:
  483                         printf("Chip is not halted\n");
  484                         break;
  485 
  486                 case -2:
  487                         printf("Couldn't get MicroCode Start"
  488                                " address\n");
  489                         break;
  490 
  491                 case ASC_WARN_IO_PORT_ROTATE:
  492                         printf("I/O port address modified\n");
  493                         break;
  494 
  495                 case ASC_WARN_AUTO_CONFIG:
  496                         printf("I/O port increment switch enabled\n");
  497                         break;
  498 
  499                 case ASC_WARN_EEPROM_CHKSUM:
  500                         printf("EEPROM checksum error\n");
  501                         break;
  502 
  503                 case ASC_WARN_IRQ_MODIFIED:
  504                         printf("IRQ modified\n");
  505                         break;
  506 
  507                 case ASC_WARN_CMD_QNG_CONFLICT:
  508                         printf("tag queuing enabled w/o disconnects\n");
  509                         break;
  510 
  511                 default:
  512                         printf("unknown warning %d\n", warn);
  513                 }
  514         }
  515         if (sc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT)
  516                 sc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT;
  517 
  518         /*
  519          * Modify the board configuration
  520          */
  521         warn = AscInitFromASC_SOFTC(sc);
  522         if (warn) {
  523                 printf("%s -set: ", sc->sc_dev.dv_xname);
  524                 switch (warn) {
  525                 case ASC_WARN_CMD_QNG_CONFLICT:
  526                         printf("tag queuing enabled w/o disconnects\n");
  527                         break;
  528 
  529                 case ASC_WARN_AUTO_CONFIG:
  530                         printf("I/O port increment switch enabled\n");
  531                         break;
  532 
  533                 default:
  534                         printf("unknown warning %d\n", warn);
  535                 }
  536         }
  537         sc->isr_callback = (ulong) adv_narrow_isr_callback;
  538 
  539         if (!(sc->overrun_buf = adv_alloc_overrunbuf(sc->sc_dev.dv_xname,
  540                                                      sc->sc_dmat))) {
  541                 return (1);
  542         }
  543 
  544         return (0);
  545 }
  546 
  547 
  548 void
  549 adv_attach(sc)
  550         ASC_SOFTC      *sc;
  551 {
  552         struct scsibus_attach_args      saa;
  553         int                             i, error;
  554 
  555         /*
  556          * Initialize board RISC chip and enable interrupts.
  557          */
  558         switch (AscInitDriver(sc)) {
  559         case 0:
  560                 /* AllOK */
  561                 break;
  562 
  563         case 1:
  564                 panic("%s: bad signature", sc->sc_dev.dv_xname);
  565                 break;
  566 
  567         case 2:
  568                 panic("%s: unable to load MicroCode",
  569                       sc->sc_dev.dv_xname);
  570                 break;
  571 
  572         case 3:
  573                 panic("%s: unable to initialize MicroCode",
  574                       sc->sc_dev.dv_xname);
  575                 break;
  576 
  577         default:
  578                 panic("%s: unable to initialize board RISC chip",
  579                       sc->sc_dev.dv_xname);
  580         }
  581 
  582 
  583         /*
  584          * fill in the prototype scsi_link.
  585          */
  586         sc->sc_link.adapter_softc = sc;
  587         sc->sc_link.adapter_target = sc->chip_scsi_id;
  588         sc->sc_link.adapter = &adv_switch;
  589         sc->sc_link.device = &adv_dev;
  590         sc->sc_link.openings = 4;
  591         sc->sc_link.adapter_buswidth = 7;
  592 
  593 
  594         TAILQ_INIT(&sc->sc_free_ccb);
  595         TAILQ_INIT(&sc->sc_waiting_ccb);
  596         LIST_INIT(&sc->sc_queue);
  597 
  598 
  599         /*
  600          * Allocate the Control Blocks.
  601          */
  602         error = adv_alloc_ccbs(sc);
  603         if (error)
  604                 return; /* (error) */ ;
  605 
  606         /*
  607          * Create and initialize the Control Blocks.
  608          */
  609         i = adv_create_ccbs(sc, sc->sc_control->ccbs, ADV_MAX_CCB);
  610         if (i == 0) {
  611                 printf("%s: unable to create control blocks\n",
  612                        sc->sc_dev.dv_xname);
  613                 return; /* (ENOMEM) */ ;
  614         } else if (i != ADV_MAX_CCB) {
  615                 printf("%s: WARNING: only %d of %d control blocks created\n",
  616                        sc->sc_dev.dv_xname, i, ADV_MAX_CCB);
  617         }
  618 
  619         bzero(&saa, sizeof(saa));
  620         saa.saa_sc_link = &sc->sc_link;
  621         config_found(&sc->sc_dev, &saa, scsiprint);
  622 }
  623 
  624 
  625 static void
  626 advminphys(bp)
  627         struct buf     *bp;
  628 {
  629 
  630         if (bp->b_bcount > ((ASC_MAX_SG_LIST - 1) * PAGE_SIZE))
  631                 bp->b_bcount = ((ASC_MAX_SG_LIST - 1) * PAGE_SIZE);
  632         minphys(bp);
  633 }
  634 
  635 
  636 /*
  637  * start a scsi operation given the command and the data address.  Also needs
  638  * the unit, target and lu.
  639  */
  640 static int
  641 adv_scsi_cmd(xs)
  642         struct scsi_xfer *xs;
  643 {
  644         struct scsi_link *sc_link = xs->sc_link;
  645         ASC_SOFTC      *sc = sc_link->adapter_softc;
  646         bus_dma_tag_t   dmat = sc->sc_dmat;
  647         ADV_CCB        *ccb;
  648         int             s, flags, error, nsegs;
  649         int             fromqueue = 1, dontqueue = 0;
  650 
  651 
  652         s = splbio();           /* protect the queue */
  653 
  654         /*
  655          * If we're running the queue from adv_done(), we've been
  656          * called with the first queue entry as our argument.
  657          */
  658         if (xs == LIST_FIRST(&sc->sc_queue)) {
  659                 xs = adv_dequeue(sc);
  660                 fromqueue = 1;
  661         } else {
  662 
  663                 /* Polled requests can't be queued for later. */
  664                 dontqueue = xs->flags & SCSI_POLL;
  665 
  666                 /*
  667                  * If there are jobs in the queue, run them first.
  668                  */
  669                 if (!LIST_EMPTY(&sc->sc_queue)) {
  670                         /*
  671                          * If we can't queue, we have to abort, since
  672                          * we have to preserve order.
  673                          */
  674                         if (dontqueue) {
  675                                 splx(s);
  676                                 return (TRY_AGAIN_LATER);
  677                         }
  678                         /*
  679                          * Swap with the first queue entry.
  680                          */
  681                         adv_enqueue(sc, xs, 0);
  682                         xs = adv_dequeue(sc);
  683                         fromqueue = 1;
  684                 }
  685         }
  686 
  687 
  688         /*
  689          * get a ccb to use. If the transfer
  690          * is from a buf (possibly from interrupt time)
  691          * then we can't allow it to sleep
  692          */
  693 
  694         flags = xs->flags;
  695         if ((ccb = adv_get_ccb(sc, flags)) == NULL) {
  696                 /*
  697                  * If we can't queue, we lose.
  698                  */
  699                 if (dontqueue) {
  700                         splx(s);
  701                         return (TRY_AGAIN_LATER);
  702                 }
  703                 /*
  704                  * Stuff ourselves into the queue, in front
  705                  * if we came off in the first place.
  706                  */
  707                 adv_enqueue(sc, xs, fromqueue);
  708                 splx(s);
  709                 return (SUCCESSFULLY_QUEUED);
  710         }
  711         splx(s);                /* done playing with the queue */
  712 
  713         ccb->xs = xs;
  714         ccb->timeout = xs->timeout;
  715 
  716         /*
  717          * Build up the request
  718          */
  719         memset(&ccb->scsiq, 0, sizeof(ASC_SCSI_Q));
  720 
  721         ccb->scsiq.q2.ccb_ptr = (ulong) ccb;
  722 
  723         ccb->scsiq.cdbptr = &xs->cmd->opcode;
  724         ccb->scsiq.q2.cdb_len = xs->cmdlen;
  725         ccb->scsiq.q1.target_id = ASC_TID_TO_TARGET_ID(sc_link->target);
  726         ccb->scsiq.q1.target_lun = sc_link->lun;
  727         ccb->scsiq.q2.target_ix = ASC_TIDLUN_TO_IX(sc_link->target,
  728                                                    sc_link->lun);
  729         ccb->scsiq.q1.sense_addr = sc->sc_dmamap_control->dm_segs[0].ds_addr +
  730                 ADV_CCB_OFF(ccb) + offsetof(struct adv_ccb, scsi_sense);
  731         ccb->scsiq.q1.sense_len = sizeof(struct scsi_sense_data);
  732 
  733         /*
  734          * If  there  are  any  outstanding  requests  for  the  current target,
  735          * then  every  255th request  send an  ORDERED request.  This heuristic
  736          * tries  to  retain  the  benefit  of request  sorting while preventing
  737          * request starvation. 255 is the max number of tags or pending commands
  738          * a device may have outstanding.
  739          */
  740         sc->reqcnt[sc_link->target]++;
  741         if ((sc->reqcnt[sc_link->target] > 0) &&
  742             (sc->reqcnt[sc_link->target] % 255) == 0) {
  743                 ccb->scsiq.q2.tag_code = M2_QTAG_MSG_ORDERED;
  744         } else {
  745                 ccb->scsiq.q2.tag_code = M2_QTAG_MSG_SIMPLE;
  746         }
  747 
  748 
  749         if (xs->datalen) {
  750                 /*
  751                  * Map the DMA transfer.
  752                  */
  753 #ifdef TFS
  754                 if (flags & SCSI_DATA_UIO) {
  755                         error = bus_dmamap_load_uio(dmat,
  756                                   ccb->dmamap_xfer, (struct uio *) xs->data,
  757                                                     (flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
  758                 } else
  759 #endif                          /* TFS */
  760                 {
  761                         error = bus_dmamap_load(dmat,
  762                               ccb->dmamap_xfer, xs->data, xs->datalen, NULL,
  763                                                 (flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
  764                 }
  765 
  766                 if (error) {
  767                         if (error == EFBIG) {
  768                                 printf("%s: adv_scsi_cmd, more than %d dma"
  769                                        " segments\n",
  770                                        sc->sc_dev.dv_xname, ASC_MAX_SG_LIST);
  771                         } else {
  772                                 printf("%s: adv_scsi_cmd, error %d loading"
  773                                        " dma map\n",
  774                                        sc->sc_dev.dv_xname, error);
  775                         }
  776 
  777                         xs->error = XS_DRIVER_STUFFUP;
  778                         adv_free_ccb(sc, ccb);
  779                         return (COMPLETE);
  780                 }
  781                 bus_dmamap_sync(dmat, ccb->dmamap_xfer,
  782                     0, ccb->dmamap_xfer->dm_mapsize,
  783                     ((flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
  784                         BUS_DMASYNC_PREWRITE));
  785 
  786 
  787                 memset(&ccb->sghead, 0, sizeof(ASC_SG_HEAD));
  788 
  789                 for (nsegs = 0; nsegs < ccb->dmamap_xfer->dm_nsegs; nsegs++) {
  790 
  791                         ccb->sghead.sg_list[nsegs].addr =
  792                                 ccb->dmamap_xfer->dm_segs[nsegs].ds_addr;
  793                         ccb->sghead.sg_list[nsegs].bytes =
  794                                 ccb->dmamap_xfer->dm_segs[nsegs].ds_len;
  795                 }
  796 
  797                 ccb->sghead.entry_cnt = ccb->scsiq.q1.sg_queue_cnt =
  798                         ccb->dmamap_xfer->dm_nsegs;
  799 
  800                 ccb->scsiq.q1.cntl |= ASC_QC_SG_HEAD;
  801                 ccb->scsiq.sg_head = &ccb->sghead;
  802                 ccb->scsiq.q1.data_addr = 0;
  803                 ccb->scsiq.q1.data_cnt = 0;
  804         } else {
  805                 /*
  806                  * No data xfer, use non S/G values.
  807                  */
  808                 ccb->scsiq.q1.data_addr = 0;
  809                 ccb->scsiq.q1.data_cnt = 0;
  810         }
  811 
  812 #ifdef ASC_DEBUG
  813         printf("id = %d, lun = %d, cmd = %d, ccb = 0x%lX \n",
  814                         sc_link->scsipi_scsi.target,
  815                         sc_link->scsipi_scsi.lun, xs->cmd->opcode,
  816                         (unsigned long)ccb);
  817 #endif
  818         s = splbio();
  819         adv_queue_ccb(sc, ccb);
  820         splx(s);
  821 
  822         /*
  823          * Usually return SUCCESSFULLY QUEUED
  824          */
  825         if ((flags & SCSI_POLL) == 0)
  826                 return (SUCCESSFULLY_QUEUED);
  827 
  828         /*
  829          * If we can't use interrupts, poll on completion
  830          */
  831         if (adv_poll(sc, xs, ccb->timeout)) {
  832                 adv_timeout(ccb);
  833                 if (adv_poll(sc, xs, ccb->timeout))
  834                         adv_timeout(ccb);
  835         }
  836         return (COMPLETE);
  837 }
  838 
  839 
  840 int
  841 adv_intr(arg)
  842         void           *arg;
  843 {
  844         ASC_SOFTC      *sc = arg;
  845         struct scsi_xfer *xs;
  846 
  847 #ifdef ASC_DEBUG
  848         int int_pend = FALSE;
  849 
  850         if(ASC_IS_INT_PENDING(sc->sc_iot, sc->sc_ioh))
  851         {
  852                 int_pend = TRUE;
  853                 printf("ISR - ");
  854         }
  855 #endif
  856         AscISR(sc);
  857 #ifdef ASC_DEBUG
  858         if(int_pend)
  859                 printf("\n");
  860 #endif
  861 
  862         /*
  863          * If there are queue entries in the software queue, try to
  864          * run the first one.  We should be more or less guaranteed
  865          * to succeed, since we just freed a CCB.
  866          *
  867          * NOTE: adv_scsi_cmd() relies on our calling it with
  868          * the first entry in the queue.
  869          */
  870         if ((xs = LIST_FIRST(&sc->sc_queue)) != NULL)
  871                 (void) adv_scsi_cmd(xs);
  872 
  873         return (1);
  874 }
  875 
  876 
  877 /*
  878  * Poll a particular unit, looking for a particular xs
  879  */
  880 static int
  881 adv_poll(sc, xs, count)
  882         ASC_SOFTC      *sc;
  883         struct scsi_xfer *xs;
  884         int             count;
  885 {
  886 
  887         /* timeouts are in msec, so we loop in 1000 usec cycles */
  888         while (count) {
  889                 adv_intr(sc);
  890                 if (xs->flags & ITSDONE)
  891                         return (0);
  892                 delay(1000);    /* only happens in boot so ok */
  893                 count--;
  894         }
  895         return (1);
  896 }
  897 
  898 
  899 static void
  900 adv_timeout(arg)
  901         void           *arg;
  902 {
  903         ADV_CCB        *ccb = arg;
  904         struct scsi_xfer *xs = ccb->xs;
  905         struct scsi_link *sc_link = xs->sc_link;
  906         ASC_SOFTC      *sc = sc_link->adapter_softc;
  907         int             s;
  908 
  909         sc_print_addr(sc_link);
  910         printf("timed out");
  911 
  912         s = splbio();
  913 
  914         /*
  915          * If it has been through before, then a previous abort has failed,
  916          * don't try abort again, reset the bus instead.
  917          */
  918         if (ccb->flags & CCB_ABORT) {
  919                 /* abort timed out */
  920                 printf(" AGAIN. Resetting Bus\n");
  921                 /* Lets try resetting the bus! */
  922                 if (AscResetBus(sc) == ASC_ERROR) {
  923                         ccb->timeout = sc->scsi_reset_wait;
  924                         adv_queue_ccb(sc, ccb);
  925                 }
  926         } else {
  927                 /* abort the operation that has timed out */
  928                 printf("\n");
  929                 AscAbortCCB(sc, (u_int32_t) ccb);
  930                 ccb->xs->error = XS_TIMEOUT;
  931                 ccb->timeout = ADV_ABORT_TIMEOUT;
  932                 ccb->flags |= CCB_ABORT;
  933                 adv_queue_ccb(sc, ccb);
  934         }
  935 
  936         splx(s);
  937 }
  938 
  939 
  940 static void
  941 adv_watchdog(arg)
  942         void           *arg;
  943 {
  944         ADV_CCB        *ccb = arg;
  945         struct scsi_xfer *xs = ccb->xs;
  946         struct scsi_link *sc_link = xs->sc_link;
  947         ASC_SOFTC      *sc = sc_link->adapter_softc;
  948         int             s;
  949 
  950         s = splbio();
  951 
  952         ccb->flags &= ~CCB_WATCHDOG;
  953         adv_start_ccbs(sc);
  954 
  955         splx(s);
  956 }
  957 
  958 
  959 /******************************************************************************/
  960 /*                  NARROW and WIDE boards Interrupt callbacks                */
  961 /******************************************************************************/
  962 
  963 
  964 /*
  965  * adv_narrow_isr_callback() - Second Level Interrupt Handler called by AscISR()
  966  *
  967  * Interrupt callback function for the Narrow SCSI Asc Library.
  968  */
  969 static void
  970 adv_narrow_isr_callback(sc, qdonep)
  971         ASC_SOFTC      *sc;
  972         ASC_QDONE_INFO *qdonep;
  973 {
  974         bus_dma_tag_t   dmat = sc->sc_dmat;
  975         ADV_CCB        *ccb = (ADV_CCB *) qdonep->d2.ccb_ptr;
  976         struct scsi_xfer *xs = ccb->xs;
  977         struct scsi_sense_data *s1, *s2;
  978 
  979 
  980 #ifdef ASC_DEBUG
  981         printf(" - ccb=0x%lx, id=%d, lun=%d, cmd=%d, ",
  982                         (unsigned long)ccb,
  983                         xs->sc_link->scsipi_scsi.target,
  984                         xs->sc_link->scsipi_scsi.lun, xs->cmd->opcode);
  985 #endif
  986         timeout_del(&xs->stimeout);
  987 
  988         /*
  989          * If we were a data transfer, unload the map that described
  990          * the data buffer.
  991          */
  992         if (xs->datalen) {
  993                 bus_dmamap_sync(dmat, ccb->dmamap_xfer,
  994                     0, ccb->dmamap_xfer->dm_mapsize,
  995                     ((xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
  996                         BUS_DMASYNC_POSTWRITE));
  997                 bus_dmamap_unload(dmat, ccb->dmamap_xfer);
  998         }
  999         if ((ccb->flags & CCB_ALLOC) == 0) {
 1000                 printf("%s: exiting ccb not allocated!\n", sc->sc_dev.dv_xname);
 1001                 Debugger();
 1002                 return;
 1003         }
 1004         /*
 1005          * 'qdonep' contains the command's ending status.
 1006          */
 1007 #ifdef ASC_DEBUG
 1008         printf("d_s=%d, h_s=%d", qdonep->d3.done_stat, qdonep->d3.host_stat);
 1009 #endif
 1010         switch (qdonep->d3.done_stat) {
 1011         case ASC_QD_NO_ERROR:
 1012                 switch (qdonep->d3.host_stat) {
 1013                 case ASC_QHSTA_NO_ERROR:
 1014                         xs->error = XS_NOERROR;
 1015                         xs->resid = 0;
 1016                         break;
 1017 
 1018                 default:
 1019                         /* QHSTA error occurred */
 1020                         xs->error = XS_DRIVER_STUFFUP;
 1021                         break;
 1022                 }
 1023 
 1024                 /*
 1025                  * If an INQUIRY command completed successfully, then call
 1026                  * the AscInquiryHandling() function to patch bugged boards.
 1027                  */
 1028                 if ((xs->cmd->opcode == SCSICMD_Inquiry) &&
 1029                     (xs->sc_link->lun == 0) &&
 1030                     (xs->datalen - qdonep->remain_bytes) >= 8) {
 1031                         AscInquiryHandling(sc,
 1032                                       xs->sc_link->target & 0x7,
 1033                                            (ASC_SCSI_INQUIRY *) xs->data);
 1034                 }
 1035                 break;
 1036 
 1037         case ASC_QD_WITH_ERROR:
 1038                 switch (qdonep->d3.host_stat) {
 1039                 case ASC_QHSTA_NO_ERROR:
 1040                         if (qdonep->d3.scsi_stat == SS_CHK_CONDITION) {
 1041                                 s1 = &ccb->scsi_sense;
 1042                                 s2 = &xs->sense;
 1043                                 *s2 = *s1;
 1044                                 xs->error = XS_SENSE;
 1045                         } else {
 1046                                 xs->error = XS_DRIVER_STUFFUP;
 1047                         }
 1048                         break;
 1049 
 1050                 default:
 1051                         /* QHSTA error occurred */
 1052                         xs->error = XS_DRIVER_STUFFUP;
 1053                         break;
 1054                 }
 1055                 break;
 1056 
 1057         case ASC_QD_ABORTED_BY_HOST:
 1058         default:
 1059                 xs->error = XS_DRIVER_STUFFUP;
 1060                 break;
 1061         }
 1062 
 1063 
 1064         adv_free_ccb(sc, ccb);
 1065         xs->flags |= ITSDONE;
 1066         scsi_done(xs);
 1067 }

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