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


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

FreeBSD/Linux Kernel Cross Reference
sys/i386/isa/bs/bshw_pdma.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 /*      $NecBSD: bshw_pdma.c,v 1.4 1997/10/31 17:43:39 honda Exp $      */
    2 /*      $NetBSD$        */
    3 /*
    4  * [NetBSD for NEC PC98 series]
    5  *  Copyright (c) 1994, 1995, 1996 NetBSD/pc98 porting staff.
    6  *  All rights reserved.
    7  * 
    8  *  Redistribution and use in source and binary forms, with or without
    9  *  modification, are permitted provided that the following conditions
   10  *  are met:
   11  *  1. Redistributions of source code must retain the above copyright
   12  *     notice, this list of conditions and the following disclaimer.
   13  *  2. Redistributions in binary form must reproduce the above copyright
   14  *     notice, this list of conditions and the following disclaimer in the
   15  *     documentation and/or other materials provided with the distribution.
   16  *  3. The name of the author may not be used to endorse or promote products
   17  *     derived from this software without specific prior written permission.
   18  * 
   19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   22  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
   23  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   25  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   27  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   28  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 /*
   32  * Copyright (c) 1994, 1995, 1996 Naofumi HONDA.  All rights reserved.
   33  */
   34 
   35 #define LC_SMIT_TIMEOUT 2       /* 2 sec: timeout for a fifo status ready */
   36 
   37 static BS_INLINE void bshw_lc_smit_start __P((struct bs_softc *, int, u_int));
   38 static int bshw_lc_smit_fstat __P((struct bs_softc *, int, int));
   39 static BS_INLINE void bshw_lc_smit_stop __P((struct bs_softc *));
   40 
   41 /*********************************************************
   42  * SM FIFO (GENERIC)
   43  *********************************************************/
   44 void
   45 bshw_smitabort(bsc)
   46         struct bs_softc *bsc;
   47 {
   48         if (bsc->sc_hw->hw_flags & BSHW_SMFIFO)
   49                 bshw_lc_smit_stop(bsc);
   50 
   51         bshw_set_count(bsc, 0);
   52         bsc->sc_flags &= ~BSSMITSTART;
   53 }
   54 
   55 void
   56 bs_smit_xfer_end(ti)
   57         struct targ_info *ti;
   58 {
   59         struct bs_softc *bsc = ti->ti_bsc;
   60         struct sc_p *sp = &bsc->sc_p;
   61         u_int count;
   62         u_char *s;
   63 
   64         bshw_lc_smit_stop(bsc);
   65         bsc->sc_flags &= ~BSSMITSTART;
   66 
   67         if (ti->ti_phase == DATAPHASE)
   68         {
   69                 count = bshw_get_count(bsc);
   70                 if (count < (u_int) sp->datalen)
   71                 {
   72                         sp->data += (sp->datalen - count);
   73                         sp->datalen = count;
   74                         /* XXX:
   75                          * strict double checks!
   76                          * target   => wd33c93c transfer counts
   77                          * wd33c93c => memory   transfer counts
   78                          */
   79                         if ((bsc->sc_dmadir & BSHW_READ) &&
   80                              count != bsc->sm_tdatalen)
   81                         {
   82                                 s = "read count miss";
   83                                 goto bad;
   84                         }
   85                         return;
   86                 }
   87                 else if (count == (u_int) sp->datalen)
   88                 {
   89                         return;
   90                 }
   91 
   92                 s = "strange count";
   93         }
   94         else
   95                 s = "extra smit interrupt";
   96 
   97 bad:
   98         bs_printf(ti, "smit_xfer_end", s);
   99         ti->ti_error |= BSDMAABNORMAL;
  100 }
  101 
  102 /*********************************************************
  103  * LOGITEC's SMIT TRANSFER
  104  *********************************************************/
  105 
  106 #define BSHW_LC_FSET    0x36
  107 #define BSHW_LC_FCTRL   0x44
  108 #define FCTRL_EN        0x01
  109 #define FCTRL_WRITE     0x02
  110 
  111 #define SF_ABORT        0x08
  112 #define SF_RDY          0x10
  113 
  114 #define LC_FSZ          DEV_BSIZE
  115 #define LC_SFSZ         0x0c
  116 #define LC_REST         (LC_FSZ - LC_SFSZ)
  117 
  118 static BS_INLINE void
  119 bshw_lc_smit_stop(bsc)
  120         struct bs_softc *bsc;
  121 {
  122 
  123         write_wd33c93(bsc, BSHW_LC_FCTRL, 0);
  124         BUS_IOW(cmd_port, CMDP_DMER);
  125 }
  126 
  127 static BS_INLINE void
  128 bshw_lc_smit_start(bsc, count, direction)
  129         struct bs_softc *bsc;
  130         int count;
  131         u_int direction;
  132 {
  133         u_int8_t pval, val = read_wd33c93(bsc, BSHW_LC_FSET);
  134 
  135         bsc->sc_flags |= BSSMITSTART;
  136         bshw_set_count(bsc, count);
  137 
  138         pval = FCTRL_EN;
  139         if ((direction & BSHW_READ) == 0)
  140                 pval |= (val & 0xe0) | FCTRL_WRITE;
  141         write_wd33c93(bsc, BSHW_LC_FCTRL, pval);
  142         bshw_start_xfer(bsc);
  143 }
  144 
  145 static int
  146 bshw_lc_smit_fstat(bsc, wc, read)
  147         struct bs_softc *bsc;
  148         int wc, read;
  149 {
  150         u_int8_t stat;
  151 
  152 #define ALWAYS_ABORT
  153 #ifdef  ALWAYS_ABORT
  154         if (read == BSHW_READ)
  155         {
  156                 while (wc -- > 0)
  157                 {
  158                         BUS_IO_WEIGHT;
  159                         stat = BUS_IOR(cmd_port);
  160                         if (stat & SF_RDY)
  161                                 return 0;
  162                         if (stat & SF_ABORT)
  163                                 return EIO;
  164                 }
  165         }
  166         else
  167         {
  168 #endif  /* ALWAYS_ABORT */
  169                 while (wc -- > 0)
  170                 {
  171                         BUS_IO_WEIGHT;
  172                         stat = BUS_IOR(cmd_port);
  173                         if (stat & SF_ABORT)
  174                                 return EIO;
  175                         if (stat & SF_RDY)
  176                                 return 0;
  177                 }
  178 #ifdef  ALWAYS_ABORT
  179         }
  180 #endif  /* ALWAYS_ABORT */
  181 
  182         bs_poll_timeout(bsc, "bshw_lc_smit");
  183         return EIO;
  184 }
  185 
  186 void
  187 bs_lc_smit_xfer(ti, direction)
  188         struct targ_info *ti;
  189         u_int direction;
  190 {
  191         struct bs_softc *bsc = ti->ti_bsc;
  192         struct sc_p *sp = &bsc->sc_p;
  193         int datalen, count, wc = LC_SMIT_TIMEOUT * 1024 * 1024;
  194         u_int8_t *data;
  195 
  196         sp->bufp = NULL;
  197         sp->seglen = 0;
  198         data = sp->data;
  199         datalen = sp->datalen;
  200 
  201         bsc->sc_dmadir = direction;
  202         bshw_set_dma_trans(bsc, ti->ti_cfgflags);
  203         bshw_lc_smit_start(bsc, sp->datalen, direction);
  204 
  205         if (direction & BSHW_READ)
  206         {
  207                 do
  208                 {
  209                         if (bshw_lc_smit_fstat(bsc, wc, BSHW_READ))
  210                                 break;
  211 
  212                         count = (datalen > LC_FSZ ? LC_FSZ : datalen);
  213 #ifdef  __FreeBSD__
  214                         memcopy((u_int8_t *)ti->sm_offset, data, count);
  215 #else   /* NetBSD */
  216                         bus_space_read_region_4(bsc->sc_memt, bsc->sc_memh,
  217                                 ti->sm_offset, (u_int32_t *) data, count >> 2);
  218 #endif  /* NetBSD */
  219                         data += count;
  220                         datalen -= count;
  221                 }
  222                 while (datalen > 0);
  223 
  224                 bsc->sm_tdatalen = datalen;
  225         }
  226         else
  227         {
  228                 do
  229                 {
  230                         if (bshw_lc_smit_fstat(bsc, wc, BSHW_WRITE))
  231                                 break;
  232 
  233                         count = (datalen > LC_SFSZ ? LC_SFSZ : datalen);
  234 #ifdef  __FreeBSD__
  235                         memcopy(data, (u_int8_t *)ti->sm_offset, count);
  236 #else   /* NetBSD */
  237                         bus_space_write_region_4(bsc->sc_memt, bsc->sc_memh,
  238                                 ti->sm_offset, (u_int32_t *) data, count >> 2);
  239 #endif  /* NetBSD */
  240                         data += count;
  241                         datalen -= count;
  242 
  243                         if (bshw_lc_smit_fstat(bsc, wc, BSHW_WRITE))
  244                                 break;
  245 
  246                         count = (datalen > LC_REST ? LC_REST : datalen);
  247 #ifdef  __FreeBSD__
  248                         memcopy(data, (u_int8_t *)(ti->sm_offset + LC_SFSZ), count);
  249 #else   /* NetBSD */
  250                         bus_space_write_region_4(bsc->sc_memt, bsc->sc_memh,
  251                                                  ti->sm_offset + LC_SFSZ, 
  252                                                  (u_int32_t *) data, count >> 2);
  253 #endif  /* NetBSD */
  254                         data += count;
  255                         datalen -= count;
  256                 }
  257                 while (datalen > 0);
  258         }
  259 }

Cache object: 361b09c49d6fca2d8b6355afa8054881


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