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/ic/uha.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: uha.c,v 1.42 2008/04/28 20:23:51 martin Exp $  */
    2 
    3 /*-
    4  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
    9  * Simulation Facility, NASA Ames Research Center.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   30  * POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 /*
   34  * Ported for use with the UltraStor 14f by Gary Close (gclose@wvnvms.wvnet.edu)
   35  * Slight fixes to timeouts to run with the 34F
   36  * Thanks to Julian Elischer for advice and help with this port.
   37  *
   38  * Originally written by Julian Elischer (julian@tfs.com)
   39  * for TRW Financial Systems for use under the MACH(2.5) operating system.
   40  *
   41  * TRW Financial Systems, in accordance with their agreement with Carnegie
   42  * Mellon University, makes this software available to CMU to distribute
   43  * or use in any manner that they see fit as long as this message is kept with
   44  * the software. For this reason TFS also grants any other persons or
   45  * organisations permission to use or modify this software.
   46  *
   47  * TFS supplies this software to be publicly redistributed
   48  * on the understanding that TFS is not responsible for the correct
   49  * functioning of this software in any circumstances.
   50  *
   51  * commenced: Sun Sep 27 18:14:01 PDT 1992
   52  * slight mod to make work with 34F as well: Wed Jun  2 18:05:48 WST 1993
   53  */
   54 
   55 #include <sys/cdefs.h>
   56 __KERNEL_RCSID(0, "$NetBSD: uha.c,v 1.42 2008/04/28 20:23:51 martin Exp $");
   57 
   58 #undef UHADEBUG
   59 #ifdef DDB
   60 #define integrate
   61 #else
   62 #define integrate       static inline
   63 #endif
   64 
   65 #include <sys/param.h>
   66 #include <sys/systm.h>
   67 #include <sys/kernel.h>
   68 #include <sys/errno.h>
   69 #include <sys/ioctl.h>
   70 #include <sys/device.h>
   71 #include <sys/malloc.h>
   72 #include <sys/buf.h>
   73 #include <sys/proc.h>
   74 #include <sys/user.h>
   75 
   76 #include <uvm/uvm_extern.h>
   77 
   78 #include <sys/bus.h>
   79 #include <sys/intr.h>
   80 
   81 #include <dev/scsipi/scsi_all.h>
   82 #include <dev/scsipi/scsipi_all.h>
   83 #include <dev/scsipi/scsiconf.h>
   84 
   85 #include <dev/ic/uhareg.h>
   86 #include <dev/ic/uhavar.h>
   87 
   88 #ifndef DDB
   89 #define Debugger() panic("should call debugger here (uha.c)")
   90 #endif /* ! DDB */
   91 
   92 #define UHA_MAXXFER     ((UHA_NSEG - 1) << PGSHIFT)
   93 
   94 integrate void uha_reset_mscp(struct uha_softc *, struct uha_mscp *);
   95 void uha_free_mscp(struct uha_softc *, struct uha_mscp *);
   96 integrate int uha_init_mscp(struct uha_softc *, struct uha_mscp *);
   97 struct uha_mscp *uha_get_mscp(struct uha_softc *);
   98 void uhaminphys(struct buf *);
   99 void uha_scsipi_request(struct scsipi_channel *, scsipi_adapter_req_t, void *);
  100 int uha_create_mscps(struct uha_softc *, struct uha_mscp *, int);
  101 
  102 #define UHA_ABORT_TIMEOUT       2000    /* time to wait for abort (mSec) */
  103 
  104 /*
  105  * Attach all the sub-devices we can find
  106  */
  107 void
  108 uha_attach(sc, upd)
  109         struct uha_softc *sc;
  110         struct uha_probe_data *upd;
  111 {
  112         struct scsipi_adapter *adapt = &sc->sc_adapter;
  113         struct scsipi_channel *chan = &sc->sc_channel;
  114         bus_dma_segment_t seg;
  115         int i, error, rseg;
  116 
  117         TAILQ_INIT(&sc->sc_free_mscp);
  118 
  119         (sc->init)(sc);
  120 
  121         /*
  122          * Fill in the scsipi_adapter.
  123          */
  124         memset(adapt, 0, sizeof(*adapt));
  125         adapt->adapt_dev = &sc->sc_dev;
  126         adapt->adapt_nchannels = 1;
  127         /* adapt_openings initialized below */
  128         /* adapt_max_periph initialized below */
  129         adapt->adapt_request = uha_scsipi_request;
  130         adapt->adapt_minphys = uhaminphys;
  131 
  132         /*
  133          * Fill in the scsipi_channel.
  134          */
  135         memset(chan, 0, sizeof(*chan));
  136         chan->chan_adapter = adapt;
  137         chan->chan_bustype = &scsi_bustype;
  138         chan->chan_channel = 0;
  139         chan->chan_ntargets = 8;
  140         chan->chan_nluns = 8;
  141         chan->chan_id = upd->sc_scsi_dev;
  142 
  143 #define MSCPSIZE        (UHA_MSCP_MAX * sizeof(struct uha_mscp))
  144 
  145         /*
  146          * Allocate the MSCPs.
  147          */
  148         if ((error = bus_dmamem_alloc(sc->sc_dmat, MSCPSIZE,
  149             PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
  150                 aprint_error_dev(&sc->sc_dev, "unable to allocate mscps, error = %d\n",
  151                     error);
  152                 return;
  153         }
  154         if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
  155             MSCPSIZE, (void **)&sc->sc_mscps,
  156             BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
  157                 aprint_error_dev(&sc->sc_dev, "unable to map mscps, error = %d\n",
  158                     error);
  159                 return;
  160         }
  161 
  162         /*
  163          * Create and load the DMA map used for the mscps.
  164          */
  165         if ((error = bus_dmamap_create(sc->sc_dmat, MSCPSIZE,
  166             1, MSCPSIZE, 0, BUS_DMA_NOWAIT | sc->sc_dmaflags,
  167             &sc->sc_dmamap_mscp)) != 0) {
  168                 aprint_error_dev(&sc->sc_dev, "unable to create mscp DMA map, error = %d\n",
  169                     error);
  170                 return;
  171         }
  172         if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_mscp,
  173             sc->sc_mscps, MSCPSIZE, NULL, BUS_DMA_NOWAIT)) != 0) {
  174                 aprint_error_dev(&sc->sc_dev, "unable to load mscp DMA map, error = %d\n",
  175                     error);
  176                 return;
  177         }
  178 
  179 #undef MSCPSIZE
  180 
  181         /*
  182          * Initialize the mscps.
  183          */
  184         i = uha_create_mscps(sc, sc->sc_mscps, UHA_MSCP_MAX);
  185         if (i == 0) {
  186                 aprint_error_dev(&sc->sc_dev, "unable to create mscps\n");
  187                 return;
  188         } else if (i != UHA_MSCP_MAX) {
  189                 aprint_error_dev(&sc->sc_dev, "WARNING: only %d of %d mscps created\n",
  190                     i, UHA_MSCP_MAX);
  191         }
  192 
  193         adapt->adapt_openings = i;
  194         adapt->adapt_max_periph = adapt->adapt_openings;
  195 
  196         /*
  197          * ask the adapter what subunits are present
  198          */
  199         config_found(&sc->sc_dev, &sc->sc_channel, scsiprint);
  200 }
  201 
  202 integrate void
  203 uha_reset_mscp(struct uha_softc *sc, struct uha_mscp *mscp)
  204 {
  205 
  206         mscp->flags = 0;
  207 }
  208 
  209 /*
  210  * A mscp (and hence a mbx-out) is put onto the free list.
  211  */
  212 void
  213 uha_free_mscp(sc, mscp)
  214         struct uha_softc *sc;
  215         struct uha_mscp *mscp;
  216 {
  217         int s;
  218 
  219         s = splbio();
  220         uha_reset_mscp(sc, mscp);
  221         TAILQ_INSERT_HEAD(&sc->sc_free_mscp, mscp, chain);
  222         splx(s);
  223 }
  224 
  225 integrate int
  226 uha_init_mscp(sc, mscp)
  227         struct uha_softc *sc;
  228         struct uha_mscp *mscp;
  229 {
  230         bus_dma_tag_t dmat = sc->sc_dmat;
  231         int hashnum, error;
  232 
  233         /*
  234          * Create the DMA map for this MSCP.
  235          */
  236         error = bus_dmamap_create(dmat, UHA_MAXXFER, UHA_NSEG, UHA_MAXXFER,
  237             0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW | sc->sc_dmaflags,
  238             &mscp->dmamap_xfer);
  239         if (error) {
  240                 aprint_error_dev(&sc->sc_dev, "can't create mscp DMA map, error = %d\n",
  241                     error);
  242                 return (error);
  243         }
  244 
  245         /*
  246          * put in the phystokv hash table
  247          * Never gets taken out.
  248          */
  249         mscp->hashkey = sc->sc_dmamap_mscp->dm_segs[0].ds_addr +
  250             UHA_MSCP_OFF(mscp);
  251         hashnum = MSCP_HASH(mscp->hashkey);
  252         mscp->nexthash = sc->sc_mscphash[hashnum];
  253         sc->sc_mscphash[hashnum] = mscp;
  254         uha_reset_mscp(sc, mscp);
  255         return (0);
  256 }
  257 
  258 /*
  259  * Create a set of MSCPs and add them to the free list.
  260  */
  261 int
  262 uha_create_mscps(sc, mscpstore, count)
  263         struct uha_softc *sc;
  264         struct uha_mscp *mscpstore;
  265         int count;
  266 {
  267         struct uha_mscp *mscp;
  268         int i, error;
  269 
  270         memset(mscpstore, 0, sizeof(struct uha_mscp) * count);
  271         for (i = 0; i < count; i++) {
  272                 mscp = &mscpstore[i];
  273                 if ((error = uha_init_mscp(sc, mscp)) != 0) {
  274                         aprint_error_dev(&sc->sc_dev, "unable to initialize mscp, error = %d\n",
  275                             error);
  276                         goto out;
  277                 }
  278                 TAILQ_INSERT_TAIL(&sc->sc_free_mscp, mscp, chain);
  279         }
  280  out:
  281         return (i);
  282 }
  283 
  284 /*
  285  * Get a free mscp
  286  *
  287  * If there are none, see if we can allocate a new one.  If so, put it in the
  288  * hash table too otherwise either return an error or sleep.
  289  */
  290 struct uha_mscp *
  291 uha_get_mscp(sc)
  292         struct uha_softc *sc;
  293 {
  294         struct uha_mscp *mscp;
  295         int s;
  296 
  297         s = splbio();
  298         mscp = TAILQ_FIRST(&sc->sc_free_mscp);
  299         if (mscp != NULL) {
  300                 TAILQ_REMOVE(&sc->sc_free_mscp, mscp, chain);
  301                 mscp->flags |= MSCP_ALLOC;
  302         }
  303         splx(s);
  304         return (mscp);
  305 }
  306 
  307 /*
  308  * given a physical address, find the mscp that it corresponds to.
  309  */
  310 struct uha_mscp *
  311 uha_mscp_phys_kv(sc, mscp_phys)
  312         struct uha_softc *sc;
  313         u_long mscp_phys;
  314 {
  315         int hashnum = MSCP_HASH(mscp_phys);
  316         struct uha_mscp *mscp = sc->sc_mscphash[hashnum];
  317 
  318         while (mscp) {
  319                 if (mscp->hashkey == mscp_phys)
  320                         break;
  321                 mscp = mscp->nexthash;
  322         }
  323         return (mscp);
  324 }
  325 
  326 /*
  327  * We have a mscp which has been processed by the adaptor, now we look to see
  328  * how the operation went.
  329  */
  330 void
  331 uha_done(sc, mscp)
  332         struct uha_softc *sc;
  333         struct uha_mscp *mscp;
  334 {
  335         bus_dma_tag_t dmat = sc->sc_dmat;
  336         struct scsi_sense_data *s1, *s2;
  337         struct scsipi_xfer *xs = mscp->xs;
  338 
  339         SC_DEBUG(xs->xs_periph, SCSIPI_DB2, ("uha_done\n"));
  340 
  341         bus_dmamap_sync(dmat, sc->sc_dmamap_mscp,
  342             UHA_MSCP_OFF(mscp), sizeof(struct uha_mscp),
  343             BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
  344 
  345         /*
  346          * If we were a data transfer, unload the map that described
  347          * the data buffer.
  348          */
  349         if (xs->datalen) {
  350                 bus_dmamap_sync(dmat, mscp->dmamap_xfer, 0,
  351                     mscp->dmamap_xfer->dm_mapsize,
  352                     (xs->xs_control & XS_CTL_DATA_IN) ? BUS_DMASYNC_POSTREAD :
  353                     BUS_DMASYNC_POSTWRITE);
  354                 bus_dmamap_unload(dmat, mscp->dmamap_xfer);
  355         }
  356 
  357         /*
  358          * Otherwise, put the results of the operation
  359          * into the xfer and call whoever started it
  360          */
  361         if ((mscp->flags & MSCP_ALLOC) == 0) {
  362                 aprint_error_dev(&sc->sc_dev, "exiting ccb not allocated!\n");
  363                 Debugger();
  364                 return;
  365         }
  366         if (xs->error == XS_NOERROR) {
  367                 if (mscp->host_stat != UHA_NO_ERR) {
  368                         switch (mscp->host_stat) {
  369                         case UHA_SBUS_TIMEOUT:          /* No response */
  370                                 xs->error = XS_SELTIMEOUT;
  371                                 break;
  372                         default:        /* Other scsi protocol messes */
  373                                 aprint_error_dev(&sc->sc_dev, "host_stat %x\n",
  374                                     mscp->host_stat);
  375                                 xs->error = XS_DRIVER_STUFFUP;
  376                         }
  377                 } else if (mscp->target_stat != SCSI_OK) {
  378                         switch (mscp->target_stat) {
  379                         case SCSI_CHECK:
  380                                 s1 = &mscp->mscp_sense;
  381                                 s2 = &xs->sense.scsi_sense;
  382                                 *s2 = *s1;
  383                                 xs->error = XS_SENSE;
  384                                 break;
  385                         case SCSI_BUSY:
  386                                 xs->error = XS_BUSY;
  387                                 break;
  388                         default:
  389                                 aprint_error_dev(&sc->sc_dev, "target_stat %x\n",
  390                                     mscp->target_stat);
  391                                 xs->error = XS_DRIVER_STUFFUP;
  392                         }
  393                 } else
  394                         xs->resid = 0;
  395         }
  396         uha_free_mscp(sc, mscp);
  397         scsipi_done(xs);
  398 }
  399 
  400 void
  401 uhaminphys(bp)
  402         struct buf *bp;
  403 {
  404 
  405         if (bp->b_bcount > UHA_MAXXFER)
  406                 bp->b_bcount = UHA_MAXXFER;
  407         minphys(bp);
  408 }
  409 
  410 /*
  411  * start a scsi operation given the command and the data address.  Also
  412  * needs the unit, target and lu.
  413  */
  414 
  415 void
  416 uha_scsipi_request(chan, req, arg)
  417         struct scsipi_channel *chan;
  418         scsipi_adapter_req_t req;
  419         void *arg;
  420 {
  421         struct scsipi_xfer *xs;
  422         struct scsipi_periph *periph;
  423         struct uha_softc *sc = (void *)chan->chan_adapter->adapt_dev;
  424         bus_dma_tag_t dmat = sc->sc_dmat;
  425         struct uha_mscp *mscp;
  426         int error, seg, flags, s;
  427 
  428 
  429         switch (req) {
  430         case ADAPTER_REQ_RUN_XFER:
  431                 xs = arg;
  432                 periph = xs->xs_periph;
  433                 flags = xs->xs_control;
  434 
  435                 SC_DEBUG(periph, SCSIPI_DB2, ("uha_scsipi_request\n"));
  436 
  437                 /* Get an MSCP to use. */
  438                 mscp = uha_get_mscp(sc);
  439 #ifdef DIAGNOSTIC
  440                 /*
  441                  * This should never happen as we track the resources
  442                  * in the mid-layer.
  443                  */
  444                 if (mscp == NULL) {
  445                         scsipi_printaddr(periph);
  446                         printf("unable to allocate mscp\n");
  447                         panic("uha_scsipi_request");
  448                 }
  449 #endif
  450 
  451                 mscp->xs = xs;
  452                 mscp->timeout = xs->timeout;
  453 
  454                 /*
  455                  * Put all the arguments for the xfer in the mscp
  456                  */
  457                 if (flags & XS_CTL_RESET) {
  458                         mscp->opcode = UHA_SDR;
  459                         mscp->ca = 0x01;
  460                 } else {
  461                         if (xs->cmdlen > sizeof(mscp->scsi_cmd)) {
  462                                 aprint_error_dev(&sc->sc_dev, "cmdlen %d too large for MSCP\n",
  463                                     xs->cmdlen);
  464                                 xs->error = XS_DRIVER_STUFFUP;
  465                                 goto out_bad;
  466                         }
  467                         mscp->opcode = UHA_TSP;
  468                         /* XXX Not for tapes. */
  469                         mscp->ca = 0x01;
  470                         memcpy(&mscp->scsi_cmd, xs->cmd, mscp->scsi_cmd_length);
  471                 }
  472                 mscp->xdir = UHA_SDET;
  473                 mscp->dcn = 0x00;
  474                 mscp->chan = 0x00;
  475                 mscp->target = periph->periph_target;
  476                 mscp->lun = periph->periph_lun;
  477                 mscp->scsi_cmd_length = xs->cmdlen;
  478                 mscp->sense_ptr = sc->sc_dmamap_mscp->dm_segs[0].ds_addr +
  479                     UHA_MSCP_OFF(mscp) + offsetof(struct uha_mscp, mscp_sense);
  480                 mscp->req_sense_length = sizeof(mscp->mscp_sense);
  481                 mscp->host_stat = 0x00;
  482                 mscp->target_stat = 0x00;
  483 
  484                 if (xs->datalen) {
  485                         seg = 0;
  486 #ifdef  TFS
  487                         if (flags & SCSI_DATA_UIO) {
  488                                 error = bus_dmamap_load_uio(dmat,
  489                                     mscp->dmamap_xfer, (struct uio *)xs->data,
  490                                     ((flags & XS_CTL_NOSLEEP) ? BUS_DMA_NOWAIT :
  491                                      BUS_DMA_WAITOK) | BUS_DMA_STREAMING |
  492                                      ((flags & XS_CTL_DATA_IN) ? BUS_DMA_READ :
  493                                       BUS_DMA_WRITE));
  494                         } else
  495 #endif /*TFS */
  496                         {
  497                                 error = bus_dmamap_load(dmat,
  498                                     mscp->dmamap_xfer, xs->data, xs->datalen,
  499                                     NULL,
  500                                     ((flags & XS_CTL_NOSLEEP) ? BUS_DMA_NOWAIT :
  501                                      BUS_DMA_WAITOK) | BUS_DMA_STREAMING |
  502                                      ((flags & XS_CTL_DATA_IN) ? BUS_DMA_READ :
  503                                       BUS_DMA_WRITE));
  504                         }
  505 
  506                         switch (error) {
  507                         case 0:
  508                                 break;
  509 
  510                         case ENOMEM:
  511                         case EAGAIN:
  512                                 xs->error = XS_RESOURCE_SHORTAGE;
  513                                 goto out_bad;
  514 
  515                         default:
  516                                 xs->error = XS_DRIVER_STUFFUP;
  517                                 aprint_error_dev(&sc->sc_dev, "error %d loading DMA map\n",
  518                                     error);
  519  out_bad:
  520                                 uha_free_mscp(sc, mscp);
  521                                 scsipi_done(xs);
  522                                 return;
  523                         }
  524 
  525                         bus_dmamap_sync(dmat, mscp->dmamap_xfer, 0,
  526                             mscp->dmamap_xfer->dm_mapsize,
  527                             (flags & XS_CTL_DATA_IN) ? BUS_DMASYNC_PREREAD :
  528                             BUS_DMASYNC_PREWRITE);
  529 
  530                         /*
  531                          * Load the hardware scatter/gather map with the
  532                          * contents of the DMA map.
  533                          */
  534                         for (seg = 0;
  535                              seg < mscp->dmamap_xfer->dm_nsegs; seg++) {
  536                                 mscp->uha_dma[seg].seg_addr =
  537                                     mscp->dmamap_xfer->dm_segs[seg].ds_addr;
  538                                 mscp->uha_dma[seg].seg_len =
  539                                     mscp->dmamap_xfer->dm_segs[seg].ds_len;
  540                         }
  541 
  542                         mscp->data_addr =
  543                             sc->sc_dmamap_mscp->dm_segs[0].ds_addr +
  544                             UHA_MSCP_OFF(mscp) + offsetof(struct uha_mscp,
  545                             uha_dma);
  546                         mscp->data_length = xs->datalen;
  547                         mscp->sgth = 0x01;
  548                         mscp->sg_num = seg;
  549                 } else {                /* No data xfer, use non S/G values */
  550                         mscp->data_addr = (physaddr)0;
  551                         mscp->data_length = 0;
  552                         mscp->sgth = 0x00;
  553                         mscp->sg_num = 0;
  554                 }
  555                 mscp->link_id = 0;
  556                 mscp->link_addr = (physaddr)0;
  557 
  558                 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_mscp,
  559                     UHA_MSCP_OFF(mscp), sizeof(struct uha_mscp),
  560                     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  561 
  562                 s = splbio();
  563                 (sc->start_mbox)(sc, mscp);
  564                 splx(s);
  565 
  566                 if ((flags & XS_CTL_POLL) == 0)
  567                         return;
  568 
  569                 /*
  570                  * If we can't use interrupts, poll on completion
  571                  */
  572                 if ((sc->poll)(sc, xs, mscp->timeout)) {
  573                         uha_timeout(mscp);
  574                         if ((sc->poll)(sc, xs, mscp->timeout))
  575                                 uha_timeout(mscp);
  576                 }
  577                 return;
  578 
  579         case ADAPTER_REQ_GROW_RESOURCES:
  580                 /* XXX Not supported. */
  581                 return;
  582 
  583         case ADAPTER_REQ_SET_XFER_MODE:
  584                 /*
  585                  * We can't really do this (the UltraStor controllers
  586                  * have their own config).
  587                  *
  588                  * XXX How do we query the config?
  589                  */
  590                 return;
  591         }
  592 }
  593 void
  594 uha_timeout(arg)
  595         void *arg;
  596 {
  597         struct uha_mscp *mscp = arg;
  598         struct scsipi_xfer *xs = mscp->xs;
  599         struct scsipi_periph *periph = xs->xs_periph;
  600         struct uha_softc *sc =
  601             (void *)periph->periph_channel->chan_adapter->adapt_dev;
  602         int s;
  603 
  604         scsipi_printaddr(periph);
  605         printf("timed out");
  606 
  607         s = splbio();
  608 
  609         if (mscp->flags & MSCP_ABORT) {
  610                 /* abort timed out */
  611                 printf(" AGAIN\n");
  612                 /* XXX Must reset! */
  613         } else {
  614                 /* abort the operation that has timed out */
  615                 printf("\n");
  616                 mscp->xs->error = XS_TIMEOUT;
  617                 mscp->timeout = UHA_ABORT_TIMEOUT;
  618                 mscp->flags |= MSCP_ABORT;
  619                 (sc->start_mbox)(sc, mscp);
  620         }
  621 
  622         splx(s);
  623 }

Cache object: 6aa8224a1e9bab48673c6d59f08bc0db


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