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_dma.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: releng/5.1/sys/i386/isa/bs/bshw_dma.c 92765 2002-03-20 07:51:46Z alfred $ */
    2 /*      $NecBSD: bshw_dma.c,v 1.3 1997/07/26 06:03:16 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 /*********************************************************
   37  * static declare.
   38  *********************************************************/
   39 static void bshw_dmastart(struct bs_softc *);
   40 static void bshw_dmadone(struct bs_softc *);
   41 
   42 /**********************************************
   43  * UPPER INTERFACE FUNCS (all funcs exported)
   44  **********************************************/
   45 void
   46 bshw_dmaabort(bsc, ti)
   47         struct bs_softc *bsc;
   48         struct targ_info *ti;
   49 {
   50 
   51         bshw_dmadone(bsc);
   52         bsc->sc_p.seglen = 0;
   53         bshw_set_count(bsc, 0);
   54 
   55         if (ti == NULL)
   56         {
   57                 int i;
   58                 struct targ_info *tmpti;
   59 
   60                 for (i = 0; i < NTARGETS; i++)
   61                         if ((tmpti = bsc->sc_ti[i]) != NULL)
   62                                 tmpti->ti_scsp.seglen = 0;
   63         }
   64         else
   65                 ti->ti_scsp.seglen = 0;
   66 }
   67 
   68 /* DMA TRANSFER */
   69 void
   70 bs_dma_xfer(ti, direction)
   71         struct targ_info *ti;
   72         u_int direction;
   73 {
   74         vm_offset_t va, endva, phys, nphys;
   75         struct bs_softc *bsc = ti->ti_bsc;
   76         struct sc_p *sp = &bsc->sc_p;
   77 
   78         bsc->sc_dmadir = direction;
   79         bshw_set_dma_trans(bsc, ti->ti_cfgflags);
   80 
   81         if (sp->seglen == 0)
   82         {
   83                 phys = vtophys((vm_offset_t) sp->data);
   84                 if (phys >= RAM_END)
   85                 {
   86                         /* setup segaddr */
   87                         sp->segaddr = ti->bounce_phys;
   88                         /* setup seglen */
   89                         sp->seglen = sp->datalen;
   90                         if (sp->seglen > ti->bounce_size)
   91                                 sp->seglen = ti->bounce_size;
   92                         /* setup bufp */
   93                         sp->bufp = ti->bounce_addr;
   94                         if (bsc->sc_dmadir != BSHW_READ)
   95                                 bcopy(sp->data, sp->bufp, sp->seglen);
   96 #ifdef  BS_STATICS
   97                         bs_bounce_used[ti->ti_id]++;
   98 #endif  /* BS_STATICS */
   99                 }
  100                 else
  101                 {
  102                         /* setup segaddr */
  103                         sp->segaddr = (u_int8_t *) phys;
  104                         /* setup seglen */
  105                         endva = (vm_offset_t)round_page((unsigned long)(sp->data + sp->datalen));
  106                         for (va = (vm_offset_t) sp->data; ; phys = nphys)
  107                         {
  108                                 if ((va += BSHW_NBPG) >= endva)
  109                                 {
  110                                         sp->seglen = sp->datalen;
  111                                         break;
  112                                 }
  113 
  114                                 nphys = vtophys(va);
  115                                 if (phys + BSHW_NBPG != nphys || nphys >= RAM_END)
  116                                 {
  117                                         sp->seglen =
  118                                             (u_int8_t *) trunc_page(va) - sp->data;
  119                                         break;
  120                                 }
  121                         }
  122                         /* setup bufp */
  123                         sp->bufp = NULL;
  124                 }
  125         }
  126 
  127         bshw_dmastart(bsc);
  128         bshw_set_count(bsc, sp->seglen);
  129 }
  130 
  131 void
  132 bs_dma_xfer_end(ti)
  133         struct targ_info *ti;
  134 {
  135         struct bs_softc *bsc = ti->ti_bsc;
  136         struct sc_p *sp = &bsc->sc_p;
  137         u_int count, transbytes;
  138 
  139         bshw_dmadone(bsc);
  140         if (ti->ti_phase == DATAPHASE)
  141         {
  142                 count = bshw_get_count(bsc);
  143                 if (count < (u_int) sp->seglen)
  144                 {
  145                         transbytes = sp->seglen - count;
  146                         if (sp->bufp)
  147                         {
  148                                 if (bsc->sc_dmadir == BSHW_READ)
  149                                         bcopy(sp->bufp, sp->data, transbytes);
  150                                 sp->bufp += transbytes;
  151                         }
  152                         sp->seglen = count;
  153                         sp->segaddr += transbytes;
  154                         sp->data += transbytes;
  155                         sp->datalen -= transbytes;
  156                         return;
  157                 }
  158                 else if (count == (u_int) sp->seglen)
  159                 {
  160                         return;
  161                 }
  162 
  163                 bs_printf(ti, "xfer_end", "strange count");
  164                 printf("port data %x seglen %x\n", count, sp->seglen);
  165         }
  166         else
  167                 bs_printf(ti, "xfer_end", "extra dma interrupt");
  168 
  169         ti->ti_error |= BSDMAABNORMAL;
  170         sp->seglen = ti->ti_scsp.seglen = 0;    /* XXX */
  171 }
  172 
  173 /**********************************************
  174  * GENERIC DMA FUNCS
  175  **********************************************/
  176 static u_int8_t dmapageport[4] = { 0x27, 0x21, 0x23, 0x25 };
  177 
  178 /* common dma settings */
  179 #undef  DMA1_SMSK
  180 #define DMA1_SMSK       (0x15)
  181 #undef  DMA1_MODE
  182 #define DMA1_MODE       (0x17)
  183 #undef  DMA1_FFC
  184 #define DMA1_FFC        (0x19)
  185 #undef  DMA37SM_SET
  186 #define DMA37SM_SET     0x04
  187 #undef  DMA1_CHN
  188 #define DMA1_CHN(c)     (0x01 + ((c) << 2))
  189 
  190 static void
  191 bshw_dmastart(bsc)
  192         struct bs_softc *bsc;
  193 {
  194         int chan = bsc->sc_dmachan;
  195         int waport;
  196         u_int8_t *phys = bsc->sc_p.segaddr;
  197         u_int nbytes = bsc->sc_p.seglen;
  198 
  199         /*
  200          * Program one of DMA channels 0..3. These are
  201          * byte mode channels.
  202          */
  203         /* set dma channel mode, and reset address ff */
  204 #ifdef __FreeBSD__
  205         if (need_pre_dma_flush)
  206                 wbinvd();
  207 #else   /* NetBSD/pc98 */
  208         if (bsc->sc_dmadir & BSHW_READ)
  209                 cpu_cf_preRead(curcpu);
  210         else
  211                 cpu_cf_preWrite(curcpu);
  212 #endif
  213 
  214         if (bsc->sc_dmadir & BSHW_READ)
  215                 outb(DMA1_MODE, DMA37MD_SINGLE | DMA37MD_WRITE | chan);
  216         else
  217                 outb(DMA1_MODE, DMA37MD_SINGLE | DMA37MD_READ | chan);
  218         outb(DMA1_FFC, 0);
  219 
  220         /* send start address */
  221         waport = DMA1_CHN(chan);
  222         outb(waport, (u_int) phys);
  223         outb(waport, ((u_int) phys) >> 8);
  224         outb(dmapageport[chan], ((u_int) phys) >> 16);
  225 
  226         /* send count */
  227         outb(waport + 2, --nbytes);
  228         outb(waport + 2, nbytes >> 8);
  229 
  230         /* vendor unique hook */
  231         if (bsc->sc_hw->dma_start)
  232                 (*bsc->sc_hw->dma_start)(bsc);
  233 
  234         outb(DMA1_SMSK, chan);
  235         BUS_IOW(cmd_port, CMDP_DMES);
  236 
  237         bsc->sc_flags |= BSDMASTART;
  238 }
  239 
  240 static void
  241 bshw_dmadone(bsc)
  242         struct bs_softc *bsc;
  243 {
  244 
  245         outb(DMA1_SMSK, (bsc->sc_dmachan | DMA37SM_SET));
  246         BUS_IOW(cmd_port, CMDP_DMER);
  247 
  248         /* vendor unique hook */
  249         if (bsc->sc_hw->dma_stop)
  250                 (*bsc->sc_hw->dma_stop)(bsc);
  251 
  252 #ifdef __FreeBSD__
  253         if (need_post_dma_flush)
  254                 invd();
  255 #else
  256         if (bsc->sc_dmadir & BSHW_READ)
  257                 cpu_cf_postRead(curcpu);
  258         else
  259                 cpu_cf_postWrite(curcpu);
  260 #endif
  261 
  262         bsc->sc_flags &= (~BSDMASTART);
  263 }
  264 
  265 /**********************************************
  266  * VENDOR UNIQUE DMA FUNCS
  267  **********************************************/
  268 static int
  269 bshw_dma_init_texa(bsc)
  270         struct bs_softc *bsc;
  271 {
  272         u_int8_t regval;
  273 
  274         if ((regval = read_wd33c93(bsc, 0x37)) & 0x08)
  275                 return 0;
  276 
  277         write_wd33c93(bsc, 0x37, regval | 0x08);
  278         regval = read_wd33c93(bsc, 0x3f);
  279         write_wd33c93(bsc, 0x3f, regval | 0x08);
  280         return 1;
  281 }
  282 
  283 static int
  284 bshw_dma_init_sc98(bsc)
  285         struct bs_softc *bsc;
  286 {
  287 
  288         if (read_wd33c93(bsc, 0x37) & 0x08)
  289                 return 0;
  290 
  291         /* If your card is SC98 with bios ver 1.01 or 1.02 under no PCI */
  292         write_wd33c93(bsc, 0x37, 0x1a);
  293         write_wd33c93(bsc, 0x3f, 0x1a);
  294 #if     0
  295         /* only valid for IO */
  296         write_wd33c93(bsc, 0x40, 0xf4);
  297         write_wd33c93(bsc, 0x41, 0x9);
  298         write_wd33c93(bsc, 0x43, 0xff);
  299         write_wd33c93(bsc, 0x46, 0x4e);
  300 
  301         write_wd33c93(bsc, 0x48, 0xf4);
  302         write_wd33c93(bsc, 0x49, 0x9);
  303         write_wd33c93(bsc, 0x4b, 0xff);
  304         write_wd33c93(bsc, 0x4e, 0x4e);
  305 #endif
  306         return 1;
  307 }
  308 
  309 static void
  310 bshw_dma_start_sc98(bsc)
  311         struct bs_softc *bsc;
  312 {
  313 
  314         write_wd33c93(bsc, 0x73, 0x32);
  315         write_wd33c93(bsc, 0x74, 0x23);
  316 }
  317 
  318 static void
  319 bshw_dma_stop_sc98(bsc)
  320         struct bs_softc *bsc;
  321 {
  322 
  323         write_wd33c93(bsc, 0x73, 0x43);
  324         write_wd33c93(bsc, 0x74, 0x34);
  325 }
  326 
  327 static void
  328 bshw_dma_start_elecom(bsc)
  329         struct bs_softc *bsc;
  330 {
  331         u_int8_t tmp = read_wd33c93(bsc, 0x4c);
  332 
  333         write_wd33c93(bsc, 0x32, tmp & 0xdf);
  334 }
  335 
  336 static void
  337 bshw_dma_stop_elecom(bsc)
  338         struct bs_softc *bsc;
  339 {
  340         u_int8_t tmp = read_wd33c93(bsc, 0x4c);
  341 
  342         write_wd33c93(bsc, 0x32, tmp | 0x20);
  343 }

Cache object: d0621e2ab0003d064fd18c4f063db71e


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