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/arm/xscale/ixp425/avila_ata.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2006 Sam Leffler, Errno Consulting
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer,
   10  *    without modification.
   11  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
   12  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
   13  *    redistribution must be conditioned upon including a substantially
   14  *    similar Disclaimer requirement for further binary redistribution.
   15  *
   16  * NO WARRANTY
   17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   19  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
   20  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
   21  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
   22  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
   25  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   27  * THE POSSIBILITY OF SUCH DAMAGES.
   28  */
   29 
   30 #include <sys/cdefs.h>
   31 __FBSDID("$FreeBSD$");
   32 
   33 /*
   34  * Compact Flash Support for the Avila Gateworks XScale boards.
   35  * The CF slot is operated in "True IDE" mode. Registers are on
   36  * the Expansion Bus connected to CS1 and CS2. Interrupts are
   37  * tied to GPIO pin 12.  No DMA, just PIO.
   38  *
   39  * The ADI Pronghorn Metro is very similar. It use CS3 and CS4 and
   40  * GPIO pin 0 for interrupts.
   41  *
   42  * See also http://www.intel.com/design/network/applnots/302456.htm.
   43  */
   44 #include <sys/param.h>
   45 #include <sys/systm.h>
   46 #include <sys/kernel.h>
   47 #include <sys/module.h>
   48 #include <sys/time.h>
   49 #include <sys/bus.h>
   50 #include <sys/resource.h>
   51 #include <sys/rman.h>
   52 #include <sys/sysctl.h>
   53 #include <sys/endian.h>
   54 
   55 #include <machine/bus.h>
   56 #include <machine/cpu.h>
   57 #include <machine/cpufunc.h>
   58 #include <machine/resource.h>
   59 #include <machine/intr.h>
   60 #include <arm/xscale/ixp425/ixp425reg.h>
   61 #include <arm/xscale/ixp425/ixp425var.h>
   62 
   63 #include <sys/ata.h>
   64 #include <sys/sema.h>
   65 #include <sys/taskqueue.h>
   66 #include <vm/uma.h>
   67 #include <dev/ata/ata-all.h>
   68 #include <ata_if.h>
   69 
   70 #define AVILA_IDE_GPIN          12              /* GPIO pin # */
   71 #define AVILA_IDE_IRQ           IXP425_INT_GPIO_12
   72 #define AVILA_IDE_CTRL          0x06            /* control register */
   73 
   74 #define PRONGHORN_IDE_GPIN      0       /* GPIO pin # */
   75 #define PRONGHORN_IDE_IRQ       IXP425_INT_GPIO_0
   76 #define PRONGHORN_IDE_CNTRL     0x06    /* control register */
   77 
   78 struct ata_avila_softc {
   79         device_t                sc_dev;
   80         bus_space_tag_t         sc_iot;
   81         bus_space_handle_t      sc_exp_ioh;     /* Exp Bus config registers */
   82         bus_space_handle_t      sc_ioh;         /* CS1/3 data registers */
   83         bus_space_handle_t      sc_alt_ioh;     /* CS2/4 data registers */
   84         struct bus_space        sc_expbus_tag;
   85         struct resource         sc_ata;         /* hand-crafted for ATA */
   86         struct resource         sc_alt_ata;     /* hand-crafted for ATA */
   87         u_int32_t               sc_16bit_off;   /* EXP_TIMING_CSx_OFFSET */
   88         int                     sc_rid;         /* rid for IRQ */
   89         struct resource         *sc_irq;        /* IRQ resource */
   90         void                    *sc_ih;         /* interrupt handler */
   91         struct {
   92                 void    (*cb)(void *);
   93                 void    *arg;
   94         } sc_intr[1];                   /* NB: 1/channel */
   95 };
   96 
   97 static void ata_avila_intr(void *);
   98 bs_protos(ata);
   99 static  void ata_bs_rm_2_s(void *, bus_space_handle_t, bus_size_t,
  100                 u_int16_t *, bus_size_t);
  101 static  void ata_bs_wm_2_s(void *, bus_space_handle_t, bus_size_t,
  102                 const u_int16_t *, bus_size_t);
  103 
  104 static int
  105 ata_avila_probe(device_t dev)
  106 {
  107         struct ixp425_softc *sa = device_get_softc(device_get_parent(dev));
  108 
  109         /* XXX any way to check? */
  110         if (EXP_BUS_READ_4(sa, EXP_TIMING_CS2_OFFSET) != 0)
  111                 device_set_desc_copy(dev, "Gateworks Avila IDE/CF Controller");
  112         else
  113                 device_set_desc_copy(dev,
  114                     "ADI Pronghorn Metro IDE/CF Controller");
  115         return 0;
  116 }
  117 
  118 static int
  119 ata_avila_attach(device_t dev)
  120 {
  121         struct ata_avila_softc *sc = device_get_softc(dev);
  122         struct ixp425_softc *sa = device_get_softc(device_get_parent(dev));
  123         u_int32_t alt_t_off, ide_gpin, ide_irq;
  124 
  125         sc->sc_dev = dev;
  126         /* NB: borrow from parent */
  127         sc->sc_iot = sa->sc_iot;
  128         sc->sc_exp_ioh = sa->sc_exp_ioh;
  129         if (EXP_BUS_READ_4(sc, EXP_TIMING_CS2_OFFSET) != 0) {
  130                 /* Avila board */
  131                 if (bus_space_map(sc->sc_iot, IXP425_EXP_BUS_CS1_HWBASE,
  132                     IXP425_EXP_BUS_CS1_SIZE, 0, &sc->sc_ioh))
  133                         panic("%s: unable to map Expansion Bus CS1 window",
  134                             __func__);
  135                 if (bus_space_map(sc->sc_iot, IXP425_EXP_BUS_CS2_HWBASE,
  136                     IXP425_EXP_BUS_CS2_SIZE, 0, &sc->sc_alt_ioh))
  137                         panic("%s: unable to map Expansion Bus CS2 window",
  138                             __func__);
  139                 ide_gpin = AVILA_IDE_GPIN;
  140                 ide_irq = AVILA_IDE_IRQ;
  141                 sc->sc_16bit_off = EXP_TIMING_CS1_OFFSET;
  142                 alt_t_off = EXP_TIMING_CS2_OFFSET;
  143         } else {
  144                 /* Pronghorn */
  145                 if (bus_space_map(sc->sc_iot, IXP425_EXP_BUS_CS3_HWBASE,
  146                     IXP425_EXP_BUS_CS3_SIZE, 0, &sc->sc_ioh))
  147                         panic("%s: unable to map Expansion Bus CS3 window",
  148                             __func__);
  149                 if (bus_space_map(sc->sc_iot, IXP425_EXP_BUS_CS4_HWBASE,
  150                     IXP425_EXP_BUS_CS4_SIZE, 0, &sc->sc_alt_ioh))
  151                         panic("%s: unable to map Expansion Bus CS4 window",
  152                             __func__);
  153                 ide_gpin = PRONGHORN_IDE_GPIN;
  154                 ide_irq = PRONGHORN_IDE_IRQ;
  155                 sc->sc_16bit_off = EXP_TIMING_CS3_OFFSET;
  156                 alt_t_off = EXP_TIMING_CS4_OFFSET;
  157         }
  158 
  159         /*
  160          * Craft special resource for ATA bus space ops
  161          * that go through the expansion bus and require
  162          * special hackery to ena/dis 16-bit operations.
  163          *
  164          * XXX probably should just make this generic for
  165          * accessing the expansion bus.
  166          */
  167         sc->sc_expbus_tag.bs_cookie = sc;       /* NB: backpointer */
  168         /* read single */
  169         sc->sc_expbus_tag.bs_r_1        = ata_bs_r_1,
  170         sc->sc_expbus_tag.bs_r_2        = ata_bs_r_2,
  171         /* read multiple */
  172         sc->sc_expbus_tag.bs_rm_2       = ata_bs_rm_2,
  173         sc->sc_expbus_tag.bs_rm_2_s     = ata_bs_rm_2_s,
  174         /* write (single) */
  175         sc->sc_expbus_tag.bs_w_1        = ata_bs_w_1,
  176         sc->sc_expbus_tag.bs_w_2        = ata_bs_w_2,
  177         /* write multiple */
  178         sc->sc_expbus_tag.bs_wm_2       = ata_bs_wm_2,
  179         sc->sc_expbus_tag.bs_wm_2_s     = ata_bs_wm_2_s,
  180 
  181         rman_set_bustag(&sc->sc_ata, &sc->sc_expbus_tag);
  182         rman_set_bushandle(&sc->sc_ata, sc->sc_ioh);
  183         rman_set_bustag(&sc->sc_alt_ata, &sc->sc_expbus_tag);
  184         rman_set_bushandle(&sc->sc_alt_ata, sc->sc_alt_ioh);
  185 
  186         GPIO_CONF_WRITE_4(sa, IXP425_GPIO_GPOER, 
  187             GPIO_CONF_READ_4(sa, IXP425_GPIO_GPOER) | (1<<ide_gpin));
  188         /* set interrupt type */
  189         GPIO_CONF_WRITE_4(sa, GPIO_TYPE_REG(ide_gpin),
  190             (GPIO_CONF_READ_4(sa, GPIO_TYPE_REG(ide_gpin)) &~
  191              GPIO_TYPE(ide_gpin, GPIO_TYPE_MASK)) |
  192              GPIO_TYPE(ide_gpin, GPIO_TYPE_EDG_RISING));
  193 
  194         /* clear ISR */
  195         GPIO_CONF_WRITE_4(sa, IXP425_GPIO_GPISR, (1<<ide_gpin));
  196 
  197         /* configure CS1/3 window, leaving timing unchanged */
  198         EXP_BUS_WRITE_4(sc, sc->sc_16bit_off,
  199             EXP_BUS_READ_4(sc, sc->sc_16bit_off) |
  200                 EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN);
  201         /* configure CS2/4 window, leaving timing unchanged */
  202         EXP_BUS_WRITE_4(sc, alt_t_off,
  203             EXP_BUS_READ_4(sc, alt_t_off) |
  204                 EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN);
  205 
  206         /* setup interrupt */
  207         sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->sc_rid,
  208             ide_irq, ide_irq, 1, RF_ACTIVE);
  209         if (!sc->sc_irq)
  210                 panic("Unable to allocate irq %u.\n", ide_irq);
  211         bus_setup_intr(dev, sc->sc_irq,
  212             INTR_TYPE_BIO | INTR_MPSAFE | INTR_ENTROPY,
  213             NULL, ata_avila_intr, sc, &sc->sc_ih);
  214 
  215         /* attach channel on this controller */
  216         device_add_child(dev, "ata", devclass_find_free_unit(ata_devclass, 0));
  217         bus_generic_attach(dev);
  218 
  219         return 0;
  220 }
  221 
  222 static int
  223 ata_avila_detach(device_t dev)
  224 {
  225         struct ata_avila_softc *sc = device_get_softc(dev);
  226         device_t *children;
  227         int nc;
  228 
  229         /* XXX quiesce gpio? */
  230 
  231         /* detach & delete all children */
  232         if (device_get_children(dev, &children, &nc) == 0) {
  233             if (nc > 0)
  234                     device_delete_child(dev, children[0]);
  235             free(children, M_TEMP);
  236         }
  237 
  238         bus_teardown_intr(dev, sc->sc_irq, sc->sc_ih);
  239         bus_release_resource(dev, SYS_RES_IRQ, sc->sc_rid, sc->sc_irq);
  240 
  241         return 0;
  242 }
  243 
  244 static void
  245 ata_avila_intr(void *xsc)
  246 {
  247         struct ata_avila_softc *sc = xsc;
  248 
  249         if (sc->sc_intr[0].cb != NULL)
  250                 sc->sc_intr[0].cb(sc->sc_intr[0].arg);
  251 }
  252 
  253 static struct resource *
  254 ata_avila_alloc_resource(device_t dev, device_t child, int type, int *rid,
  255                        u_long start, u_long end, u_long count, u_int flags)
  256 {
  257         struct ata_avila_softc *sc = device_get_softc(dev);
  258 
  259         KASSERT(type == SYS_RES_IRQ && *rid == ATA_IRQ_RID,
  260             ("type %u rid %u start %lu end %lu count %lu flags %u",
  261              type, *rid, start, end, count, flags));
  262 
  263         /* doesn't matter what we return so reuse the real thing */
  264         return sc->sc_irq;
  265 }
  266 
  267 static int
  268 ata_avila_release_resource(device_t dev, device_t child, int type, int rid,
  269                          struct resource *r)
  270 {
  271         KASSERT(type == SYS_RES_IRQ && rid == ATA_IRQ_RID,
  272             ("type %u rid %u", type, rid));
  273         return 0;
  274 }
  275 
  276 static int
  277 ata_avila_setup_intr(device_t dev, device_t child, struct resource *irq, 
  278                    int flags, driver_filter_t *filt,
  279                    driver_intr_t *function, void *argument, void **cookiep)
  280 {
  281         struct ata_avila_softc *sc = device_get_softc(dev);
  282         int unit = ((struct ata_channel *)device_get_softc(child))->unit;
  283 
  284         KASSERT(unit == 0, ("unit %d", unit));
  285         sc->sc_intr[unit].cb = function;
  286         sc->sc_intr[unit].arg = argument;
  287         *cookiep = sc;
  288         return 0;
  289 }
  290 
  291 static int
  292 ata_avila_teardown_intr(device_t dev, device_t child, struct resource *irq,
  293                       void *cookie)
  294 {
  295         struct ata_avila_softc *sc = device_get_softc(dev);
  296         int unit = ((struct ata_channel *)device_get_softc(child))->unit;
  297 
  298         KASSERT(unit == 0, ("unit %d", unit));
  299         sc->sc_intr[unit].cb = NULL;
  300         sc->sc_intr[unit].arg = NULL;
  301         return 0;
  302 }
  303 
  304 /*
  305  * Bus space accessors for CF-IDE PIO operations.
  306  */
  307 
  308 /*
  309  * Enable/disable 16-bit ops on the expansion bus.
  310  */
  311 static void __inline
  312 enable_16(struct ata_avila_softc *sc)
  313 {
  314         EXP_BUS_WRITE_4(sc, sc->sc_16bit_off,
  315             EXP_BUS_READ_4(sc, sc->sc_16bit_off) &~ EXP_BYTE_EN);
  316         DELAY(100);             /* XXX? */
  317 }
  318 
  319 static void __inline
  320 disable_16(struct ata_avila_softc *sc)
  321 {
  322         DELAY(100);             /* XXX? */
  323         EXP_BUS_WRITE_4(sc, sc->sc_16bit_off,
  324             EXP_BUS_READ_4(sc, sc->sc_16bit_off) | EXP_BYTE_EN);
  325 }
  326 
  327 uint8_t
  328 ata_bs_r_1(void *t, bus_space_handle_t h, bus_size_t o)
  329 {
  330         struct ata_avila_softc *sc = t;
  331 
  332         return bus_space_read_1(sc->sc_iot, h, o);
  333 }
  334 
  335 void
  336 ata_bs_w_1(void *t, bus_space_handle_t h, bus_size_t o, u_int8_t v)
  337 {
  338         struct ata_avila_softc *sc = t;
  339 
  340         bus_space_write_1(sc->sc_iot, h, o, v);
  341 }
  342 
  343 uint16_t
  344 ata_bs_r_2(void *t, bus_space_handle_t h, bus_size_t o)
  345 {
  346         struct ata_avila_softc *sc = t;
  347         uint16_t v;
  348 
  349         enable_16(sc);
  350         v = bus_space_read_2(sc->sc_iot, h, o);
  351         disable_16(sc);
  352         return v;
  353 }
  354 
  355 void
  356 ata_bs_w_2(void *t, bus_space_handle_t h, bus_size_t o, uint16_t v)
  357 {
  358         struct ata_avila_softc *sc = t;
  359 
  360         enable_16(sc);
  361         bus_space_write_2(sc->sc_iot, h, o, v);
  362         disable_16(sc);
  363 }
  364 
  365 void
  366 ata_bs_rm_2(void *t, bus_space_handle_t h, bus_size_t o,
  367         u_int16_t *d, bus_size_t c)
  368 {
  369         struct ata_avila_softc *sc = t;
  370 
  371         enable_16(sc);
  372         bus_space_read_multi_2(sc->sc_iot, h, o, d, c);
  373         disable_16(sc);
  374 }
  375 
  376 void
  377 ata_bs_wm_2(void *t, bus_space_handle_t h, bus_size_t o,
  378         const u_int16_t *d, bus_size_t c)
  379 {
  380         struct ata_avila_softc *sc = t;
  381 
  382         enable_16(sc);
  383         bus_space_write_multi_2(sc->sc_iot, h, o, d, c);
  384         disable_16(sc);
  385 }
  386 
  387 /* XXX workaround ata driver by (incorrectly) byte swapping stream cases */
  388 
  389 void
  390 ata_bs_rm_2_s(void *t, bus_space_handle_t h, bus_size_t o,
  391         u_int16_t *d, bus_size_t c)
  392 {
  393         struct ata_avila_softc *sc = t;
  394         uint16_t v;
  395         bus_size_t i;
  396 
  397         enable_16(sc);
  398 #if 1
  399         for (i = 0; i < c; i++) {
  400                 v = bus_space_read_2(sc->sc_iot, h, o);
  401                 d[i] = bswap16(v);
  402         }
  403 #else
  404         bus_space_read_multi_stream_2(sc->sc_iot, h, o, d, c);
  405 #endif
  406         disable_16(sc);
  407 }
  408 
  409 void
  410 ata_bs_wm_2_s(void *t, bus_space_handle_t h, bus_size_t o,
  411         const u_int16_t *d, bus_size_t c)
  412 {
  413         struct ata_avila_softc *sc = t;
  414         bus_size_t i;
  415 
  416         enable_16(sc);
  417 #if 1
  418         for (i = 0; i < c; i++)
  419                 bus_space_write_2(sc->sc_iot, h, o, bswap16(d[i]));
  420 #else
  421         bus_space_write_multi_stream_2(sc->sc_iot, h, o, d, c);
  422 #endif
  423         disable_16(sc);
  424 }
  425 
  426 static device_method_t ata_avila_methods[] = {
  427         /* device interface */
  428         DEVMETHOD(device_probe,             ata_avila_probe),
  429         DEVMETHOD(device_attach,            ata_avila_attach),
  430         DEVMETHOD(device_detach,            ata_avila_detach),
  431         DEVMETHOD(device_shutdown,          bus_generic_shutdown),
  432         DEVMETHOD(device_suspend,           bus_generic_suspend),
  433         DEVMETHOD(device_resume,            bus_generic_resume),
  434 
  435         /* bus methods */
  436         DEVMETHOD(bus_alloc_resource,       ata_avila_alloc_resource),
  437         DEVMETHOD(bus_release_resource,     ata_avila_release_resource),
  438         DEVMETHOD(bus_activate_resource,    bus_generic_activate_resource),
  439         DEVMETHOD(bus_deactivate_resource,  bus_generic_deactivate_resource),
  440         DEVMETHOD(bus_setup_intr,           ata_avila_setup_intr),
  441         DEVMETHOD(bus_teardown_intr,        ata_avila_teardown_intr),
  442 
  443         { 0, 0 }
  444 };
  445 
  446 devclass_t ata_avila_devclass;
  447 
  448 static driver_t ata_avila_driver = {
  449         "ata_avila",
  450         ata_avila_methods,
  451         sizeof(struct ata_avila_softc),
  452 };
  453 
  454 DRIVER_MODULE(ata_avila, ixp, ata_avila_driver, ata_avila_devclass, 0, 0);
  455 MODULE_VERSION(ata_avila, 1);
  456 MODULE_DEPEND(ata_avila, ata, 1, 1, 1);
  457 
  458 static int
  459 avila_channel_probe(device_t dev)
  460 {
  461         struct ata_channel *ch = device_get_softc(dev);
  462 
  463         ch->unit = 0;
  464         ch->flags |= ATA_USE_16BIT | ATA_NO_SLAVE;
  465         device_set_desc_copy(dev, "ATA channel 0");
  466 
  467         return ata_probe(dev);
  468 }
  469 
  470 static int
  471 avila_channel_attach(device_t dev)
  472 {
  473         struct ata_avila_softc *sc = device_get_softc(device_get_parent(dev));
  474         struct ata_channel *ch = device_get_softc(dev);
  475         int i;
  476 
  477         for (i = 0; i < ATA_MAX_RES; i++)
  478                 ch->r_io[i].res = &sc->sc_ata;
  479 
  480         ch->r_io[ATA_DATA].offset = ATA_DATA;
  481         ch->r_io[ATA_FEATURE].offset = ATA_FEATURE;
  482         ch->r_io[ATA_COUNT].offset = ATA_COUNT;
  483         ch->r_io[ATA_SECTOR].offset = ATA_SECTOR;
  484         ch->r_io[ATA_CYL_LSB].offset = ATA_CYL_LSB;
  485         ch->r_io[ATA_CYL_MSB].offset = ATA_CYL_MSB;
  486         ch->r_io[ATA_DRIVE].offset = ATA_DRIVE;
  487         ch->r_io[ATA_COMMAND].offset = ATA_COMMAND;
  488         ch->r_io[ATA_ERROR].offset = ATA_FEATURE;
  489         /* NB: should be used only for ATAPI devices */
  490         ch->r_io[ATA_IREASON].offset = ATA_COUNT;
  491         ch->r_io[ATA_STATUS].offset = ATA_COMMAND;
  492 
  493         /* NB: the control and alt status registers are special */
  494         ch->r_io[ATA_ALTSTAT].res = &sc->sc_alt_ata;
  495         ch->r_io[ATA_ALTSTAT].offset = AVILA_IDE_CTRL;
  496         ch->r_io[ATA_CONTROL].res = &sc->sc_alt_ata;
  497         ch->r_io[ATA_CONTROL].offset = AVILA_IDE_CTRL;
  498 
  499         /* NB: by convention this points at the base of registers */
  500         ch->r_io[ATA_IDX_ADDR].offset = 0;
  501 
  502         ata_generic_hw(dev);
  503         return ata_attach(dev);
  504 }
  505 
  506 static device_method_t avila_channel_methods[] = {
  507         /* device interface */
  508         DEVMETHOD(device_probe,     avila_channel_probe),
  509         DEVMETHOD(device_attach,    avila_channel_attach),
  510         DEVMETHOD(device_detach,    ata_detach),
  511         DEVMETHOD(device_shutdown,  bus_generic_shutdown),
  512         DEVMETHOD(device_suspend,   ata_suspend),
  513         DEVMETHOD(device_resume,    ata_resume),
  514 
  515         { 0, 0 }
  516 };
  517 
  518 driver_t avila_channel_driver = {
  519         "ata",
  520         avila_channel_methods,
  521         sizeof(struct ata_channel),
  522 };
  523 DRIVER_MODULE(ata, ata_avila, avila_channel_driver, ata_devclass, 0, 0);

Cache object: de82e3390f4abbbd5f633178586f4c27


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