diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/files.pci | 9 | ||||
-rw-r--r-- | sys/dev/pci/jmb.c | 218 |
2 files changed, 226 insertions, 1 deletions
diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci index fc5f1767364..ca4c67b7a04 100644 --- a/sys/dev/pci/files.pci +++ b/sys/dev/pci/files.pci @@ -1,4 +1,4 @@ -# $OpenBSD: files.pci,v 1.237 2007/07/02 00:46:22 dlg Exp $ +# $OpenBSD: files.pci,v 1.238 2007/07/02 01:14:36 dlg Exp $ # $NetBSD: files.pci,v 1.20 1996/09/24 17:47:15 christos Exp $ # # Config file and device description for machine-independent PCI code. @@ -84,6 +84,13 @@ device ahci: scsi, atascsi attach ahci at pci with ahci_pci file dev/pci/ahci.c ahci | ahci_pci +# JMicron JMB36x controllers +device jmb {} +attach jmb at pci +attach ahci at jmb with ahci_jmb +file dev/pci/jmb.c jmb | ahci_jmb + + # AMI MegaRAID Express x00/Elite 1500/Express 1x00 RAID Controllers attach ami at pci with ami_pci file dev/pci/ami_pci.c ami_pci diff --git a/sys/dev/pci/jmb.c b/sys/dev/pci/jmb.c new file mode 100644 index 00000000000..685008e8787 --- /dev/null +++ b/sys/dev/pci/jmb.c @@ -0,0 +1,218 @@ +/* $OpenBSD: jmb.c,v 1.1 2007/07/02 01:14:36 dlg Exp $ */ + +/* + * Copyright (c) 2007 David Gwynne <dlg@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/buf.h> +#include <sys/kernel.h> +#include <sys/malloc.h> +#include <sys/device.h> +#include <sys/proc.h> +#include <sys/queue.h> + +#include <machine/bus.h> + +#include <dev/pci/pcireg.h> +#include <dev/pci/pcivar.h> +#include <dev/pci/pcidevs.h> + +#include <dev/ata/atascsi.h> + +#include <dev/pci/ahcivar.h> + +/* JMicron registers */ +#define JM_PCI_CTL0 0x40 /* control register 0 */ +#define JM_PCI_CTL0_ROM_EN (1<<31) /* External Option ROM */ +#define JM_PCI_CTL0_IDWR_EN (1<<30) /* Device ID Write */ +#define JM_PCI_CTL0_MSI64_EN (1<<25) /* 64bit MSI Addr Mode */ +#define JM_PCI_CTL0_MSI_EN (1<<24) /* MSI Addr Mode */ +#define JM_PCI_CTL0_IDEDMA_CFG (1<<23) /* PCIIDE DMA Chan Cfg */ +#define JM_PCI_CTL0_PCIIDE_CS (1<<22) /* PCIIDE channels Swap */ +#define JM_PCI_CTL0_SATA_PS (1<<21) /* SATA channel M/S swap */ +#define JM_PCI_CTL0_AHCI_PS (1<<20) /* SATA AHCI ports swap */ +#define JM_PCI_CTL0_F1_SUBCLASS_M 0xc0000 /* subclass for func 1 */ +#define JM_PCI_CTL0_F0_SUBCLASS_M 0x30000 /* subclass for func 0 */ +#define JM_PCI_CTL0_SUBCLASS_IDE 0x0 /* IDE Controller */ +#define JM_PCI_CTL0_SUBCLASS_RAID 0x1 /* RAID Controller */ +#define JM_PCI_CTL0_SUBCLASS_AHCI 0x2 /* AHCI Controller */ +#define JM_PCI_CTL0_SUBCLASS_OTHER 0x3 /* Other Mass Storage */ +#define JM_PCI_CTL0_F1_SUBCLASS(_m) ((_m)<<18) /* subclass for func 1 */ +#define JM_PCI_CTL0_F0_SUBCLASS(_m) ((_m)<<16) /* subclass for func 0 */ +#define JM_PCI_CTL0_SATA1_AHCI (1<<15) /* SATA port 1 AHCI enable */ +#define JM_PCI_CTL0_SATA1_IDE (1<<14) /* SATA port 1 IDE enable */ +#define JM_PCI_CTL0_SATA0_AHCI (1<<13) /* SATA port 0 AHCI enable */ +#define JM_PCI_CTL0_SATA0_IDE (1<<12) /* SATA port 0 PCIIDE enable */ +#define JM_PCI_CTL0_AHCI_F1 (1<<9) /* AHCI on function 1 */ +#define JM_PCI_CTL0_AHCI_EN (1<<8) /* ACHI enable */ +#define JM_PCI_CTL0_PATA0_RST (1<<6) /* PATA port 0 reset */ +#define JM_PCI_CTL0_PATA0_EN (1<<5) /* PATA port 0 enable */ +#define JM_PCI_CTL0_PATA0_SEC (1<<4) /* PATA 0 enable on 2nd chan */ +#define JM_PCI_CTL0_PATA0_40P (1<<3) /* PATA 0 40pin cable */ +#define JM_PCI_CTL0_PCIIDE_F1 (1<<1) /* PCIIDE on function 1 */ +#define JM_PCI_CTL0_PATA0_PRI (1<<0) /* PATA 0 enable on 1st chan */ + +#define JM_PCI_CTL5 0x80 /* control register 8 */ +#define JM_PCI_CTL5_PATA1_PRI (1<<24) /* force PATA 1 on chan0 */ + +int jmb_match(struct device *, void *, void *); +void jmb_attach(struct device *, struct device *, void *); +int jmb_print(void *, const char *); + +struct jmb_softc { + struct device sc_dev; +}; + +struct cfattach jmb_ca = { + sizeof(struct jmb_softc), jmb_match, jmb_attach +}; + +struct cfdriver jmb_cd = { + NULL, "jmb", DV_DULL +}; + + +struct jmb_attach_args { + enum { + JMB_DEV_AHCI, + JMB_DEV_IDE + } ja_dev; + struct pci_attach_args *ja_pa; + pci_intr_handle_t ja_ih; +}; + +static const struct pci_matchid jmb_devices[] = { + { PCI_VENDOR_JMICRON, PCI_PRODUCT_JMICRON_JMB360 }, + { PCI_VENDOR_JMICRON, PCI_PRODUCT_JMICRON_JMB361 }, + { PCI_VENDOR_JMICRON, PCI_PRODUCT_JMICRON_JMB363 }, + { PCI_VENDOR_JMICRON, PCI_PRODUCT_JMICRON_JMB365 }, + { PCI_VENDOR_JMICRON, PCI_PRODUCT_JMICRON_JMB366 } +}; + +int +jmb_match(struct device *parent, void *match, void *aux) +{ + struct pci_attach_args *pa = aux; + + return (pci_matchbyid(pa, jmb_devices, + sizeof(jmb_devices) / sizeof(jmb_devices[0]))); +} + +void +jmb_attach(struct device *parent, struct device *self, void *aux) +{ + struct pci_attach_args *pa = aux; + struct jmb_attach_args ja; + u_int32_t ctl0, ctl5; + + ctl0 = pci_conf_read(pa->pa_pc, pa->pa_tag, JM_PCI_CTL0); + ctl0 &= ~(JM_PCI_CTL0_PCIIDE_F1 | JM_PCI_CTL0_AHCI_EN | + JM_PCI_CTL0_AHCI_F1 | JM_PCI_CTL0_SATA0_IDE | + JM_PCI_CTL0_SATA0_AHCI | JM_PCI_CTL0_SATA1_IDE | + JM_PCI_CTL0_SATA1_AHCI | JM_PCI_CTL0_F1_SUBCLASS_M | + JM_PCI_CTL0_F0_SUBCLASS_M | JM_PCI_CTL0_PCIIDE_CS | + JM_PCI_CTL0_IDEDMA_CFG); + + ctl5 = pci_conf_read(pa->pa_pc, pa->pa_tag, JM_PCI_CTL5); + ctl5 &= ~JM_PCI_CTL5_PATA1_PRI; + + switch (PCI_PRODUCT(pa->pa_id)) { + case PCI_PRODUCT_JMICRON_JMB360: + /* set to single function AHCI mode */ + ctl0 |= JM_PCI_CTL0_AHCI_EN | JM_PCI_CTL0_SATA0_AHCI | + JM_PCI_CTL0_SATA1_AHCI | + JM_PCI_CTL0_F0_SUBCLASS(JM_PCI_CTL0_SUBCLASS_AHCI); + break; + + case PCI_PRODUCT_JMICRON_JMB366: + case PCI_PRODUCT_JMICRON_JMB365: + /* wire the second PATA port in the right place */ + ctl5 |= JM_PCI_CTL5_PATA1_PRI; + /* FALLTHROUGH */ + case PCI_PRODUCT_JMICRON_JMB363: + case PCI_PRODUCT_JMICRON_JMB361: + /* enable AHCI and put IDE on the second function */ + ctl0 |= JM_PCI_CTL0_PCIIDE_F1 | JM_PCI_CTL0_AHCI_EN | + JM_PCI_CTL0_SATA0_AHCI | JM_PCI_CTL0_SATA1_AHCI | + JM_PCI_CTL0_F0_SUBCLASS(JM_PCI_CTL0_SUBCLASS_AHCI) | + JM_PCI_CTL0_F1_SUBCLASS(JM_PCI_CTL0_SUBCLASS_IDE) | + JM_PCI_CTL0_PCIIDE_CS | JM_PCI_CTL0_IDEDMA_CFG; + break; + } + + pci_conf_write(pa->pa_pc, pa->pa_tag, JM_PCI_CTL0, ctl0); + pci_conf_write(pa->pa_pc, pa->pa_tag, JM_PCI_CTL5, ctl5); + + bzero(&ja, sizeof(ja)); + ja.ja_pa = pa; + + if (pci_intr_map(pa, &ja.ja_ih) != 0) { + printf(": unable to map interrupt\n"); + return; + } + printf(": %s\n", pci_intr_string(pa->pa_pc, ja.ja_ih)); + + ja.ja_dev = JMB_DEV_AHCI; + config_found(self, &ja, jmb_print); + + ja.ja_dev = JMB_DEV_IDE; + config_found(self, &ja, jmb_print); +} + +int +jmb_print(void *aux, const char *pnp) +{ + struct jmb_attach_args *ja = aux; + + if (pnp != NULL) { + printf("\"%s\" at %s", + (ja->ja_dev == JMB_DEV_AHCI) ? "sata" : "pata", pnp); + } + + return (UNCONF); +} + + +int ahci_jmb_match(struct device *, void *, void *); +void ahci_jmb_attach(struct device *, struct device *, + void *); + +struct cfattach ahci_jmb_ca = { + sizeof(struct ahci_softc), ahci_jmb_match, ahci_jmb_attach +}; + +int +ahci_jmb_match(struct device *parent, void *match, void *aux) +{ + struct jmb_attach_args *ja = aux; + + if (ja->ja_dev == JMB_DEV_AHCI) + return (1); + + return (0); +} + +void +ahci_jmb_attach(struct device *parent, struct device *self, void *aux) +{ + struct ahci_softc *sc = (struct ahci_softc *)self; + struct jmb_attach_args *ja = aux; + + printf(":"); + + ahci_attach(sc, ja->ja_pa, ja->ja_ih); +} |