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