root/dev/pci/jmb.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. jmb_match
  2. jmb_attach
  3. jmb_print

    1 /*      $OpenBSD: jmb.c,v 1.6 2007/07/03 01:08:36 dlg Exp $ */
    2 
    3 /*
    4  * Copyright (c) 2007 David Gwynne <dlg@openbsd.org>
    5  *
    6  * Permission to use, copy, modify, and distribute this software for any
    7  * purpose with or without fee is hereby granted, provided that the above
    8  * copyright notice and this permission notice appear in all copies.
    9  *
   10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   17  */
   18 
   19 #include <sys/param.h>
   20 #include <sys/systm.h>
   21 #include <sys/buf.h>
   22 #include <sys/kernel.h>
   23 #include <sys/malloc.h>
   24 #include <sys/device.h>
   25 #include <sys/proc.h>
   26 #include <sys/queue.h>
   27 
   28 #include <machine/bus.h>
   29 
   30 #include <dev/pci/pcireg.h>
   31 #include <dev/pci/pcivar.h>
   32 #include <dev/pci/pcidevs.h>
   33 
   34 /* JMicron registers */
   35 #define JM_PCI_CTL0             0x40 /* control register 0 */
   36 #define  JM_PCI_CTL0_ROM_EN             (1<<31) /* External Option ROM */
   37 #define  JM_PCI_CTL0_IDWR_EN            (1<<30) /* Device ID Write */
   38 #define  JM_PCI_CTL0_MSI64_EN           (1<<25) /* 64bit MSI Addr Mode */
   39 #define  JM_PCI_CTL0_MSI_EN             (1<<24) /* MSI Addr Mode */
   40 #define  JM_PCI_CTL0_IDEDMA_CFG         (1<<23) /* PCIIDE DMA Chan Cfg */
   41 #define  JM_PCI_CTL0_PCIIDE_CS          (1<<22) /* PCIIDE channels Swap */
   42 #define  JM_PCI_CTL0_SATA_PS            (1<<21) /* SATA channel M/S swap */
   43 #define  JM_PCI_CTL0_AHCI_PS            (1<<20) /* SATA AHCI ports swap */
   44 #define  JM_PCI_CTL0_F1_SUBCLASS_M      0xc0000 /* subclass for func 1 */
   45 #define  JM_PCI_CTL0_F0_SUBCLASS_M      0x30000 /* subclass for func 0 */
   46 #define  JM_PCI_CTL0_SUBCLASS_IDE       0x0 /* IDE Controller */
   47 #define  JM_PCI_CTL0_SUBCLASS_RAID      0x1 /* RAID Controller */
   48 #define  JM_PCI_CTL0_SUBCLASS_AHCI      0x2 /* AHCI Controller */
   49 #define  JM_PCI_CTL0_SUBCLASS_OTHER     0x3 /* Other Mass Storage */
   50 #define  JM_PCI_CTL0_F1_SUBCLASS(_m)    ((_m)<<18) /* subclass for func 1 */
   51 #define  JM_PCI_CTL0_F0_SUBCLASS(_m)    ((_m)<<16) /* subclass for func 0 */
   52 #define  JM_PCI_CTL0_SATA1_AHCI         (1<<15) /* SATA port 1 AHCI enable */
   53 #define  JM_PCI_CTL0_SATA1_IDE          (1<<14) /* SATA port 1 IDE enable */
   54 #define  JM_PCI_CTL0_SATA0_AHCI         (1<<13) /* SATA port 0 AHCI enable */
   55 #define  JM_PCI_CTL0_SATA0_IDE          (1<<12) /* SATA port 0 PCIIDE enable */
   56 #define  JM_PCI_CTL0_AHCI_F1            (1<<9) /* AHCI on function 1 */
   57 #define  JM_PCI_CTL0_AHCI_EN            (1<<8) /* ACHI enable */
   58 #define  JM_PCI_CTL0_PATA0_RST          (1<<6) /* PATA port 0 reset */
   59 #define  JM_PCI_CTL0_PATA0_EN           (1<<5) /* PATA port 0 enable */
   60 #define  JM_PCI_CTL0_PATA0_SEC          (1<<4) /* PATA 0 enable on 2nd chan */
   61 #define  JM_PCI_CTL0_PATA0_40P          (1<<3) /* PATA 0 40pin cable */
   62 #define  JM_PCI_CTL0_PCIIDE_F1          (1<<1) /* PCIIDE on function 1 */
   63 #define  JM_PCI_CTL0_PATA0_PRI          (1<<0) /* PATA 0 enable on 1st chan */
   64 
   65 #define JM_PCI_CTL5             0x80 /* control register 8 */
   66 #define  JM_PCI_CTL5_PATA1_PRI          (1<<24) /* force PATA 1 on chan0 */
   67 
   68 int             jmb_match(struct device *, void *, void *);
   69 void            jmb_attach(struct device *, struct device *, void *);
   70 int             jmb_print(void *, const char *);
   71 
   72 struct jmb_softc {
   73         struct device           sc_dev;
   74 };
   75 
   76 struct cfattach jmb_ca = {
   77         sizeof(struct jmb_softc), jmb_match, jmb_attach
   78 };
   79 
   80 struct cfdriver jmb_cd = {
   81         NULL, "jmb", DV_DULL
   82 };
   83 
   84 static const struct pci_matchid jmb_devices[] = {
   85         { PCI_VENDOR_JMICRON,   PCI_PRODUCT_JMICRON_JMB360 },
   86         { PCI_VENDOR_JMICRON,   PCI_PRODUCT_JMICRON_JMB361 },
   87         { PCI_VENDOR_JMICRON,   PCI_PRODUCT_JMICRON_JMB362 },
   88         { PCI_VENDOR_JMICRON,   PCI_PRODUCT_JMICRON_JMB363 },
   89         { PCI_VENDOR_JMICRON,   PCI_PRODUCT_JMICRON_JMB365 },
   90         { PCI_VENDOR_JMICRON,   PCI_PRODUCT_JMICRON_JMB366 },
   91         { PCI_VENDOR_JMICRON,   PCI_PRODUCT_JMICRON_JMB368 }
   92 };
   93 
   94 int
   95 jmb_match(struct device *parent, void *match, void *aux)
   96 {
   97         struct pci_attach_args          *pa = aux;
   98 
   99         return (pci_matchbyid(pa, jmb_devices,
  100             sizeof(jmb_devices) / sizeof(jmb_devices[0])) * 3);
  101 }
  102 
  103 void
  104 jmb_attach(struct device *parent, struct device *self, void *aux)
  105 {
  106         struct pci_attach_args          *pa = aux, jpa;
  107         u_int32_t                       ctl0, ctl5;
  108         int                             sata = 0, pata = 0;
  109 
  110         ctl0 = pci_conf_read(pa->pa_pc, pa->pa_tag, JM_PCI_CTL0);
  111         ctl5 = pci_conf_read(pa->pa_pc, pa->pa_tag, JM_PCI_CTL5);
  112 
  113         /* configure sata bits if it is on this function */
  114         if (pa->pa_function == (ISSET(ctl0, JM_PCI_CTL0_AHCI_F1) ? 1 : 0)) {
  115                 ctl0 &= ~(JM_PCI_CTL0_AHCI_EN | JM_PCI_CTL0_SATA0_IDE |
  116                     JM_PCI_CTL0_SATA0_AHCI | JM_PCI_CTL0_SATA1_IDE |
  117                     JM_PCI_CTL0_SATA1_AHCI);
  118 
  119                 switch (PCI_PRODUCT(pa->pa_id)) {
  120                 case PCI_PRODUCT_JMICRON_JMB360:
  121                 case PCI_PRODUCT_JMICRON_JMB361:
  122                 case PCI_PRODUCT_JMICRON_JMB362:
  123                 case PCI_PRODUCT_JMICRON_JMB363:
  124                 case PCI_PRODUCT_JMICRON_JMB365:
  125                 case PCI_PRODUCT_JMICRON_JMB366:
  126                         /* enable AHCI */
  127                         ctl0 |= JM_PCI_CTL0_AHCI_EN | JM_PCI_CTL0_SATA0_AHCI |
  128                             JM_PCI_CTL0_SATA1_AHCI;
  129                         sata = 1;
  130                         break;
  131                 }
  132         }
  133 
  134         /* configure pata bits if it is on this function */
  135         if (pa->pa_function == (ISSET(ctl0, JM_PCI_CTL0_PCIIDE_F1) ? 1 : 0)) {
  136                 ctl0 &= ~(JM_PCI_CTL0_PCIIDE_CS | JM_PCI_CTL0_IDEDMA_CFG);
  137                 ctl5 &= ~JM_PCI_CTL5_PATA1_PRI;
  138 
  139                 switch (PCI_PRODUCT(pa->pa_id)) {
  140                 case PCI_PRODUCT_JMICRON_JMB366:
  141                 case PCI_PRODUCT_JMICRON_JMB365:
  142                         /* wire the second PATA port in the right place */
  143                         ctl5 |= JM_PCI_CTL5_PATA1_PRI;
  144                         /* FALLTHROUGH */
  145                 case PCI_PRODUCT_JMICRON_JMB363:
  146                 case PCI_PRODUCT_JMICRON_JMB361:
  147                 case PCI_PRODUCT_JMICRON_JMB368:
  148                         ctl0 |= JM_PCI_CTL0_PCIIDE_CS | JM_PCI_CTL0_IDEDMA_CFG;
  149                         pata = 1;
  150                         break;
  151                 }
  152         }
  153 
  154         pci_conf_write(pa->pa_pc, pa->pa_tag, JM_PCI_CTL0, ctl0);
  155         pci_conf_write(pa->pa_pc, pa->pa_tag, JM_PCI_CTL5, ctl5);
  156 
  157         printf("\n");
  158 
  159         jpa = *pa;
  160 
  161         if (sata) {
  162                 /* tweak the class to look like ahci, then try to attach it */
  163                 jpa.pa_class = (PCI_CLASS_MASS_STORAGE << PCI_CLASS_SHIFT) |
  164                     (PCI_SUBCLASS_MASS_STORAGE_SATA << PCI_SUBCLASS_SHIFT) |
  165                     (0x01 << PCI_INTERFACE_SHIFT); /* AHCI_PCI_INTERFACE */
  166                 config_found(self, &jpa, jmb_print);
  167         }
  168 
  169         if (pata) {
  170                 /* set things up for pciide */
  171                 jpa.pa_class = (PCI_CLASS_MASS_STORAGE << PCI_CLASS_SHIFT) |
  172                     (PCI_SUBCLASS_MASS_STORAGE_IDE << PCI_SUBCLASS_SHIFT) |
  173                     (0x85 << PCI_INTERFACE_SHIFT);
  174                 config_found(self, &jpa, jmb_print);
  175         }
  176 }
  177 
  178 int
  179 jmb_print(void *aux, const char *pnp)
  180 {
  181         struct pci_attach_args          *pa = aux;
  182         char                            devinfo[256];
  183 
  184         if (pnp != NULL) {
  185                 pci_devinfo(pa->pa_id, pa->pa_class, 1, devinfo,
  186                     sizeof(devinfo));
  187                 printf("%s at %s", devinfo, pnp);
  188         }
  189 
  190         return (UNCONF);
  191 }

/* [<][>][^][v][top][bottom][index][help] */