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

Cache object: 3c77b1eb44d72362408fb6a7a31021cb


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