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

Cache object: 7583166e61690f68a421ed54d770148f


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