[BACK]Return to jmb.c CVS log [TXT][DIR] Up to [local] / sys / dev / pci

Annotation of sys/dev/pci/jmb.c, Revision 1.1.1.1

1.1       nbrk        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: }

CVSweb