Annotation of sys/dev/pci/ciss_pci.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: ciss_pci.c,v 1.10 2006/09/20 19:45:16 brad Exp $ */
! 2:
! 3: /*
! 4: * Copyright (c) 2005 Michael Shalayeff
! 5: * All rights reserved.
! 6: *
! 7: * Permission to use, copy, modify, and distribute this software for any
! 8: * purpose with or without fee is hereby granted, provided that the above
! 9: * copyright notice and this permission notice appear in all copies.
! 10: *
! 11: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
! 12: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 13: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
! 14: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 15: * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
! 16: * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
! 17: * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 18: */
! 19:
! 20: #include <sys/param.h>
! 21: #include <sys/systm.h>
! 22: #include <sys/kernel.h>
! 23: #include <sys/malloc.h>
! 24: #include <sys/device.h>
! 25:
! 26: #include <dev/pci/pcidevs.h>
! 27: #include <dev/pci/pcivar.h>
! 28:
! 29: #include <machine/bus.h>
! 30:
! 31: #include <scsi/scsi_all.h>
! 32: #include <scsi/scsi_disk.h>
! 33: #include <scsi/scsiconf.h>
! 34:
! 35: #include <dev/ic/cissreg.h>
! 36: #include <dev/ic/cissvar.h>
! 37:
! 38: #define CISS_BAR 0x10
! 39:
! 40: int ciss_pci_match(struct device *, void *, void *);
! 41: void ciss_pci_attach(struct device *, struct device *, void *);
! 42:
! 43: struct cfattach ciss_pci_ca = {
! 44: sizeof(struct ciss_softc), ciss_pci_match, ciss_pci_attach
! 45: };
! 46:
! 47: const struct pci_matchid ciss_pci_devices[] = {
! 48: { PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_CSA532 },
! 49: { PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_CSA5300 },
! 50: { PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_CSA5300_2 },
! 51: { PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_CSA5312 },
! 52: { PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_CSA5i },
! 53: { PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_CSA5i_2 },
! 54: { PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_CSA6i },
! 55: { PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_CSA641 },
! 56: { PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_CSA642 },
! 57: { PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_CSA6400 },
! 58: { PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_CSA6400EM },
! 59: { PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_CSA6422 },
! 60: { PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_CSA64XX },
! 61: { PCI_VENDOR_HP, PCI_PRODUCT_HP_HPSAE200 },
! 62: { PCI_VENDOR_HP, PCI_PRODUCT_HP_HPSAE200I_1 },
! 63: { PCI_VENDOR_HP, PCI_PRODUCT_HP_HPSAE200I_2 },
! 64: { PCI_VENDOR_HP, PCI_PRODUCT_HP_HPSAE200I_3 },
! 65: { PCI_VENDOR_HP, PCI_PRODUCT_HP_HPSAE500 },
! 66: { PCI_VENDOR_HP, PCI_PRODUCT_HP_HPSAP600 },
! 67: { PCI_VENDOR_HP, PCI_PRODUCT_HP_HPSAP800 },
! 68: { PCI_VENDOR_HP, PCI_PRODUCT_HP_HPSAV100 },
! 69: { PCI_VENDOR_HP, PCI_PRODUCT_HP_HPSA_1 },
! 70: { PCI_VENDOR_HP, PCI_PRODUCT_HP_HPSA_2 },
! 71: { PCI_VENDOR_HP, PCI_PRODUCT_HP_HPSA_3 },
! 72: { PCI_VENDOR_HP, PCI_PRODUCT_HP_HPSA_4 },
! 73: { PCI_VENDOR_HP, PCI_PRODUCT_HP_HPSA_5 },
! 74: { PCI_VENDOR_HP, PCI_PRODUCT_HP_HPSA_6 },
! 75: { PCI_VENDOR_HP, PCI_PRODUCT_HP_HPSA_7 },
! 76: { PCI_VENDOR_HP, PCI_PRODUCT_HP_HPSA_8 },
! 77: { PCI_VENDOR_HP, PCI_PRODUCT_HP_HPSA_9 },
! 78: { PCI_VENDOR_HP, PCI_PRODUCT_HP_HPSA_10 },
! 79: { PCI_VENDOR_HP, PCI_PRODUCT_HP_HPSA_11 },
! 80: { PCI_VENDOR_HP, PCI_PRODUCT_HP_HPSA_12 }
! 81: };
! 82: #define CISS_PCI_NDEVS sizeof(ciss_pci_devices)/sizeof(ciss_pci_devices[0])
! 83:
! 84: int
! 85: ciss_pci_match(struct device *parent, void *match, void *aux)
! 86: {
! 87: struct pci_attach_args *pa = aux;
! 88:
! 89: return pci_matchbyid(pa, ciss_pci_devices, CISS_PCI_NDEVS);
! 90: }
! 91:
! 92: void
! 93: ciss_pci_attach(struct device *parent, struct device *self, void *aux)
! 94: {
! 95: struct ciss_softc *sc = (struct ciss_softc *)self;
! 96: struct pci_attach_args *pa = aux;
! 97: bus_size_t size, cfgsz;
! 98: pci_intr_handle_t ih;
! 99: const char *intrstr;
! 100: int cfg_bar, memtype;
! 101: pcireg_t reg;
! 102:
! 103: memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, CISS_BAR);
! 104: if (memtype != (PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT) &&
! 105: memtype != (PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT)) {
! 106: printf(": wrong BAR type\n");
! 107: return;
! 108: }
! 109: if (pci_mapreg_map(pa, CISS_BAR, memtype, 0,
! 110: &sc->iot, &sc->ioh, NULL, &size, 0)) {
! 111: printf(": can't map controller i/o space\n");
! 112: return;
! 113: }
! 114: sc->dmat = pa->pa_dmat;
! 115:
! 116: sc->iem = CISS_READYENA;
! 117: reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
! 118: if (PCI_VENDOR(reg) == PCI_VENDOR_COMPAQ &&
! 119: (PCI_PRODUCT(reg) == PCI_PRODUCT_COMPAQ_CSA5i ||
! 120: PCI_PRODUCT(reg) == PCI_PRODUCT_COMPAQ_CSA532 ||
! 121: PCI_PRODUCT(reg) == PCI_PRODUCT_COMPAQ_CSA5312))
! 122: sc->iem = CISS_READYENAB;
! 123:
! 124: cfg_bar = bus_space_read_2(sc->iot, sc->ioh, CISS_CFG_BAR);
! 125: sc->cfgoff = bus_space_read_4(sc->iot, sc->ioh, CISS_CFG_OFF);
! 126: if (cfg_bar != CISS_BAR) {
! 127: if (pci_mapreg_map(pa, cfg_bar, PCI_MAPREG_TYPE_MEM, 0,
! 128: NULL, &sc->cfg_ioh, NULL, &cfgsz, 0)) {
! 129: printf(": can't map controller config space\n");
! 130: bus_space_unmap(sc->iot, sc->ioh, size);
! 131: return;
! 132: }
! 133: } else {
! 134: sc->cfg_ioh = sc->ioh;
! 135: cfgsz = size;
! 136: }
! 137:
! 138: if (sc->cfgoff + sizeof(struct ciss_config) > cfgsz) {
! 139: printf(": unfit config space\n");
! 140: bus_space_unmap(sc->iot, sc->ioh, size);
! 141: if (cfg_bar != CISS_BAR)
! 142: bus_space_unmap(sc->iot, sc->cfg_ioh, cfgsz);
! 143: return;
! 144: }
! 145:
! 146: /* disable interrupts until ready */
! 147: bus_space_write_4(sc->iot, sc->ioh, CISS_IMR,
! 148: bus_space_read_4(sc->iot, sc->ioh, CISS_IMR) | sc->iem);
! 149:
! 150: if (pci_intr_map(pa, &ih)) {
! 151: printf(": can't map interrupt\n");
! 152: bus_space_unmap(sc->iot, sc->ioh, size);
! 153: if (cfg_bar != CISS_BAR)
! 154: bus_space_unmap(sc->iot, sc->cfg_ioh, cfgsz);
! 155: return;
! 156: }
! 157: intrstr = pci_intr_string(pa->pa_pc, ih);
! 158: sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, ciss_intr, sc,
! 159: sc->sc_dev.dv_xname);
! 160: if (!sc->sc_ih) {
! 161: printf(": can't establish interrupt");
! 162: if (intrstr)
! 163: printf(" at %s", intrstr);
! 164: printf("\n");
! 165: bus_space_unmap(sc->iot, sc->ioh, size);
! 166: if (cfg_bar != CISS_BAR)
! 167: bus_space_unmap(sc->iot, sc->cfg_ioh, cfgsz);
! 168: }
! 169:
! 170: printf(": %s\n%s", intrstr, sc->sc_dev.dv_xname);
! 171:
! 172: if (ciss_attach(sc)) {
! 173: pci_intr_disestablish(pa->pa_pc, sc->sc_ih);
! 174: sc->sc_ih = NULL;
! 175: bus_space_unmap(sc->iot, sc->ioh, size);
! 176: if (cfg_bar != CISS_BAR)
! 177: bus_space_unmap(sc->iot, sc->cfg_ioh, cfgsz);
! 178: return;
! 179: }
! 180:
! 181: /* enable interrupts now */
! 182: bus_space_write_4(sc->iot, sc->ioh, CISS_IMR,
! 183: bus_space_read_4(sc->iot, sc->ioh, CISS_IMR) & ~sc->iem);
! 184: }
CVSweb