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/mv/mv_sata.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 /*-
    2  * Copyright (C) 2008-2009 Semihalf
    3  * All rights reserved.
    4  *
    5  * Initial version developed by Ilya Bakulin. Full functionality and bringup
    6  * by Piotr Ziecik.
    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  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
   21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  */
   29 
   30 #include <sys/cdefs.h>
   31 __FBSDID("$FreeBSD: releng/10.1/sys/arm/mv/mv_sata.c 266152 2014-05-15 16:11:06Z ian $");
   32 
   33 #include <sys/param.h>
   34 #include <sys/bus.h>
   35 #include <sys/lock.h>
   36 #include <sys/resource.h>
   37 #include <sys/systm.h>
   38 #include <sys/rman.h>
   39 #include <sys/kernel.h>
   40 #include <sys/module.h>
   41 #include <sys/mutex.h>
   42 #include <sys/endian.h>
   43 #include <sys/sema.h>
   44 #include <sys/taskqueue.h>
   45 #include <vm/uma.h>
   46 #include <machine/bus.h>
   47 #include <machine/resource.h>
   48 
   49 #include <sys/ata.h>
   50 #include <dev/ata/ata-all.h>
   51 #include <dev/ofw/ofw_bus.h>
   52 #include <dev/ofw/ofw_bus_subr.h>
   53 
   54 #include "ata_if.h"
   55 
   56 #include "mvreg.h"
   57 #include "mvvar.h"
   58 
   59 /* Useful macros */
   60 #define EDMA_TIMEOUT            100000 /* 100 ms */
   61 #define SATA_INL(sc, reg)       ATA_INL((sc)->sc_mem_res, reg)
   62 #define SATA_OUTL(sc, reg, val) ATA_OUTL((sc)->sc_mem_res, reg, val)
   63 
   64 /* HW-related data structures */
   65 struct sata_prdentry {
   66         uint32_t        prd_addrlo;
   67         uint32_t        prd_count;
   68         uint32_t        prd_addrhi;
   69         uint32_t        prd_reserved;
   70 };
   71 
   72 struct sata_crqb {
   73         uint32_t        crqb_prdlo;
   74         uint32_t        crqb_prdhi;
   75         uint32_t        crqb_flags;
   76         uint16_t        crqb_count;
   77         uint16_t        crqb_reserved1[2];
   78         uint8_t         crqb_ata_command;
   79         uint8_t         crqb_ata_feature;
   80         uint8_t         crqb_ata_lba_low;
   81         uint8_t         crqb_ata_lba_mid;
   82         uint8_t         crqb_ata_lba_high;
   83         uint8_t         crqb_ata_device;
   84         uint8_t         crqb_ata_lba_low_p;
   85         uint8_t         crqb_ata_lba_mid_p;
   86         uint8_t         crqb_ata_lba_high_p;
   87         uint8_t         crqb_ata_feature_p;
   88         uint8_t         crqb_ata_count;
   89         uint8_t         crqb_ata_count_p;
   90         uint16_t        crqb_reserved2;
   91 };
   92 
   93 struct sata_crpb {
   94         uint8_t         crpb_tag;
   95         uint8_t         crpb_reserved;
   96         uint8_t         crpb_edma_status;
   97         uint8_t         crpb_dev_status;
   98         uint32_t        crpb_timestamp;
   99 };
  100 
  101 /* Identification section. */
  102 struct sata_softc {
  103         device_t                sc_dev;
  104         unsigned int            sc_version;
  105         unsigned int            sc_edma_qlen;
  106         uint32_t                sc_edma_reqis_mask;
  107         uint32_t                sc_edma_resos_mask;
  108         struct resource         *sc_mem_res;
  109         bus_space_tag_t         sc_mem_res_bustag;
  110         bus_space_handle_t      sc_mem_res_bushdl;
  111         struct resource         *sc_irq_res;
  112         void                    *sc_irq_cookiep;
  113         struct {
  114                 void    (*function)(void *);
  115                 void    *argument;
  116         } sc_interrupt[SATA_CHAN_NUM];
  117 };
  118 
  119 /* Controller functions */
  120 static int      sata_probe(device_t dev);
  121 static int      sata_attach(device_t dev);
  122 static int      sata_detach(device_t dev);
  123 static void     sata_intr(void*);
  124 static struct resource * sata_alloc_resource(device_t dev, device_t child,
  125     int type, int *rid, u_long start, u_long end, u_long count, u_int flags);
  126 static int      sata_release_resource(device_t dev, device_t child, int type,
  127     int rid, struct resource *r);
  128 static int      sata_setup_intr(device_t dev, device_t child,
  129     struct resource *irq, int flags, driver_filter_t *filt,
  130     driver_intr_t *function, void *argument, void **cookiep);
  131 static int      sata_teardown_intr(device_t dev, device_t child,
  132     struct resource *irq, void *cookie);
  133 
  134 /* Channel functions */
  135 static int      sata_channel_probe(device_t dev);
  136 static int      sata_channel_attach(device_t dev);
  137 static int      sata_channel_detach(device_t dev);
  138 static int      sata_channel_begin_transaction(struct ata_request *request);
  139 static int      sata_channel_end_transaction(struct ata_request *request);
  140 static int      sata_channel_status(device_t dev);
  141 static int      sata_channel_setmode(device_t dev, int target, int mode);
  142 static int      sata_channel_getrev(device_t dev, int target);
  143 static void     sata_channel_reset(device_t dev);
  144 static void     sata_channel_dmasetprd(void *xsc, bus_dma_segment_t *segs,
  145     int nsegs, int error);
  146 
  147 /* EDMA functions */
  148 static int      sata_edma_ctrl(device_t dev, int on);
  149 static int      sata_edma_is_running(device_t);
  150 
  151 static device_method_t sata_methods[] = {
  152         /* Device method */
  153         DEVMETHOD(device_probe,         sata_probe),
  154         DEVMETHOD(device_attach,        sata_attach),
  155         DEVMETHOD(device_detach,        sata_detach),
  156         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
  157         DEVMETHOD(device_suspend,       bus_generic_suspend),
  158         DEVMETHOD(device_resume,        bus_generic_resume),
  159 
  160         /* ATA bus methods. */
  161         DEVMETHOD(bus_alloc_resource,           sata_alloc_resource),
  162         DEVMETHOD(bus_release_resource,         sata_release_resource),
  163         DEVMETHOD(bus_activate_resource,        bus_generic_activate_resource),
  164         DEVMETHOD(bus_deactivate_resource,      bus_generic_deactivate_resource),
  165         DEVMETHOD(bus_setup_intr,               sata_setup_intr),
  166         DEVMETHOD(bus_teardown_intr,            sata_teardown_intr),
  167         { 0, 0 },
  168 };
  169 
  170 static driver_t sata_driver = {
  171         "sata",
  172         sata_methods,
  173         sizeof(struct sata_softc),
  174 };
  175 
  176 devclass_t sata_devclass;
  177 
  178 DRIVER_MODULE(sata, simplebus, sata_driver, sata_devclass, 0, 0);
  179 MODULE_VERSION(sata, 1);
  180 MODULE_DEPEND(sata, ata, 1, 1, 1);
  181 
  182 static int
  183 sata_probe(device_t dev)
  184 {
  185         struct sata_softc *sc;
  186         uint32_t d, r;
  187 
  188         if (!ofw_bus_status_okay(dev))
  189                 return (ENXIO);
  190 
  191         if (!ofw_bus_is_compatible(dev, "mrvl,sata"))
  192                 return (ENXIO);
  193 
  194         soc_id(&d, &r);
  195         sc = device_get_softc(dev);
  196 
  197         switch(d) {
  198         case MV_DEV_88F5182:
  199                 sc->sc_version = 1;
  200                 sc->sc_edma_qlen = 128;
  201                 break;
  202         case MV_DEV_88F6281:
  203         case MV_DEV_88F6282:
  204         case MV_DEV_MV78100:
  205         case MV_DEV_MV78100_Z0:
  206         case MV_DEV_MV78460:
  207                 sc->sc_version = 2;
  208                 sc->sc_edma_qlen = 32;
  209                 break;
  210         default:
  211                 device_printf(dev, "unsupported SoC (ID: 0x%08X)!\n", d);
  212                 return (ENXIO);
  213         }
  214 
  215         sc->sc_edma_reqis_mask = (sc->sc_edma_qlen - 1) << SATA_EDMA_REQIS_OFS;
  216         sc->sc_edma_resos_mask = (sc->sc_edma_qlen - 1) << SATA_EDMA_RESOS_OFS;
  217 
  218         device_set_desc(dev, "Marvell Integrated SATA Controller");
  219         return (0);
  220 }
  221 
  222 static int
  223 sata_attach(device_t dev)
  224 {
  225         struct sata_softc *sc;
  226         int mem_id, irq_id, error, i;
  227         device_t ata_chan;
  228         uint32_t reg;
  229 
  230         sc = device_get_softc(dev);
  231         sc->sc_dev = dev;
  232         mem_id = 0;
  233         irq_id = 0;
  234 
  235         /* Allocate resources */
  236         sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
  237             &mem_id, RF_ACTIVE);
  238         if (sc->sc_mem_res == NULL) {
  239                 device_printf(dev, "could not allocate memory.\n");
  240                 return (ENOMEM);
  241         }
  242 
  243         sc->sc_mem_res_bustag = rman_get_bustag(sc->sc_mem_res);
  244         sc->sc_mem_res_bushdl = rman_get_bushandle(sc->sc_mem_res);
  245         KASSERT(sc->sc_mem_res_bustag && sc->sc_mem_res_bushdl,
  246             ("cannot get bus handle or tag."));
  247 
  248         sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &irq_id,
  249             RF_ACTIVE);
  250         if (sc->sc_irq_res == NULL) {
  251                 device_printf(dev, "could not allocate IRQ.\n");
  252                 error = ENOMEM;
  253                 goto err;
  254         }
  255 
  256         error = bus_setup_intr(dev, sc->sc_irq_res,
  257             INTR_TYPE_BIO | INTR_MPSAFE | INTR_ENTROPY,
  258             NULL, sata_intr, sc, &sc->sc_irq_cookiep);
  259         if (error != 0) {
  260                 device_printf(dev, "could not setup interrupt.\n");
  261                 goto err;
  262         }
  263 
  264         /* Attach channels */
  265         for (i = 0; i < SATA_CHAN_NUM; i++) {
  266                 ata_chan = device_add_child(dev, "ata",
  267                     devclass_find_free_unit(ata_devclass, 0));
  268 
  269                 if (!ata_chan) {
  270                         device_printf(dev, "cannot add channel %d.\n", i);
  271                         error = ENOMEM;
  272                         goto err;
  273                 }
  274         }
  275 
  276         /* Disable interrupt coalescing */
  277         reg = SATA_INL(sc, SATA_CR);
  278         for (i = 0; i < SATA_CHAN_NUM; i++)
  279                 reg |= SATA_CR_COALDIS(i);
  280 
  281         /* Disable DMA byte swapping */
  282         if (sc->sc_version == 2)
  283                 reg |= SATA_CR_NODMABS | SATA_CR_NOEDMABS |
  284                     SATA_CR_NOPRDPBS;
  285 
  286         SATA_OUTL(sc, SATA_CR, reg);
  287 
  288         /* Clear and mask all interrupts */
  289         SATA_OUTL(sc, SATA_ICR, 0);
  290         SATA_OUTL(sc, SATA_MIMR, 0);
  291 
  292         return(bus_generic_attach(dev));
  293 
  294 err:
  295         sata_detach(dev);
  296         return (error);
  297 }
  298 
  299 static int
  300 sata_detach(device_t dev)
  301 {
  302         struct sata_softc *sc;
  303 
  304         sc = device_get_softc(dev);
  305 
  306         if (device_is_attached(dev))
  307                 bus_generic_detach(dev);
  308 
  309         if (sc->sc_mem_res != NULL) {
  310                 bus_release_resource(dev, SYS_RES_MEMORY,
  311                     rman_get_rid(sc->sc_mem_res), sc->sc_mem_res);
  312                 sc->sc_mem_res = NULL;
  313         }
  314 
  315         if (sc->sc_irq_res != NULL) {
  316                 bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_irq_cookiep);
  317                 bus_release_resource(dev, SYS_RES_IRQ,
  318                     rman_get_rid(sc->sc_irq_res), sc->sc_irq_res);
  319                 sc->sc_irq_res = NULL;
  320         }
  321 
  322         return (0);
  323 }
  324 
  325 static struct resource *
  326 sata_alloc_resource(device_t dev, device_t child, int type, int *rid,
  327     u_long start, u_long end, u_long count, u_int flags)
  328 {
  329         struct sata_softc *sc;
  330 
  331         sc = device_get_softc(dev);
  332 
  333         KASSERT(type == SYS_RES_IRQ && *rid == ATA_IRQ_RID,
  334             ("illegal resource request (type %u, rid %u).",
  335             type, *rid));
  336 
  337         return (sc->sc_irq_res);
  338 }
  339 
  340 static int
  341 sata_release_resource(device_t dev, device_t child, int type, int rid,
  342     struct resource *r)
  343 {
  344 
  345         KASSERT(type == SYS_RES_IRQ && rid == ATA_IRQ_RID,
  346             ("strange type %u and/or rid %u while releasing resource.", type,
  347             rid));
  348 
  349         return (0);
  350 }
  351 
  352 static int
  353 sata_setup_intr(device_t dev, device_t child, struct resource *irq, int flags,
  354     driver_filter_t *filt, driver_intr_t *function, void *argument,
  355     void **cookiep)
  356 {
  357         struct sata_softc *sc;
  358         struct ata_channel *ch;
  359 
  360         sc = device_get_softc(dev);
  361         ch = device_get_softc(child);
  362 
  363         if (filt != NULL) {
  364                 device_printf(dev, "filter interrupts are not supported.\n");
  365                 return (EINVAL);
  366         }
  367 
  368         sc->sc_interrupt[ch->unit].function = function;
  369         sc->sc_interrupt[ch->unit].argument = argument;
  370         *cookiep = sc;
  371 
  372         return (0);
  373 }
  374 
  375 static int
  376 sata_teardown_intr(device_t dev, device_t child, struct resource *irq,
  377     void *cookie)
  378 {
  379         struct sata_softc *sc;
  380         struct ata_channel *ch;
  381 
  382         sc = device_get_softc(dev);
  383         ch = device_get_softc(child);
  384 
  385         sc->sc_interrupt[ch->unit].function = NULL;
  386         sc->sc_interrupt[ch->unit].argument = NULL;
  387 
  388         return (0);
  389 }
  390 
  391 static void
  392 sata_intr(void *xsc)
  393 {
  394         struct sata_softc *sc;
  395         int unit;
  396 
  397         sc = xsc;
  398 
  399         /*
  400          * Behave like ata_generic_intr() for PCI controllers.
  401          * Simply invoke ISRs on all channels.
  402          */
  403         for (unit = 0; unit < SATA_CHAN_NUM; unit++)
  404                 if (sc->sc_interrupt[unit].function != NULL)
  405                         sc->sc_interrupt[unit].function(
  406                             sc->sc_interrupt[unit].argument);
  407 }
  408 
  409 static int
  410 sata_channel_probe(device_t dev)
  411 {
  412 
  413         device_set_desc(dev, "Marvell Integrated SATA Channel");
  414         return (ata_probe(dev));
  415 }
  416 
  417 static int
  418 sata_channel_attach(device_t dev)
  419 {
  420         struct sata_softc *sc;
  421         struct ata_channel *ch;
  422         uint64_t work;
  423         int error, i;
  424 
  425         sc = device_get_softc(device_get_parent(dev));
  426         ch = device_get_softc(dev);
  427 
  428         if (ch->attached)
  429                 return (0);
  430 
  431         ch->dev = dev;
  432         ch->unit = device_get_unit(dev);
  433         ch->flags |= ATA_USE_16BIT | ATA_NO_SLAVE | ATA_SATA;
  434 
  435         /* Set legacy ATA resources. */
  436         for (i = ATA_DATA; i <= ATA_COMMAND; i++) {
  437                 ch->r_io[i].res = sc->sc_mem_res;
  438                 ch->r_io[i].offset = SATA_SHADOWR_BASE(ch->unit) + (i << 2);
  439         }
  440 
  441         ch->r_io[ATA_CONTROL].res = sc->sc_mem_res;
  442         ch->r_io[ATA_CONTROL].offset = SATA_SHADOWR_CONTROL(ch->unit);
  443 
  444         ch->r_io[ATA_IDX_ADDR].res = sc->sc_mem_res;
  445         ata_default_registers(dev);
  446 
  447         /* Set SATA resources. */
  448         ch->r_io[ATA_SSTATUS].res = sc->sc_mem_res;
  449         ch->r_io[ATA_SSTATUS].offset = SATA_SATA_SSTATUS(ch->unit);
  450         ch->r_io[ATA_SERROR].res = sc->sc_mem_res;
  451         ch->r_io[ATA_SERROR].offset = SATA_SATA_SERROR(ch->unit);
  452         ch->r_io[ATA_SCONTROL].res = sc->sc_mem_res;
  453         ch->r_io[ATA_SCONTROL].offset = SATA_SATA_SCONTROL(ch->unit);
  454         ata_generic_hw(dev);
  455 
  456         ch->hw.begin_transaction = sata_channel_begin_transaction;
  457         ch->hw.end_transaction = sata_channel_end_transaction;
  458         ch->hw.status = sata_channel_status;
  459 
  460         /* Set DMA resources */
  461         ata_dmainit(dev);
  462         ch->dma.setprd = sata_channel_dmasetprd;
  463 
  464         /* Clear work area */
  465         KASSERT(sc->sc_edma_qlen * (sizeof(struct sata_crqb) +
  466             sizeof(struct sata_crpb)) <= ch->dma.max_iosize,
  467             ("insufficient DMA memory for request/response queues.\n"));
  468         bzero(ch->dma.work, sc->sc_edma_qlen * (sizeof(struct sata_crqb) +
  469             sizeof(struct sata_crpb)));
  470         bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
  471             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  472 
  473         /* Turn off EDMA engine */
  474         error = sata_edma_ctrl(dev, 0);
  475         if (error) {
  476                 ata_dmafini(dev);
  477                 return (error);
  478         }
  479 
  480         /*
  481          * Initialize EDMA engine:
  482          *      - Native Command Queuing off,
  483          *      - Non-Queued operation,
  484          *      - Host Queue Cache enabled.
  485          */
  486         SATA_OUTL(sc, SATA_EDMA_CFG(ch->unit), SATA_EDMA_CFG_HQCACHE |
  487             (sc->sc_version == 1) ? SATA_EDMA_CFG_QL128 : 0);
  488 
  489         /* Set request queue pointers */
  490         work = ch->dma.work_bus;
  491         SATA_OUTL(sc, SATA_EDMA_REQBAHR(ch->unit), work >> 32);
  492         SATA_OUTL(sc, SATA_EDMA_REQIPR(ch->unit), work & 0xFFFFFFFF);
  493         SATA_OUTL(sc, SATA_EDMA_REQOPR(ch->unit), work & 0xFFFFFFFF);
  494 
  495         /* Set response queue pointers */
  496         work += sc->sc_edma_qlen * sizeof(struct sata_crqb);
  497         SATA_OUTL(sc, SATA_EDMA_RESBAHR(ch->unit), work >> 32);
  498         SATA_OUTL(sc, SATA_EDMA_RESIPR(ch->unit), work & 0xFFFFFFFF);
  499         SATA_OUTL(sc, SATA_EDMA_RESOPR(ch->unit), work & 0xFFFFFFFF);
  500 
  501         /* Clear any outstanding interrupts */
  502         ATA_IDX_OUTL(ch, ATA_SERROR, ATA_IDX_INL(ch, ATA_SERROR));
  503         SATA_OUTL(sc, SATA_SATA_FISICR(ch->unit), 0);
  504         SATA_OUTL(sc, SATA_EDMA_IECR(ch->unit), 0);
  505         SATA_OUTL(sc, SATA_ICR,
  506             ~(SATA_ICR_DEV(ch->unit) | SATA_ICR_DMADONE(ch->unit)));
  507 
  508         /* Umask channel interrupts */
  509         SATA_OUTL(sc, SATA_EDMA_IEMR(ch->unit), 0xFFFFFFFF);
  510         SATA_OUTL(sc, SATA_MIMR, SATA_INL(sc, SATA_MIMR) |
  511             SATA_MICR_DONE(ch->unit) | SATA_MICR_DMADONE(ch->unit) |
  512             SATA_MICR_ERR(ch->unit));
  513 
  514         ch->attached = 1;
  515 
  516         return (ata_attach(dev));
  517 }
  518 
  519 static int
  520 sata_channel_detach(device_t dev)
  521 {
  522         struct sata_softc *sc;
  523         struct ata_channel *ch;
  524         int error;
  525 
  526         sc = device_get_softc(device_get_parent(dev));
  527         ch = device_get_softc(dev);
  528 
  529         if (!ch->attached)
  530                 return (0);
  531 
  532         /* Turn off EDMA engine */
  533         sata_edma_ctrl(dev, 0);
  534 
  535         /* Mask chanel interrupts */
  536         SATA_OUTL(sc, SATA_EDMA_IEMR(ch->unit), 0);
  537         SATA_OUTL(sc, SATA_MIMR, SATA_INL(sc, SATA_MIMR) & ~(
  538             SATA_MICR_DONE(ch->unit) | SATA_MICR_DMADONE(ch->unit) |
  539             SATA_MICR_ERR(ch->unit)));
  540 
  541         error = ata_detach(dev);
  542         ata_dmafini(dev);
  543 
  544         ch->attached = 0;
  545 
  546         return (error);
  547 }
  548 
  549 static int
  550 sata_channel_begin_transaction(struct ata_request *request)
  551 {
  552         struct sata_softc *sc;
  553         struct ata_channel *ch;
  554         struct sata_crqb *crqb;
  555         uint32_t req_in;
  556         int error, slot;
  557 
  558         sc = device_get_softc(device_get_parent(request->parent));
  559         ch = device_get_softc(request->parent);
  560 
  561         mtx_assert(&ch->state_mtx, MA_OWNED);
  562 
  563         /* Only DMA R/W goes through the EDMA machine. */
  564         if (request->u.ata.command != ATA_READ_DMA &&
  565             request->u.ata.command != ATA_WRITE_DMA &&
  566             request->u.ata.command != ATA_READ_DMA48 &&
  567             request->u.ata.command != ATA_WRITE_DMA48) {
  568 
  569                 /* Disable EDMA before accessing legacy registers */
  570                 if (sata_edma_is_running(request->parent)) {
  571                         error = sata_edma_ctrl(request->parent, 0);
  572                         if (error) {
  573                                 request->result = error;
  574                                 return (ATA_OP_FINISHED);
  575                         }
  576                 }
  577 
  578                 return (ata_begin_transaction(request));
  579         }
  580 
  581         /* Prepare data for DMA */
  582         if ((error = ch->dma.load(request, NULL, NULL))) {
  583                 device_printf(request->parent, "setting up DMA failed!\n");
  584                 request->result = error;
  585                 return ATA_OP_FINISHED;
  586         }
  587 
  588         /* Get next free queue slot */
  589         req_in = SATA_INL(sc, SATA_EDMA_REQIPR(ch->unit));
  590         slot = (req_in & sc->sc_edma_reqis_mask) >> SATA_EDMA_REQIS_OFS;
  591         crqb = (struct sata_crqb *)(ch->dma.work +
  592             (slot << SATA_EDMA_REQIS_OFS));
  593 
  594         /* Fill in request */
  595         bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
  596             BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  597 
  598         crqb->crqb_prdlo = htole32((uint64_t)request->dma->sg_bus & 0xFFFFFFFF);
  599         crqb->crqb_prdhi = htole32((uint64_t)request->dma->sg_bus >> 32);
  600         crqb->crqb_flags = htole32((request->flags & ATA_R_READ ? 0x01 : 0x00) |
  601             (request->tag << 1));
  602 
  603         crqb->crqb_ata_command = request->u.ata.command;
  604         crqb->crqb_ata_feature = request->u.ata.feature;
  605         crqb->crqb_ata_lba_low = request->u.ata.lba;
  606         crqb->crqb_ata_lba_mid = request->u.ata.lba >> 8;
  607         crqb->crqb_ata_lba_high = request->u.ata.lba >> 16;
  608         crqb->crqb_ata_device = ((request->u.ata.lba >> 24) & 0x0F) | (1 << 6);
  609         crqb->crqb_ata_lba_low_p = request->u.ata.lba >> 24;
  610         crqb->crqb_ata_lba_mid_p = request->u.ata.lba >> 32;
  611         crqb->crqb_ata_lba_high_p = request->u.ata.lba >> 40;
  612         crqb->crqb_ata_feature_p = request->u.ata.feature >> 8;
  613         crqb->crqb_ata_count = request->u.ata.count;
  614         crqb->crqb_ata_count_p = request->u.ata.count >> 8;
  615 
  616         bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
  617             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  618 
  619         /* Enable EDMA if disabled */
  620         if (!sata_edma_is_running(request->parent)) {
  621                 error = sata_edma_ctrl(request->parent, 1);
  622                 if (error) {
  623                         ch->dma.unload(request);
  624                         request->result = error;
  625                         return (ATA_OP_FINISHED);
  626                 }
  627         }
  628 
  629         /* Tell EDMA about new request */
  630         req_in = (req_in & ~sc->sc_edma_reqis_mask) | (((slot + 1) <<
  631             SATA_EDMA_REQIS_OFS) & sc->sc_edma_reqis_mask);
  632 
  633         SATA_OUTL(sc, SATA_EDMA_REQIPR(ch->unit), req_in);
  634 
  635         return (ATA_OP_CONTINUES);
  636 }
  637 
  638 static int
  639 sata_channel_end_transaction(struct ata_request *request)
  640 {
  641         struct sata_softc *sc;
  642         struct ata_channel *ch;
  643         struct sata_crpb *crpb;
  644         uint32_t res_in, res_out, icr;
  645         int slot;
  646 
  647         sc = device_get_softc(device_get_parent(request->parent));
  648         ch = device_get_softc(request->parent);
  649 
  650         mtx_assert(&ch->state_mtx, MA_OWNED);
  651 
  652         icr = SATA_INL(sc, SATA_ICR);
  653         if (icr & SATA_ICR_DMADONE(ch->unit)) {
  654                 /* Get current response slot */
  655                 res_out = SATA_INL(sc, SATA_EDMA_RESOPR(ch->unit));
  656                 slot = (res_out & sc->sc_edma_resos_mask) >>
  657                     SATA_EDMA_RESOS_OFS;
  658                 crpb = (struct sata_crpb *)(ch->dma.work +
  659                     (sc->sc_edma_qlen * sizeof(struct sata_crqb)) +
  660                     (slot << SATA_EDMA_RESOS_OFS));
  661 
  662                 /* Record this request status */
  663                 bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
  664                     BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  665 
  666                 request->status = crpb->crpb_dev_status;
  667                 request->error = 0;
  668 
  669                 bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
  670                     BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  671 
  672                 /* Update response queue pointer */
  673                 res_out = (res_out & ~sc->sc_edma_resos_mask) | (((slot + 1) <<
  674                     SATA_EDMA_RESOS_OFS) & sc->sc_edma_resos_mask);
  675 
  676                 SATA_OUTL(sc, SATA_EDMA_RESOPR(ch->unit), res_out);
  677 
  678                 /* Ack DMA interrupt if there is nothing more to do */
  679                 res_in = SATA_INL(sc, SATA_EDMA_RESIPR(ch->unit));
  680                 res_in &= sc->sc_edma_resos_mask;
  681                 res_out &= sc->sc_edma_resos_mask;
  682 
  683                 if (res_in == res_out)
  684                         SATA_OUTL(sc, SATA_ICR,
  685                             ~SATA_ICR_DMADONE(ch->unit));
  686 
  687                 /* Update progress */
  688                 if (!(request->status & ATA_S_ERROR) &&
  689                     !(request->flags & ATA_R_TIMEOUT))
  690                         request->donecount = request->bytecount;
  691 
  692                 /* Unload DMA data */
  693                 ch->dma.unload(request);
  694 
  695                 return(ATA_OP_FINISHED);
  696         }
  697 
  698         /* Legacy ATA interrupt */
  699         return (ata_end_transaction(request));
  700 }
  701 
  702 static int
  703 sata_channel_status(device_t dev)
  704 {
  705         struct sata_softc *sc;
  706         struct ata_channel *ch;
  707         uint32_t icr, iecr;
  708 
  709         sc = device_get_softc(device_get_parent(dev));
  710         ch = device_get_softc(dev);
  711 
  712         icr = SATA_INL(sc, SATA_ICR);
  713         iecr = SATA_INL(sc, SATA_EDMA_IECR(ch->unit));
  714 
  715         if ((icr & SATA_ICR_DEV(ch->unit)) || iecr) {
  716                 /* Disable EDMA before accessing SATA registers */
  717                 sata_edma_ctrl(dev, 0);
  718                 ata_sata_phy_check_events(dev, -1);
  719 
  720                 /* Ack device and error interrupt */
  721                 SATA_OUTL(sc, SATA_ICR, ~SATA_ICR_DEV(ch->unit));
  722                 SATA_OUTL(sc, SATA_EDMA_IECR(ch->unit), 0);
  723         }
  724 
  725         icr &= SATA_ICR_DEV(ch->unit) | SATA_ICR_DMADONE(ch->unit);
  726         return (icr);
  727 }
  728 
  729 static void
  730 sata_channel_reset(device_t dev)
  731 {
  732         struct sata_softc *sc;
  733         struct ata_channel *ch;
  734 
  735         sc = device_get_softc(device_get_parent(dev));
  736         ch = device_get_softc(dev);
  737 
  738         /* Disable EDMA before using legacy registers */
  739         sata_edma_ctrl(dev, 0);
  740 
  741         /* Mask all EDMA interrups */
  742         SATA_OUTL(sc, SATA_EDMA_IEMR(ch->unit), 0);
  743 
  744         /* Reset EDMA */
  745         SATA_OUTL(sc, SATA_EDMA_CMD(ch->unit), SATA_EDMA_CMD_RESET);
  746         DELAY(25);
  747         SATA_OUTL(sc, SATA_EDMA_CMD(ch->unit), 0);
  748 
  749         /* Reset PHY and device */
  750         if (ata_sata_phy_reset(dev, -1, 1))
  751                 ata_generic_reset(dev);
  752         else
  753                 ch->devices = 0;
  754 
  755         /* Clear EDMA errors */
  756         SATA_OUTL(sc, SATA_SATA_FISICR(ch->unit), 0);
  757         SATA_OUTL(sc, SATA_EDMA_IECR(ch->unit), 0);
  758 
  759         /* Unmask all EDMA interrups */
  760         SATA_OUTL(sc, SATA_EDMA_IEMR(ch->unit), 0xFFFFFFFF);
  761 }
  762 
  763 static int
  764 sata_channel_setmode(device_t parent, int target, int mode)
  765 {
  766 
  767         /* Disable EDMA before using legacy registers */
  768         sata_edma_ctrl(parent, 0);
  769         return (ata_sata_setmode(parent, target, mode));
  770 }
  771 
  772 static int
  773 sata_channel_getrev(device_t parent, int target)
  774 {
  775 
  776         /* Disable EDMA before using legacy registers */
  777         sata_edma_ctrl(parent, 0);
  778         return (ata_sata_getrev(parent, target));
  779 }
  780 
  781 static void
  782 sata_channel_dmasetprd(void *xsc, bus_dma_segment_t *segs, int nsegs,
  783     int error)
  784 {
  785         struct ata_dmasetprd_args *args;
  786         struct sata_prdentry *prd;
  787         int i;
  788 
  789         args = xsc;
  790         prd = args->dmatab;
  791 
  792         if ((args->error = error))
  793                 return;
  794 
  795         for (i = 0; i < nsegs; i++) {
  796                 prd[i].prd_addrlo = htole32(segs[i].ds_addr);
  797                 prd[i].prd_addrhi = htole32((uint64_t)segs[i].ds_addr >> 32);
  798                 prd[i].prd_count = htole32(segs[i].ds_len);
  799         }
  800 
  801         prd[i - 1].prd_count |= htole32(ATA_DMA_EOT);
  802         KASSERT(nsegs <= ATA_DMA_ENTRIES, ("too many DMA segment entries.\n"));
  803         args->nsegs = nsegs;
  804 }
  805 
  806 static int
  807 sata_edma_ctrl(device_t dev, int on)
  808 {
  809         struct sata_softc *sc;
  810         struct ata_channel *ch;
  811         int bit, timeout;
  812         uint32_t reg;
  813 
  814         sc = device_get_softc(device_get_parent(dev));
  815         ch = device_get_softc(dev);
  816         bit = on ? SATA_EDMA_CMD_ENABLE : SATA_EDMA_CMD_DISABLE;
  817         timeout = EDMA_TIMEOUT;
  818 
  819         SATA_OUTL(sc, SATA_EDMA_CMD(ch->unit), bit);
  820 
  821         while (1) {
  822                 DELAY(1);
  823 
  824                 reg = SATA_INL(sc, SATA_EDMA_CMD(ch->unit));
  825 
  826                 /* Enable bit will be 1 after disable command completion */
  827                 if (on && (reg & SATA_EDMA_CMD_ENABLE))
  828                         break;
  829 
  830                 /* Disable bit will be 0 after disable command completion */
  831                 if (!on && !(reg & SATA_EDMA_CMD_DISABLE))
  832                         break;
  833 
  834                 if (timeout-- <= 0) {
  835                         device_printf(dev, "EDMA command timeout!\n");
  836                         return (ETIMEDOUT);
  837                 }
  838         }
  839 
  840         return (0);
  841 }
  842 
  843 static int
  844 sata_edma_is_running(device_t dev)
  845 {
  846         struct sata_softc *sc;
  847         struct ata_channel *ch;
  848 
  849         sc = device_get_softc(device_get_parent(dev));
  850         ch = device_get_softc(dev);
  851 
  852         return (SATA_INL(sc, SATA_EDMA_CMD(ch->unit)) & SATA_EDMA_CMD_ENABLE);
  853 }
  854 
  855 static device_method_t sata_channel_methods[] = {
  856         /* Device interface. */
  857         DEVMETHOD(device_probe,         sata_channel_probe),
  858         DEVMETHOD(device_attach,        sata_channel_attach),
  859         DEVMETHOD(device_detach,        sata_channel_detach),
  860         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
  861         DEVMETHOD(device_suspend,       ata_suspend),
  862         DEVMETHOD(device_resume,        ata_resume),
  863 
  864         /* ATA channel interface */
  865         DEVMETHOD(ata_reset,            sata_channel_reset),
  866         DEVMETHOD(ata_setmode,          sata_channel_setmode),
  867         DEVMETHOD(ata_getrev,           sata_channel_getrev),
  868         { 0, 0 }
  869 };
  870 
  871 driver_t sata_channel_driver = {
  872         "ata",
  873         sata_channel_methods,
  874         sizeof(struct ata_channel),
  875 };
  876 
  877 DRIVER_MODULE(ata, sata, sata_channel_driver, ata_devclass, 0, 0);

Cache object: ed56444052e53d96bbe5764da37693f8


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