LCOV - code coverage report
Current view: top level - dev/pci - ami_pci.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 92 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 3 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: ami_pci.c,v 1.43 2008/10/28 11:43:10 marco Exp $      */
       2             : 
       3             : /*
       4             :  * Copyright (c) 2001 Michael Shalayeff
       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             :  * 2. Redistributions in binary form must reproduce the above copyright
      13             :  *    notice, this list of conditions and the following disclaimer in the
      14             :  *    documentation and/or other materials provided with the distribution.
      15             :  *
      16             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
      17             :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      18             :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      19             :  * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
      20             :  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
      21             :  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      22             :  * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      23             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      24             :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
      25             :  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
      26             :  * THE POSSIBILITY OF SUCH DAMAGE.
      27             :  */
      28             : 
      29             : #include <sys/param.h>
      30             : #include <sys/systm.h>
      31             : #include <sys/kernel.h>
      32             : #include <sys/malloc.h>
      33             : #include <sys/device.h>
      34             : #include <sys/rwlock.h>
      35             : 
      36             : #include <dev/pci/pcidevs.h>
      37             : #include <dev/pci/pcivar.h>
      38             : 
      39             : #include <machine/bus.h>
      40             : 
      41             : #include <scsi/scsi_all.h>
      42             : #include <scsi/scsi_disk.h>
      43             : #include <scsi/scsiconf.h>
      44             : 
      45             : #include <dev/biovar.h>
      46             : #include <dev/ic/amireg.h>
      47             : #include <dev/ic/amivar.h>
      48             : 
      49             : #define AMI_BAR         PCI_MAPREG_START
      50             : #define AMI_PCI_MEMSIZE 0x1000
      51             : 
      52             : /* "Quartz" i960 Config space */
      53             : #define AMI_PCI_INIT    0x9c
      54             : #define         AMI_INITSTAT(i) (((i) >>  8) & 0xff)
      55             : #define         AMI_INITTARG(i) (((i) >> 16) & 0xff)
      56             : #define         AMI_INITCHAN(i) (((i) >> 24) & 0xff)
      57             : #define AMI_PCI_SIG     0xa0
      58             : #define         AMI_SIGNATURE_1 0xcccc          /* older adapters */
      59             : #define         AMI_SIGNATURE_2 0x3344          /* newer adapters */
      60             : #define AMI_PCI_SGL     0xa4
      61             : #define         AMI_SGL_LHC     0x00000299
      62             : #define         AMI_SGL_HLC     0x00000199
      63             : 
      64             : int     ami_pci_find_device(void *);
      65             : int     ami_pci_match(struct device *, void *, void *);
      66             : void    ami_pci_attach(struct device *, struct device *, void *);
      67             : 
      68             : struct cfattach ami_pci_ca = {
      69             :         sizeof(struct ami_softc), ami_pci_match, ami_pci_attach
      70             : };
      71             : 
      72             : static const
      73             : struct  ami_pci_device {
      74             :         int     vendor;
      75             :         int     product;
      76             :         int     flags;
      77             : } ami_pci_devices[] = {
      78             :         { PCI_VENDOR_AMI,       PCI_PRODUCT_AMI_MEGARAID,       0 },
      79             :         { PCI_VENDOR_AMI,       PCI_PRODUCT_AMI_MEGARAID428,    AMI_BROKEN },
      80             :         { PCI_VENDOR_AMI,       PCI_PRODUCT_AMI_MEGARAID434,    AMI_BROKEN },
      81             :         { PCI_VENDOR_DELL,      PCI_PRODUCT_DELL_PERC_4DI,      0 },
      82             :         { PCI_VENDOR_DELL,      PCI_PRODUCT_DELL_PERC_4DI_2,    0 },
      83             :         { PCI_VENDOR_DELL,      PCI_PRODUCT_DELL_PERC_4EDI,     0 },    
      84             :         { PCI_VENDOR_INTEL,     PCI_PRODUCT_INTEL_80960RP_ATU,
      85             :             AMI_CHECK_SIGN | AMI_BROKEN },
      86             :         { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_MEGARAID,           0 },
      87             :         { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_MEGARAID_320,       0 },
      88             :         { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_MEGARAID_3202E,     0 },
      89             :         { PCI_VENDOR_SYMBIOS,   PCI_PRODUCT_SYMBIOS_MEGARAID_SATA,      0 },
      90             :         { 0 }
      91             : };
      92             : 
      93             : static const
      94             : struct  ami_pci_subsys {
      95             :         pcireg_t        id;
      96             :         const char      *name;
      97             :         int             flags;
      98             : } ami_pci_subsys[] = {
      99             :         /* only those of a special name or quirk are listed here */
     100             :         { 0x004d1025,   "ACER MegaRAID ROMB-2E", 0},
     101             :         { 0x0511101e,   "AMI MegaRAID i4", AMI_BROKEN },
     102             :         { 0x04931028,   "Dell PERC3/DC", 0 },
     103             :         { 0x05181028,   "Dell PERC4/DC", 0 },
     104             :         { 0x09a0101e,   "Dell 466v1", 0 },
     105             :         { 0x11111111,   "Dell 466v2", 0 },
     106             :         { 0x11121111,   "Dell 438", 0 },
     107             :         { 0x11111028,   "Dell 466v3", 0 },
     108             :         { 0x10651734,   "FSC MegaRAID PCI Express ROMB", 0 },
     109             :         { 0x10c6103c,   "HP 438", 0 },
     110             :         { 0x10c7103c,   "HP T5/T6", 0 },
     111             :         { 0x10cc103c,   "HP T7", 0 },
     112             :         { 0x10cd103c,   "HP 466", 0 },
     113             :         { 0x45231000,   "LSI 523", 0 },
     114             :         { 0x05328086,   "Intel RAID SRCU42X", 0 },
     115             :         { 0x05238086,   "Intel RAID SRCS16", 0 },
     116             :         { 0x00028086,   "Intel RAID SRCU42E", 0 },
     117             :         { 0x05308086,   "Intel RAID SRCZCRX", 0 },
     118             :         { 0x30088086,   "Intel RAID SRCS28X", 0 },
     119             :         { 0x34318086,   "Intel RAID SROMBU42E", 0 },
     120             :         { 0x34998086,   "Intel RAID SROMBU42E", 0 },
     121             :         { 0x05208086,   "Intel RAID SRCU51L", 0 },
     122             :         { 0x82871033,   "NEC MegaRAID PCI Express ROMB", 0 },
     123             :         { 0, NULL, 0 }
     124             : };
     125             : 
     126             : static const
     127             : struct ami_pci_vendor {
     128             :         u_int16_t id;
     129             :         char name[8];
     130             : } ami_pci_vendors[] = {
     131             :         { 0x101e, "AMI" },
     132             :         { 0x1028, "Dell" },
     133             :         { 0x103c, "HP" },
     134             :         { 0x1000, "LSI" },
     135             :         { 0x8086, "Intel" },
     136             :         { 0 }
     137             : };
     138             : 
     139             : int
     140           0 : ami_pci_find_device(void *aux)
     141             : {
     142           0 :         struct pci_attach_args *pa = aux;
     143             :         int i;
     144             : 
     145           0 :         for (i = 0; ami_pci_devices[i].vendor; i++) {
     146           0 :                 if (ami_pci_devices[i].vendor == PCI_VENDOR(pa->pa_id) &&
     147           0 :                     ami_pci_devices[i].product == PCI_PRODUCT(pa->pa_id)) {
     148             : #ifdef AMI_DEBUG
     149             :                         printf(" apfd %i ", i);
     150             : #endif /* AMI_DEBUG */
     151           0 :                         return (i);
     152             :                 }
     153             :         }
     154             : 
     155           0 :         return (-1);
     156           0 : }
     157             : 
     158             : int
     159           0 : ami_pci_match(struct device *parent, void *match, void *aux)
     160             : {
     161           0 :         struct pci_attach_args *pa = aux;
     162             :         pcireg_t sig;
     163             :         int i;
     164             : 
     165           0 :         if (PCI_CLASS(pa->pa_class) == PCI_CLASS_I2O)
     166           0 :                 return (0);
     167             : 
     168           0 :         if ((i = ami_pci_find_device(aux)) != -1) {
     169             : #ifdef AMI_DEBUG
     170             :                 printf("\nvendor: %04x  product: %04x\n",
     171             :                         ami_pci_devices[i].vendor,
     172             :                         ami_pci_devices[i].product);
     173             : #endif /* AMI_DEBUG */
     174             : 
     175           0 :                 if (!(ami_pci_devices[i].flags & AMI_CHECK_SIGN))
     176           0 :                         return (1);
     177             :                 /* some cards have 0x11223344, but some only 16bit */
     178           0 :                 sig = pci_conf_read(pa->pa_pc, pa->pa_tag,
     179           0 :                     AMI_PCI_SIG) & 0xffff;
     180           0 :                 if (sig == AMI_SIGNATURE_1 ||
     181           0 :                     sig == AMI_SIGNATURE_2)
     182           0 :                         return (1);
     183             :         }
     184             : 
     185           0 :         return (0);
     186           0 : }
     187             : 
     188             : void
     189           0 : ami_pci_attach(struct device *parent, struct device *self, void *aux)
     190             : {
     191           0 :         struct ami_softc *sc = (struct ami_softc *)self;
     192           0 :         struct pci_attach_args *pa = aux;
     193           0 :         pci_intr_handle_t ih;
     194             :         const char *intrstr, *model = NULL, *lhc;
     195             :         const struct ami_pci_subsys *ssp;
     196           0 :         bus_size_t size;
     197             :         pcireg_t csr;
     198             :         int i;
     199             : 
     200           0 :         csr = pci_mapreg_type(pa->pa_pc, pa->pa_tag, AMI_BAR);
     201           0 :         if (pci_mapreg_map(pa, AMI_BAR, csr, 0,
     202           0 :             &sc->sc_iot, &sc->sc_ioh, NULL, &size, AMI_PCI_MEMSIZE)) {
     203           0 :                 printf(": can't map controller pci space\n");
     204           0 :                 return;
     205             :         }
     206             : 
     207           0 :         if (PCI_MAPREG_TYPE(csr) == PCI_MAPREG_TYPE_IO) {
     208           0 :                 sc->sc_init = ami_schwartz_init;
     209           0 :                 sc->sc_exec = ami_schwartz_exec;
     210           0 :                 sc->sc_done = ami_schwartz_done;
     211           0 :                 sc->sc_poll = ami_schwartz_poll;
     212           0 :         } else {
     213           0 :                 sc->sc_init = ami_quartz_init;
     214           0 :                 sc->sc_exec = ami_quartz_exec;
     215           0 :                 sc->sc_done = ami_quartz_done;
     216           0 :                 sc->sc_poll = ami_quartz_poll;
     217           0 :                 sc->sc_flags |= AMI_QUARTZ;
     218             :         }
     219           0 :         sc->sc_dmat = pa->pa_dmat;
     220             : 
     221           0 :         if (pci_intr_map(pa, &ih)) {
     222           0 :                 printf(": can't map interrupt\n");
     223           0 :                 bus_space_unmap(sc->sc_iot, sc->sc_ioh, size);
     224           0 :                 return;
     225             :         }
     226           0 :         intrstr = pci_intr_string(pa->pa_pc, ih);
     227           0 :         sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, ami_intr, sc,
     228           0 :             sc->sc_dev.dv_xname);
     229           0 :         if (!sc->sc_ih) {
     230           0 :                 printf(": can't establish interrupt");
     231           0 :                 if (intrstr)
     232           0 :                         printf(" at %s", intrstr);
     233           0 :                 printf("\n");
     234           0 :                 bus_space_unmap(sc->sc_iot, sc->sc_ioh, size);
     235           0 :                 return;
     236             :         }
     237             : 
     238           0 :         printf(": %s\n", intrstr);
     239             : 
     240           0 :         csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
     241           0 :         for (ssp = ami_pci_subsys; ssp->id; ssp++) {
     242           0 :                 if (ssp->id == csr) {
     243           0 :                         model = ssp->name;
     244           0 :                         sc->sc_flags |= ssp->flags;
     245           0 :                         break;
     246             :                 }
     247             :         }
     248             : 
     249           0 :         if (!model && PCI_VENDOR(pa->pa_id) == PCI_VENDOR_AMI) {
     250           0 :                 switch (PCI_PRODUCT(pa->pa_id)) {
     251             :                 case PCI_PRODUCT_AMI_MEGARAID428:
     252             :                         model = "AMI 428";
     253           0 :                         break;
     254             :                 case PCI_PRODUCT_AMI_MEGARAID434:
     255             :                         model = "AMI 434";
     256           0 :                         break;
     257             :                 }
     258             :         }
     259             : 
     260             :         /*
     261             :          * XXX 438 is netraid 3si for hp cards, but we get to know
     262             :          * they are hp too late in md code
     263             :          */
     264           0 :         if (!model) {
     265             :                 const struct ami_pci_vendor *vp;
     266             :                 static char modelbuf[32];
     267             : 
     268           0 :                 for (vp = ami_pci_vendors;
     269           0 :                      vp->id && vp->id != (csr & 0xffff); vp++);
     270           0 :                 if (vp->id)
     271           0 :                         snprintf(modelbuf, sizeof(modelbuf), "%s %x", vp->name,
     272           0 :                             (csr >> 16) & 0xffff);
     273             :                 else
     274           0 :                         snprintf(modelbuf, sizeof(modelbuf), "unknown 0x%08x",
     275             :                             csr);
     276             :                 model = modelbuf;
     277           0 :         }
     278             : 
     279           0 :         switch (pci_conf_read(pa->pa_pc, pa->pa_tag, AMI_PCI_SGL)) {
     280           0 :         case AMI_SGL_LHC:       lhc = "64b/lhc";      break;
     281           0 :         case AMI_SGL_HLC:       lhc = "64b/hlc";      break;
     282             :         default:                lhc = "32b";
     283           0 :         }
     284             : 
     285           0 :         if ((i = ami_pci_find_device(aux)) != -1) {
     286           0 :                 if (ami_pci_devices[i].flags & AMI_BROKEN)
     287           0 :                         sc->sc_flags |= AMI_BROKEN;
     288             :         } else {
     289             :                 /* this device existed at _match() should never happen */
     290           0 :                 panic("ami device dissapeared between match() and attach()");
     291             :         }
     292             : 
     293           0 :         printf("%s: %s, %s", sc->sc_dev.dv_xname, model, lhc);
     294             : 
     295           0 :         if (ami_attach(sc)) {
     296           0 :                 pci_intr_disestablish(pa->pa_pc, sc->sc_ih);
     297           0 :                 sc->sc_ih = NULL;
     298           0 :                 bus_space_unmap(sc->sc_iot, sc->sc_ioh, size);
     299           0 :         }
     300           0 : }

Generated by: LCOV version 1.13