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/ata/chipsets/ata-via.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  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 1998 - 2008 Søren Schmidt <sos@FreeBSD.org>
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer,
   12  *    without modification, immediately at the beginning of the file.
   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 ``AS IS'' AND ANY EXPRESS OR
   18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27  */
   28 
   29 #include <sys/cdefs.h>
   30 __FBSDID("$FreeBSD$");
   31 
   32 #include <sys/param.h>
   33 #include <sys/module.h>
   34 #include <sys/systm.h>
   35 #include <sys/kernel.h>
   36 #include <sys/ata.h>
   37 #include <sys/bus.h>
   38 #include <sys/endian.h>
   39 #include <sys/malloc.h>
   40 #include <sys/lock.h>
   41 #include <sys/mutex.h>
   42 #include <sys/sema.h>
   43 #include <sys/taskqueue.h>
   44 #include <vm/uma.h>
   45 #include <machine/stdarg.h>
   46 #include <machine/resource.h>
   47 #include <machine/bus.h>
   48 #include <sys/rman.h>
   49 #include <dev/pci/pcivar.h>
   50 #include <dev/pci/pcireg.h>
   51 #include <dev/ata/ata-all.h>
   52 #include <dev/ata/ata-pci.h>
   53 #include <ata_if.h>
   54 
   55 /* local prototypes */
   56 static int ata_via_chipinit(device_t dev);
   57 static int ata_via_ch_attach(device_t dev);
   58 static int ata_via_ch_detach(device_t dev);
   59 static void ata_via_reset(device_t dev);
   60 static int ata_via_status(device_t dev);
   61 static int ata_via_old_setmode(device_t dev, int target, int mode);
   62 static void ata_via_southbridge_fixup(device_t dev);
   63 static int ata_via_new_setmode(device_t dev, int target, int mode);
   64 static int ata_via_sata_ch_attach(device_t dev);
   65 static int ata_via_sata_getrev(device_t dev, int target);
   66 static int ata_via_sata_setmode(device_t dev, int target, int mode);
   67 static void ata_via_sata_reset(device_t dev);
   68 static int ata_via_sata_scr_read(device_t dev, int port, int reg,
   69     u_int32_t *result);
   70 static int ata_via_sata_scr_write(device_t dev, int port, int reg,
   71     u_int32_t value);
   72 static int ata_via_sata_status(device_t dev);
   73 
   74 /* misc defines */
   75 #define VIA33           0
   76 #define VIA66           1
   77 #define VIA100          2
   78 #define VIA133          3
   79 
   80 #define VIACLK          0x01
   81 #define VIABUG          0x02
   82 #define VIABAR          0x04
   83 #define VIASATA         0x10
   84 
   85 /*
   86  * VIA Technologies Inc. chipset support functions
   87  */
   88 static int
   89 ata_via_probe(device_t dev)
   90 {
   91     struct ata_pci_controller *ctlr = device_get_softc(dev);
   92     static const struct ata_chip_id ids[] =
   93     {{ ATA_VIA82C586, 0x02, VIA33,  0x00,    ATA_UDMA2, "82C586B" },
   94      { ATA_VIA82C586, 0x00, VIA33,  0x00,    ATA_WDMA2, "82C586" },
   95      { ATA_VIA82C596, 0x12, VIA66,  VIACLK,  ATA_UDMA4, "82C596B" },
   96      { ATA_VIA82C596, 0x00, VIA33,  0x00,    ATA_UDMA2, "82C596" },
   97      { ATA_VIA82C686, 0x40, VIA100, VIABUG,  ATA_UDMA5, "82C686B"},
   98      { ATA_VIA82C686, 0x10, VIA66,  VIACLK,  ATA_UDMA4, "82C686A" },
   99      { ATA_VIA82C686, 0x00, VIA33,  0x00,    ATA_UDMA2, "82C686" },
  100      { ATA_VIA8231,   0x00, VIA100, VIABUG,  ATA_UDMA5, "8231" },
  101      { ATA_VIA8233,   0x00, VIA100, 0x00,    ATA_UDMA5, "8233" },
  102      { ATA_VIA8233C,  0x00, VIA100, 0x00,    ATA_UDMA5, "8233C" },
  103      { ATA_VIA8233A,  0x00, VIA133, 0x00,    ATA_UDMA6, "8233A" },
  104      { ATA_VIA8235,   0x00, VIA133, 0x00,    ATA_UDMA6, "8235" },
  105      { ATA_VIA8237,   0x00, VIA133, 0x00,    ATA_UDMA6, "8237" },
  106      { ATA_VIA8237A,  0x00, VIA133, 0x00,    ATA_UDMA6, "8237A" },
  107      { ATA_VIA8237S,  0x00, VIA133, 0x00,    ATA_UDMA6, "8237S" },
  108      { ATA_VIA8237_5372, 0x00, VIA133, 0x00, ATA_UDMA6, "8237" },
  109      { ATA_VIA8237_7372, 0x00, VIA133, 0x00, ATA_UDMA6, "8237" },
  110      { ATA_VIA8251,   0x00, VIA133, 0x00,    ATA_UDMA6, "8251" },
  111      { ATA_VIACX700,  0x00, VIA133, VIASATA, ATA_SA150, "CX700" },
  112      { ATA_VIAVX800,  0x00, VIA133, VIASATA, ATA_SA150, "VX800" },
  113      { ATA_VIAVX855,  0x00, VIA133, 0x00,    ATA_UDMA6, "VX855" },
  114      { ATA_VIAVX900,  0x00, VIA133, VIASATA, ATA_SA300, "VX900" },
  115      { 0, 0, 0, 0, 0, 0 }};
  116     static const struct ata_chip_id new_ids[] =
  117     {{ ATA_VIA6410,   0x00, 0,      0x00,    ATA_UDMA6, "6410" },
  118      { ATA_VIA6420,   0x00, 7,      0x00,    ATA_SA150, "6420" },
  119      { ATA_VIA6421,   0x00, 6,      VIABAR,  ATA_SA150, "6421" },
  120      { ATA_VIA8237A,  0x00, 7,      0x00,    ATA_SA150, "8237A" },
  121      { ATA_VIA8237S,  0x00, 7,      0x00,    ATA_SA150, "8237S" },
  122      { ATA_VIA8237_5372, 0x00, 7,   0x00,    ATA_SA300, "8237" },
  123      { ATA_VIA8237_7372, 0x00, 7,   0x00,    ATA_SA300, "8237" },
  124      { 0, 0, 0, 0, 0, 0 }};
  125 
  126     if (pci_get_vendor(dev) != ATA_VIA_ID)
  127         return ENXIO;
  128 
  129     if (pci_get_devid(dev) == ATA_VIA82C571 ||
  130         pci_get_devid(dev) == ATA_VIACX700IDE ||
  131         pci_get_devid(dev) == ATA_VIASATAIDE ||
  132         pci_get_devid(dev) == ATA_VIASATAIDE2 ||
  133         pci_get_devid(dev) == ATA_VIASATAIDE3) {
  134         if (!(ctlr->chip = ata_find_chip(dev, ids, -99))) 
  135             return ENXIO;
  136     }
  137     else {
  138         if (!(ctlr->chip = ata_match_chip(dev, new_ids))) 
  139             return ENXIO;
  140     }
  141 
  142     ata_set_desc(dev);
  143     ctlr->chipinit = ata_via_chipinit;
  144     return (BUS_PROBE_LOW_PRIORITY);
  145 }
  146 
  147 static int
  148 ata_via_chipinit(device_t dev)
  149 {
  150     struct ata_pci_controller *ctlr = device_get_softc(dev);
  151 
  152     if (ata_setup_interrupt(dev, ata_generic_intr))
  153         return ENXIO;
  154 
  155     /* 2 SATA with "SATA registers" at PCI config space + PATA on secondary */
  156     if (ctlr->chip->cfg2 & VIASATA) {
  157         ctlr->ch_attach = ata_via_sata_ch_attach;
  158         ctlr->setmode = ata_via_sata_setmode;
  159         ctlr->getrev = ata_via_sata_getrev;
  160         ctlr->reset = ata_via_sata_reset;
  161         return 0;
  162     }
  163     /* Legacy SATA/SATA+PATA with SATA registers in BAR(5). */
  164     if (ctlr->chip->max_dma >= ATA_SA150) {
  165         ctlr->r_type2 = SYS_RES_IOPORT;
  166         ctlr->r_rid2 = PCIR_BAR(5);
  167         if ((ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2,
  168                                                    &ctlr->r_rid2, RF_ACTIVE))) {
  169             ctlr->ch_attach = ata_via_ch_attach;
  170             ctlr->ch_detach = ata_via_ch_detach;
  171             ctlr->reset = ata_via_reset;
  172         }
  173         if (ctlr->chip->cfg2 & VIABAR) {
  174             ctlr->channels = 3;
  175             ctlr->setmode = ata_via_new_setmode;
  176         } else
  177             ctlr->setmode = ata_sata_setmode;
  178         ctlr->getrev = ata_sata_getrev;
  179         return 0;
  180     }
  181 
  182     /* prepare for ATA-66 on the 82C686a and 82C596b */
  183     if (ctlr->chip->cfg2 & VIACLK)
  184         pci_write_config(dev, 0x50, 0x030b030b, 4);       
  185 
  186     /* the southbridge might need the data corruption fix */
  187     if (ctlr->chip->cfg2 & VIABUG)
  188         ata_via_southbridge_fixup(dev);
  189 
  190     /* set fifo configuration half'n'half */
  191     pci_write_config(dev, 0x43, 
  192                      (pci_read_config(dev, 0x43, 1) & 0x90) | 0x2a, 1);
  193 
  194     /* set status register read retry */
  195     pci_write_config(dev, 0x44, pci_read_config(dev, 0x44, 1) | 0x08, 1);
  196 
  197     /* set DMA read & end-of-sector fifo flush */
  198     pci_write_config(dev, 0x46, 
  199                      (pci_read_config(dev, 0x46, 1) & 0x0c) | 0xf0, 1);
  200 
  201     /* set sector size */
  202     pci_write_config(dev, 0x60, DEV_BSIZE, 2);
  203     pci_write_config(dev, 0x68, DEV_BSIZE, 2);
  204 
  205     ctlr->setmode = ata_via_old_setmode;
  206     return 0;
  207 }
  208 
  209 static int
  210 ata_via_ch_attach(device_t dev)
  211 {
  212     struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
  213     struct ata_channel *ch = device_get_softc(dev);
  214 
  215     /* newer SATA chips has resources in one BAR for each channel */
  216     if (ctlr->chip->cfg2 & VIABAR) {
  217         struct resource *r_io;
  218         int i, rid;
  219                 
  220         ata_pci_dmainit(dev);
  221 
  222         rid = PCIR_BAR(ch->unit);
  223         if (!(r_io = bus_alloc_resource_any(device_get_parent(dev),
  224                                             SYS_RES_IOPORT,
  225                                             &rid, RF_ACTIVE)))
  226             return ENXIO;
  227 
  228         for (i = ATA_DATA; i <= ATA_COMMAND; i ++) {
  229             ch->r_io[i].res = r_io;
  230             ch->r_io[i].offset = i;
  231         }
  232         ch->r_io[ATA_CONTROL].res = r_io;
  233         ch->r_io[ATA_CONTROL].offset = 2 + ATA_IOSIZE;
  234         ch->r_io[ATA_IDX_ADDR].res = r_io;
  235         ata_default_registers(dev);
  236         for (i = ATA_BMCMD_PORT; i <= ATA_BMDTP_PORT; i++) {
  237             ch->r_io[i].res = ctlr->r_res1;
  238             ch->r_io[i].offset = (i - ATA_BMCMD_PORT)+(ch->unit * ATA_BMIOSIZE);
  239         }
  240         ata_pci_hw(dev);
  241         if (ch->unit >= 2)
  242             return 0;
  243     }
  244     else {
  245         /* setup the usual register normal pci style */
  246         if (ata_pci_ch_attach(dev))
  247             return ENXIO;
  248     }
  249 
  250     ch->r_io[ATA_SSTATUS].res = ctlr->r_res2;
  251     ch->r_io[ATA_SSTATUS].offset = (ch->unit << ctlr->chip->cfg1);
  252     ch->r_io[ATA_SERROR].res = ctlr->r_res2;
  253     ch->r_io[ATA_SERROR].offset = 0x04 + (ch->unit << ctlr->chip->cfg1);
  254     ch->r_io[ATA_SCONTROL].res = ctlr->r_res2;
  255     ch->r_io[ATA_SCONTROL].offset = 0x08 + (ch->unit << ctlr->chip->cfg1);
  256     ch->hw.status = ata_via_status;
  257     ch->flags |= ATA_NO_SLAVE;
  258     ch->flags |= ATA_SATA;
  259     ch->flags |= ATA_PERIODIC_POLL;
  260 
  261     ata_sata_scr_write(ch, -1, ATA_SERROR, 0xffffffff);
  262 
  263     return 0;
  264 }
  265 
  266 static int
  267 ata_via_ch_detach(device_t dev)
  268 {
  269     struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
  270     struct ata_channel *ch = device_get_softc(dev);
  271 
  272     /* newer SATA chips has resources in one BAR for each channel */
  273     if (ctlr->chip->cfg2 & VIABAR) {
  274         int rid;
  275                 
  276         rid = PCIR_BAR(ch->unit);
  277         bus_release_resource(device_get_parent(dev),
  278             SYS_RES_IOPORT, rid, ch->r_io[ATA_CONTROL].res);
  279 
  280         ata_pci_dmafini(dev);
  281     }
  282     else {
  283         /* setup the usual register normal pci style */
  284         if (ata_pci_ch_detach(dev))
  285             return ENXIO;
  286     }
  287 
  288     return 0;
  289 }
  290 
  291 static void
  292 ata_via_reset(device_t dev)
  293 {
  294     struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
  295     struct ata_channel *ch = device_get_softc(dev);
  296 
  297     if ((ctlr->chip->cfg2 & VIABAR) && (ch->unit > 1))
  298         ata_generic_reset(dev);
  299     else {
  300         if (ata_sata_phy_reset(dev, -1, 1))
  301             ata_generic_reset(dev);
  302         else
  303             ch->devices = 0;
  304     }
  305 }
  306 
  307 static int
  308 ata_via_status(device_t dev)
  309 {
  310 
  311         ata_sata_phy_check_events(dev, -1);
  312         return (ata_pci_status(dev));
  313 }
  314 
  315 static int
  316 ata_via_new_setmode(device_t dev, int target, int mode)
  317 {
  318         device_t parent = device_get_parent(dev);
  319         struct ata_pci_controller *ctlr = device_get_softc(parent);
  320         struct ata_channel *ch = device_get_softc(dev);
  321 
  322         if ((ctlr->chip->cfg2 & VIABAR) && (ch->unit > 1)) {
  323             int piomode;
  324             static const uint8_t pio_timings[] =
  325                 { 0xa8, 0x65, 0x65, 0x32, 0x20 };
  326             static const uint8_t dma_timings[] =
  327                 { 0xee, 0xe8, 0xe6, 0xe4, 0xe2, 0xe1, 0xe0 };
  328 
  329             /* This chip can't do WDMA. */
  330             if (mode >= ATA_WDMA0 && mode < ATA_UDMA0)
  331                 mode = ATA_PIO4;
  332             if (mode >= ATA_UDMA0) {
  333                 pci_write_config(parent, 0xb3,
  334                                  dma_timings[mode & ATA_MODE_MASK], 1);
  335                 piomode = ATA_PIO4;
  336             } else
  337                 piomode = mode;
  338             pci_write_config(parent, 0xab, pio_timings[ata_mode2idx(piomode)], 1);
  339         } else
  340                 mode = ata_sata_setmode(dev, target, mode);
  341         return (mode);
  342 }
  343 
  344 static int
  345 ata_via_old_setmode(device_t dev, int target, int mode)
  346 {
  347         device_t parent = device_get_parent(dev);
  348         struct ata_pci_controller *ctlr = device_get_softc(parent);
  349         struct ata_channel *ch = device_get_softc(dev);
  350         int devno = (ch->unit << 1) + target;
  351         int reg = 0x53 - devno;
  352         int piomode;
  353         static const uint8_t timings[] =
  354             { 0xa8, 0x65, 0x42, 0x22, 0x20, 0xa8, 0x22, 0x20 };
  355         static const uint8_t modes[][7] = {
  356             { 0xc2, 0xc1, 0xc0, 0x00, 0x00, 0x00, 0x00 },   /* VIA ATA33 */
  357             { 0xee, 0xec, 0xea, 0xe9, 0xe8, 0x00, 0x00 },   /* VIA ATA66 */
  358             { 0xf7, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0, 0x00 },   /* VIA ATA100 */
  359             { 0xf7, 0xf7, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0 } }; /* VIA ATA133 */
  360 
  361         mode = min(mode, ctlr->chip->max_dma);
  362         /* Set UDMA timings */
  363         if (mode >= ATA_UDMA0) {
  364             pci_write_config(parent, reg,
  365                              modes[ctlr->chip->cfg1][mode & ATA_MODE_MASK], 1);
  366             piomode = ATA_PIO4;
  367         } else {
  368             pci_write_config(parent, reg, 0x8b, 1);
  369             piomode = mode;
  370         }
  371         /* Set WDMA/PIO timings */
  372         pci_write_config(parent, reg - 0x08,timings[ata_mode2idx(piomode)], 1);
  373         return (mode);
  374 }
  375 
  376 static void
  377 ata_via_southbridge_fixup(device_t dev)
  378 {
  379     device_t *children;
  380     int nchildren, i;
  381 
  382     if (device_get_children(device_get_parent(dev), &children, &nchildren))
  383         return;
  384 
  385     for (i = 0; i < nchildren; i++) {
  386         if (pci_get_devid(children[i]) == ATA_VIA8363 ||
  387             pci_get_devid(children[i]) == ATA_VIA8371 ||
  388             pci_get_devid(children[i]) == ATA_VIA8662 ||
  389             pci_get_devid(children[i]) == ATA_VIA8361) {
  390             u_int8_t reg76 = pci_read_config(children[i], 0x76, 1);
  391 
  392             if ((reg76 & 0xf0) != 0xd0) {
  393                 device_printf(dev,
  394                 "Correcting VIA config for southbridge data corruption bug\n");
  395                 pci_write_config(children[i], 0x75, 0x80, 1);
  396                 pci_write_config(children[i], 0x76, (reg76 & 0x0f) | 0xd0, 1);
  397             }
  398             break;
  399         }
  400     }
  401     free(children, M_TEMP);
  402 }
  403 
  404 static int
  405 ata_via_sata_ch_attach(device_t dev)
  406 {
  407         struct ata_channel *ch = device_get_softc(dev);
  408 
  409         if (ata_pci_ch_attach(dev))
  410                 return ENXIO;
  411         if (ch->unit == 0) {
  412                 ch->hw.status = ata_via_sata_status;
  413                 ch->hw.pm_read = ata_via_sata_scr_read;
  414                 ch->hw.pm_write = ata_via_sata_scr_write;
  415                 ch->flags |= ATA_PERIODIC_POLL;
  416                 ch->flags |= ATA_SATA;
  417                 ata_sata_scr_write(ch, 0, ATA_SERROR, 0xffffffff);
  418                 ata_sata_scr_write(ch, 1, ATA_SERROR, 0xffffffff);
  419         }
  420         return (0);
  421 }
  422 
  423 static int
  424 ata_via_sata_getrev(device_t dev, int target)
  425 {
  426         device_t parent = device_get_parent(dev);
  427         struct ata_channel *ch = device_get_softc(dev);
  428 
  429         if (ch->unit == 0) {
  430                 if (pci_read_config(parent, 0xa0 + target, 1) & 0x10)
  431                         return (2);
  432                 else
  433                         return (1);
  434         }
  435         return (0);
  436 }
  437 
  438 static int
  439 ata_via_sata_setmode(device_t dev, int target, int mode)
  440 {
  441         struct ata_channel *ch = device_get_softc(dev);
  442 
  443         if (ch->unit == 0)
  444                 return (mode);
  445         return (ata_via_old_setmode(dev, target, mode));
  446 }
  447 
  448 static void
  449 ata_via_sata_reset(device_t dev)
  450 {
  451         struct ata_channel *ch = device_get_softc(dev);
  452         int devs, count;
  453         uint8_t status;
  454 
  455         if (ch->unit == 0) {
  456                 devs = ata_sata_phy_reset(dev, 0, 0);
  457                 count = 0;
  458                 do {
  459                         ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA |
  460                             ATA_DEV(ATA_MASTER));
  461                         DELAY(1000);
  462                         status = ATA_IDX_INB(ch, ATA_STATUS);
  463                         count++;
  464                 } while (status & ATA_S_BUSY && count < 100);
  465 
  466                 devs += ata_sata_phy_reset(dev, 1, 0);
  467                 count = 0;
  468                 do {
  469                         ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_D_LBA |
  470                             ATA_DEV(ATA_SLAVE));
  471                         DELAY(1000);
  472                         status = ATA_IDX_INB(ch, ATA_STATUS);
  473                         count++;
  474                 } while (status & ATA_S_BUSY && count < 100);
  475         } else
  476                 devs = 1;
  477         if (devs)
  478                 ata_generic_reset(dev);
  479         else
  480                 ch->devices = 0;
  481 }
  482 
  483 static int
  484 ata_via_sata_scr_read(device_t dev, int port, int reg, u_int32_t *result)
  485 {
  486         device_t parent;
  487         uint32_t val;
  488 
  489         parent = device_get_parent(dev);
  490         port = (port == 1) ? 1 : 0;
  491         switch (reg) {
  492         case ATA_SSTATUS:
  493                 val = pci_read_config(parent, 0xa0 + port, 1);
  494                 *result = val & 0x03;
  495                 if (*result != ATA_SS_DET_NO_DEVICE) {
  496                         if (val & 0x04)
  497                                 *result |= ATA_SS_IPM_PARTIAL;
  498                         else if (val & 0x08)
  499                                 *result |= ATA_SS_IPM_SLUMBER;
  500                         else
  501                                 *result |= ATA_SS_IPM_ACTIVE;
  502                         if (val & 0x10)
  503                                 *result |= ATA_SS_SPD_GEN2;
  504                         else
  505                                 *result |= ATA_SS_SPD_GEN1;
  506                 }
  507                 break;
  508         case ATA_SERROR:
  509                 *result = pci_read_config(parent, 0xa8 + port * 4, 4);
  510                 break;
  511         case ATA_SCONTROL:
  512                 val = pci_read_config(parent, 0xa4 + port, 1);
  513                 *result = 0;
  514                 if (val & 0x01)
  515                         *result |= ATA_SC_DET_RESET;
  516                 if (val & 0x02)
  517                         *result |= ATA_SC_DET_DISABLE;
  518                 if (val & 0x04)
  519                         *result |= ATA_SC_IPM_DIS_PARTIAL;
  520                 if (val & 0x08)
  521                         *result |= ATA_SC_IPM_DIS_SLUMBER;
  522                 break;
  523         default:
  524                 return (EINVAL);
  525         }
  526         return (0);
  527 }
  528 
  529 static int
  530 ata_via_sata_scr_write(device_t dev, int port, int reg, u_int32_t value)
  531 {
  532         device_t parent;
  533         uint32_t val;
  534 
  535         parent = device_get_parent(dev);
  536         port = (port == 1) ? 1 : 0;
  537         switch (reg) {
  538         case ATA_SERROR:
  539                 pci_write_config(parent, 0xa8 + port * 4, value, 4);
  540                 break;
  541         case ATA_SCONTROL:
  542                 val = 0;
  543                 if (value & ATA_SC_DET_RESET)
  544                         val |= 0x01;
  545                 if (value & ATA_SC_DET_DISABLE)
  546                         val |= 0x02;
  547                 if (value & ATA_SC_IPM_DIS_PARTIAL)
  548                         val |= 0x04;
  549                 if (value & ATA_SC_IPM_DIS_SLUMBER)
  550                         val |= 0x08;
  551                 pci_write_config(parent, 0xa4 + port, val, 1);
  552                 break;
  553         default:
  554                 return (EINVAL);
  555         }
  556         return (0);
  557 }
  558 
  559 static int
  560 ata_via_sata_status(device_t dev)
  561 {
  562 
  563         ata_sata_phy_check_events(dev, 0);
  564         ata_sata_phy_check_events(dev, 1);
  565         return (ata_pci_status(dev));
  566 }
  567 
  568 ATA_DECLARE_DRIVER(ata_via);

Cache object: 4f61c8bd9120f1253fa54c66e661a98b


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