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/isa/wdc_isa.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: wdc_isa.c,v 1.40 2004/01/03 22:56:53 thorpej Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 1998, 2003 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 Onno van der Linden.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *        This product includes software developed by the NetBSD
   21  *        Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __KERNEL_RCSID(0, "$NetBSD: wdc_isa.c,v 1.40 2004/01/03 22:56:53 thorpej Exp $");
   41 
   42 #include <sys/param.h>
   43 #include <sys/systm.h>
   44 #include <sys/device.h>
   45 #include <sys/malloc.h>
   46 
   47 #include <machine/bus.h>
   48 #include <machine/intr.h>
   49 
   50 #include <dev/isa/isavar.h>
   51 #include <dev/isa/isadmavar.h>
   52 
   53 #include <dev/ic/wdcreg.h>
   54 #include <dev/ata/atavar.h>
   55 #include <dev/ic/wdcvar.h>
   56 
   57 #define WDC_ISA_REG_NPORTS      8
   58 #define WDC_ISA_AUXREG_OFFSET   0x206
   59 #define WDC_ISA_AUXREG_NPORTS   1 /* XXX "fdc" owns ports 0x3f7/0x377 */
   60 
   61 /* options passed via the 'flags' config keyword */
   62 #define WDC_OPTIONS_32                  0x01 /* try to use 32bit data I/O */
   63 #define WDC_OPTIONS_ATA_NOSTREAM        0x04
   64 #define WDC_OPTIONS_ATAPI_NOSTREAM      0x08
   65 
   66 struct wdc_isa_softc {
   67         struct  wdc_softc sc_wdcdev;
   68         struct  wdc_channel *wdc_chanlist[1];
   69         struct  wdc_channel wdc_channel;
   70         struct  ata_queue wdc_chqueue;
   71         isa_chipset_tag_t sc_ic;
   72         void    *sc_ih;
   73         int     sc_drq;
   74 };
   75 
   76 int     wdc_isa_probe   __P((struct device *, struct cfdata *, void *));
   77 void    wdc_isa_attach  __P((struct device *, struct device *, void *));
   78 
   79 CFATTACH_DECL(wdc_isa, sizeof(struct wdc_isa_softc),
   80     wdc_isa_probe, wdc_isa_attach, NULL, NULL);
   81 
   82 #if 0
   83 static void     wdc_isa_dma_setup __P((struct wdc_isa_softc *));
   84 static int      wdc_isa_dma_init __P((void*, int, int, void *, size_t, int));
   85 static void     wdc_isa_dma_start __P((void*, int, int));
   86 static int      wdc_isa_dma_finish __P((void*, int, int, int));
   87 #endif
   88 
   89 int
   90 wdc_isa_probe(parent, match, aux)
   91         struct device *parent;
   92         struct cfdata *match;
   93         void *aux;
   94 {
   95         struct wdc_channel ch;
   96         struct isa_attach_args *ia = aux;
   97         int result = 0, i;
   98 
   99         if (ia->ia_nio < 1)
  100                 return (0);
  101         if (ia->ia_nirq < 1)
  102                 return (0);
  103 
  104         if (ISA_DIRECT_CONFIG(ia))
  105                 return (0);
  106 
  107         if (ia->ia_io[0].ir_addr == ISACF_PORT_DEFAULT)
  108                 return (0);
  109         if (ia->ia_irq[0].ir_irq == ISACF_IRQ_DEFAULT)
  110                 return (0);
  111         if (ia->ia_ndrq > 0 && ia->ia_drq[0].ir_drq == ISACF_DRQ_DEFAULT)
  112                 ia->ia_ndrq = 0;
  113 
  114         memset(&ch, 0, sizeof(ch));
  115 
  116         ch.cmd_iot = ia->ia_iot;
  117 
  118         if (bus_space_map(ch.cmd_iot, ia->ia_io[0].ir_addr,
  119             WDC_ISA_REG_NPORTS, 0, &ch.cmd_baseioh))
  120                 goto out;
  121 
  122         for (i = 0; i < WDC_ISA_REG_NPORTS; i++) {
  123                 if (bus_space_subregion(ch.cmd_iot, ch.cmd_baseioh, i,
  124                     i == 0 ? 4 : 1, &ch.cmd_iohs[i]) != 0)
  125                         goto outunmap;
  126         }
  127 
  128         ch.ctl_iot = ia->ia_iot;
  129         if (bus_space_map(ch.ctl_iot, ia->ia_io[0].ir_addr +
  130             WDC_ISA_AUXREG_OFFSET, WDC_ISA_AUXREG_NPORTS, 0, &ch.ctl_ioh))
  131                 goto outunmap;
  132 
  133         result = wdcprobe(&ch);
  134         if (result) {
  135                 ia->ia_nio = 1;
  136                 ia->ia_io[0].ir_size = WDC_ISA_REG_NPORTS;
  137 
  138                 ia->ia_nirq = 1;
  139 
  140                 ia->ia_niomem = 0;
  141         }
  142 
  143         bus_space_unmap(ch.ctl_iot, ch.ctl_ioh, WDC_ISA_AUXREG_NPORTS);
  144 outunmap:
  145         bus_space_unmap(ch.cmd_iot, ch.cmd_baseioh, WDC_ISA_REG_NPORTS);
  146 out:
  147         return (result);
  148 }
  149 
  150 void
  151 wdc_isa_attach(parent, self, aux)
  152         struct device *parent, *self;
  153         void *aux;
  154 {
  155         struct wdc_isa_softc *sc = (void *)self;
  156         struct isa_attach_args *ia = aux;
  157         int wdc_cf_flags = self->dv_cfdata->cf_flags;
  158         int i;
  159 
  160         sc->wdc_channel.cmd_iot = ia->ia_iot;
  161         sc->wdc_channel.ctl_iot = ia->ia_iot;
  162         sc->sc_ic = ia->ia_ic;
  163         if (bus_space_map(sc->wdc_channel.cmd_iot, ia->ia_io[0].ir_addr,
  164             WDC_ISA_REG_NPORTS, 0, &sc->wdc_channel.cmd_baseioh) ||
  165             bus_space_map(sc->wdc_channel.ctl_iot,
  166               ia->ia_io[0].ir_addr + WDC_ISA_AUXREG_OFFSET,
  167               WDC_ISA_AUXREG_NPORTS, 0, &sc->wdc_channel.ctl_ioh)) {
  168                 printf(": couldn't map registers\n");
  169                 return;
  170         }
  171 
  172         for (i = 0; i < WDC_ISA_REG_NPORTS; i++) {
  173                 if (bus_space_subregion(sc->wdc_channel.cmd_iot,
  174                       sc->wdc_channel.cmd_baseioh, i, i == 0 ? 4 : 1,
  175                       &sc->wdc_channel.cmd_iohs[i]) != 0) {
  176                         printf(": couldn't subregion registers\n");
  177                         return;
  178                 }
  179         }
  180 
  181         sc->wdc_channel.data32iot = sc->wdc_channel.cmd_iot;
  182         sc->wdc_channel.data32ioh = sc->wdc_channel.cmd_iohs[0];
  183 
  184         sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq,
  185             IST_EDGE, IPL_BIO, wdcintr, &sc->wdc_channel);
  186 
  187 #if 0
  188         if (ia->ia_ndrq > 0 && ia->ia_drq[0].ir_drq != ISACF_DRQ_DEFAULT) {
  189                 sc->sc_drq = ia->ia_drq[0].ir_drq;
  190 
  191                 sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA;
  192                 sc->sc_wdcdev.dma_arg = sc;
  193                 sc->sc_wdcdev.dma_init = wdc_isa_dma_init;
  194                 sc->sc_wdcdev.dma_start = wdc_isa_dma_start;
  195                 sc->sc_wdcdev.dma_finish = wdc_isa_dma_finish;
  196                 wdc_isa_dma_setup(sc);
  197         }
  198 #endif
  199         sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_PREATA;
  200         if (wdc_cf_flags & WDC_OPTIONS_32)
  201                 sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA32;
  202         if (wdc_cf_flags & WDC_OPTIONS_ATA_NOSTREAM)
  203                 sc->sc_wdcdev.cap |= WDC_CAPABILITY_ATA_NOSTREAM;
  204         if (wdc_cf_flags & WDC_OPTIONS_ATAPI_NOSTREAM)
  205                 sc->sc_wdcdev.cap |= WDC_CAPABILITY_ATAPI_NOSTREAM;
  206 
  207         sc->sc_wdcdev.PIO_cap = 0;
  208         sc->wdc_chanlist[0] = &sc->wdc_channel;
  209         sc->sc_wdcdev.channels = sc->wdc_chanlist;
  210         sc->sc_wdcdev.nchannels = 1;
  211         sc->wdc_channel.ch_channel = 0;
  212         sc->wdc_channel.ch_wdc = &sc->sc_wdcdev;
  213         sc->wdc_channel.ch_queue = &sc->wdc_chqueue;
  214 
  215         printf("\n");
  216 
  217         wdcattach(&sc->wdc_channel);
  218 }
  219 
  220 #if 0
  221 static void
  222 wdc_isa_dma_setup(sc)
  223         struct wdc_isa_softc *sc;
  224 {
  225         bus_size_t maxsize;
  226 
  227         if ((maxsize = isa_dmamaxsize(sc->sc_ic, sc->sc_drq)) < MAXPHYS) {
  228                 printf("%s: max DMA size %lu is less than required %d\n",
  229                     sc->sc_wdcdev.sc_dev.dv_xname, (u_long)maxsize, MAXPHYS);
  230                 sc->sc_wdcdev.cap &= ~WDC_CAPABILITY_DMA;
  231                 return;
  232         }
  233 
  234         if (isa_drq_alloc(sc->sc_ic, sc->sc_drq) != 0) {
  235                 printf("%s: can't reserve drq %d\n",
  236                     sc->sc_wdcdev.sc_dev.dv_xname, sc->sc_drq);
  237                 sc->sc_wdcdev.cap &= ~WDC_CAPABILITY_DMA;
  238                 return;
  239         }
  240 
  241         if (isa_dmamap_create(sc->sc_ic, sc->sc_drq,
  242             MAXPHYS, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
  243                 printf("%s: can't create map for drq %d\n",
  244                     sc->sc_wdcdev.sc_dev.dv_xname, sc->sc_drq);
  245                 sc->sc_wdcdev.cap &= ~WDC_CAPABILITY_DMA;
  246         }
  247 }
  248 
  249 static int
  250 wdc_isa_dma_init(v, channel, drive, databuf, datalen, read)
  251         void *v;
  252         void *databuf;
  253         size_t datalen;
  254         int read;
  255 {
  256         struct wdc_isa_softc *sc = v;
  257 
  258         isa_dmastart(sc->sc_ic, sc->sc_drq, databuf, datalen, NULL,
  259             (read ? DMAMODE_READ : DMAMODE_WRITE) | DMAMODE_DEMAND,
  260             BUS_DMA_NOWAIT);
  261         return 0;
  262 }
  263 
  264 static void
  265 wdc_isa_dma_start(v, channel, drive)
  266         void *v;
  267         int channel, drive;
  268 {
  269         /* nothing to do */
  270 }
  271 
  272 static int
  273 wdc_isa_dma_finish(v, channel, drive, read)
  274         void *v;
  275         int channel, drive;
  276         int read;
  277 {
  278         struct wdc_isa_softc *sc = v;
  279 
  280         isa_dmadone(sc->sc_ic, sc->sc_drq);
  281         return 0;
  282 }
  283 #endif

Cache object: 38f78816dcf54749fcf695aacd4fc4ac


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