Annotation of sys/dev/pci/mfi_pci.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: mfi_pci.c,v 1.11 2006/08/06 04:40:08 brad Exp $ */
! 2: /*
! 3: * Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
! 4: *
! 5: * Permission to use, copy, modify, and distribute this software for any
! 6: * purpose with or without fee is hereby granted, provided that the above
! 7: * copyright notice and this permission notice appear in all copies.
! 8: *
! 9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
! 10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
! 12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
! 14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
! 15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 16: */
! 17:
! 18: #include <sys/param.h>
! 19: #include <sys/systm.h>
! 20: #include <sys/kernel.h>
! 21: #include <sys/malloc.h>
! 22: #include <sys/device.h>
! 23: #include <sys/rwlock.h>
! 24:
! 25: #include <dev/pci/pcidevs.h>
! 26: #include <dev/pci/pcivar.h>
! 27:
! 28: #include <machine/bus.h>
! 29:
! 30: #include <scsi/scsi_all.h>
! 31: #include <scsi/scsi_disk.h>
! 32: #include <scsi/scsiconf.h>
! 33:
! 34: #include <dev/ic/mfireg.h>
! 35: #include <dev/ic/mfivar.h>
! 36:
! 37: #define MFI_BAR 0x10
! 38: #define MFI_PCI_MEMSIZE 0x2000 /* 8k */
! 39:
! 40: int mfi_pci_find_device(void *);
! 41: int mfi_pci_match(struct device *, void *, void *);
! 42: void mfi_pci_attach(struct device *, struct device *, void *);
! 43:
! 44: struct cfattach mfi_pci_ca = {
! 45: sizeof(struct mfi_softc), mfi_pci_match, mfi_pci_attach
! 46: };
! 47:
! 48: static const
! 49: struct mfi_pci_device {
! 50: pcireg_t mpd_vendor;
! 51: pcireg_t mpd_product;
! 52: pcireg_t mpd_subvendor;
! 53: pcireg_t mpd_subproduct;
! 54: char *mpd_model;
! 55: uint32_t mpd_flags;
! 56: } mfi_pci_devices[] = {
! 57: { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_MEGARAID_SAS,
! 58: 0, 0, "", 0 },
! 59: { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_MEGARAID_VERDE_ZCR,
! 60: 0, 0, "", 0 },
! 61: { PCI_VENDOR_DELL, PCI_PRODUCT_DELL_PERC5,
! 62: PCI_VENDOR_DELL, 0x1f01, "Dell PERC 5/e", 0 },
! 63: { PCI_VENDOR_DELL, PCI_PRODUCT_DELL_PERC5,
! 64: PCI_VENDOR_DELL, 0x1f02, "Dell PERC 5/i", 0 },
! 65: { 0 }
! 66: };
! 67:
! 68: int
! 69: mfi_pci_find_device(void *aux) {
! 70: struct pci_attach_args *pa = aux;
! 71: int i;
! 72:
! 73: for (i = 0; mfi_pci_devices[i].mpd_vendor; i++) {
! 74: if (mfi_pci_devices[i].mpd_vendor == PCI_VENDOR(pa->pa_id) &&
! 75: mfi_pci_devices[i].mpd_product == PCI_PRODUCT(pa->pa_id)) {
! 76: DNPRINTF(MFI_D_MISC, "mfi_pci_find_device: %i\n", i);
! 77: return (i);
! 78: }
! 79: }
! 80:
! 81: return (-1);
! 82: }
! 83:
! 84: int
! 85: mfi_pci_match(struct device *parent, void *match, void *aux)
! 86: {
! 87: int i;
! 88:
! 89: if ((i = mfi_pci_find_device(aux)) != -1) {
! 90: DNPRINTF(MFI_D_MISC,
! 91: "mfi_pci_match: vendor: %04x product: %04x\n",
! 92: mfi_pci_devices[i].mpd_vendor,
! 93: mfi_pci_devices[i].mpd_product);
! 94:
! 95: return (1);
! 96: }
! 97:
! 98: return (0);
! 99: }
! 100:
! 101: void
! 102: mfi_pci_attach(struct device *parent, struct device *self, void *aux)
! 103: {
! 104: struct mfi_softc *sc = (struct mfi_softc *)self;
! 105: struct pci_attach_args *pa = aux;
! 106: const char *intrstr;
! 107: pci_intr_handle_t ih;
! 108: bus_size_t size;
! 109: pcireg_t csr;
! 110: uint32_t subsysid, i;
! 111:
! 112: subsysid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
! 113: for (i = 0; mfi_pci_devices[i].mpd_vendor; i++)
! 114: if (mfi_pci_devices[i].mpd_subvendor == PCI_VENDOR(subsysid) &&
! 115: mfi_pci_devices[i].mpd_subproduct == PCI_PRODUCT(subsysid)){
! 116: printf(", %s", mfi_pci_devices[i].mpd_model);
! 117: break;
! 118: }
! 119:
! 120: csr = pci_mapreg_type(pa->pa_pc, pa->pa_tag, MFI_BAR);
! 121: csr |= PCI_MAPREG_MEM_TYPE_32BIT;
! 122: if (pci_mapreg_map(pa, MFI_BAR, csr, 0,
! 123: &sc->sc_iot, &sc->sc_ioh, NULL, &size, MFI_PCI_MEMSIZE)) {
! 124: printf(": can't map controller pci space\n");
! 125: return;
! 126: }
! 127:
! 128: sc->sc_dmat = pa->pa_dmat;
! 129:
! 130: if (pci_intr_map(pa, &ih)) {
! 131: printf(": can't map interrupt\n");
! 132: bus_space_unmap(sc->sc_iot, sc->sc_ioh, size);
! 133: return;
! 134: }
! 135: intrstr = pci_intr_string(pa->pa_pc, ih);
! 136: sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, mfi_intr, sc,
! 137: sc->sc_dev.dv_xname);
! 138: if (!sc->sc_ih) {
! 139: printf(": can't establish interrupt");
! 140: if (intrstr)
! 141: printf(" at %s", intrstr);
! 142: printf("\n");
! 143: bus_space_unmap(sc->sc_iot, sc->sc_ioh, size);
! 144: return;
! 145: }
! 146:
! 147: printf(": %s\n", intrstr);
! 148:
! 149: if (mfi_attach(sc)) {
! 150: printf("%s: can't attach", DEVNAME(sc));
! 151: pci_intr_disestablish(pa->pa_pc, sc->sc_ih);
! 152: sc->sc_ih = NULL;
! 153: bus_space_unmap(sc->sc_iot, sc->sc_ioh, size);
! 154: }
! 155: }
CVSweb