1 /* $OpenBSD: qlw_pci.c,v 1.11 2021/05/01 16:11:16 visa Exp $ */ 2 3 /* 4 * Copyright (c) 2011 David Gwynne <dlg@openbsd.org> 5 * Copyright (c) 2013, 2014 Jonathan Matthew <jmatthew@openbsd.org> 6 * Copyright (c) 2014 Mark Kettenis <kettenis@openbsd.org> 7 * 8 * Permission to use, copy, modify, and distribute this software for any 9 * purpose with or without fee is hereby granted, provided that the above 10 * copyright notice and this permission notice appear in all copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21 #include "bio.h" 22 23 #include <sys/param.h> 24 #include <sys/systm.h> 25 #include <sys/kernel.h> 26 #include <sys/malloc.h> 27 #include <sys/device.h> 28 #include <sys/sensors.h> 29 #include <sys/rwlock.h> 30 31 #include <machine/bus.h> 32 33 #include <dev/pci/pcireg.h> 34 #include <dev/pci/pcivar.h> 35 #include <dev/pci/pcidevs.h> 36 37 #ifdef __sparc64__ 38 #include <dev/ofw/openfirm.h> 39 #endif 40 41 #include <scsi/scsi_all.h> 42 #include <scsi/scsiconf.h> 43 44 #include <dev/ic/qlwreg.h> 45 #include <dev/ic/qlwvar.h> 46 47 #ifndef ISP_NOFIRMWARE 48 #include <dev/microcode/isp/asm_1040.h> 49 #include <dev/microcode/isp/asm_1080.h> 50 #include <dev/microcode/isp/asm_12160.h> 51 #endif 52 53 #define QLW_PCI_MEM_BAR 0x14 54 #define QLW_PCI_IO_BAR 0x10 55 56 int qlw_pci_match(struct device *, void *, void *); 57 void qlw_pci_attach(struct device *, struct device *, void *); 58 int qlw_pci_detach(struct device *, int); 59 60 struct qlw_pci_softc { 61 struct qlw_softc psc_qlw; 62 63 pci_chipset_tag_t psc_pc; 64 pcitag_t psc_tag; 65 66 void *psc_ih; 67 }; 68 69 struct cfattach qlw_pci_ca = { 70 sizeof(struct qlw_pci_softc), 71 qlw_pci_match, 72 qlw_pci_attach 73 }; 74 75 static const struct pci_matchid qlw_devices[] = { 76 { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1020 }, 77 { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1240 }, 78 { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1080 }, 79 { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1280 }, 80 { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP10160 }, 81 { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP12160 }, 82 }; 83 84 int 85 qlw_pci_match(struct device *parent, void *match, void *aux) 86 { 87 struct pci_attach_args *pa = aux; 88 89 /* Silly AMI MegaRAID exposes its ISP12160 to us. */ 90 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_QLOGIC_ISP12160) { 91 pcireg_t subid; 92 93 subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBVEND_0); 94 if (PCI_VENDOR(subid) == PCI_VENDOR_AMI) 95 return (0); 96 } 97 98 return (pci_matchbyid(aux, qlw_devices, nitems(qlw_devices)) * 2); 99 } 100 101 void 102 qlw_pci_attach(struct device *parent, struct device *self, void *aux) 103 { 104 struct qlw_pci_softc *psc = (void *)self; 105 struct qlw_softc *sc = &psc->psc_qlw; 106 struct pci_attach_args *pa = aux; 107 pci_intr_handle_t ih; 108 const char *intrstr; 109 u_int32_t pcictl; 110 #ifdef __sparc64__ 111 int node, initiator; 112 #endif 113 114 pcireg_t bars[] = { QLW_PCI_MEM_BAR, QLW_PCI_IO_BAR }; 115 pcireg_t memtype; 116 int r; 117 118 psc->psc_pc = pa->pa_pc; 119 psc->psc_tag = pa->pa_tag; 120 psc->psc_ih = NULL; 121 sc->sc_dmat = pa->pa_dmat; 122 sc->sc_ios = 0; 123 124 for (r = 0; r < nitems(bars); r++) { 125 memtype = pci_mapreg_type(psc->psc_pc, psc->psc_tag, bars[r]); 126 if (pci_mapreg_map(pa, bars[r], memtype, 0, 127 &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_ios, 0) == 0) 128 break; 129 130 sc->sc_ios = 0; 131 } 132 if (sc->sc_ios == 0) { 133 printf(": unable to map registers\n"); 134 return; 135 } 136 137 if (pci_intr_map(pa, &ih)) { 138 printf(": unable to map interrupt\n"); 139 goto unmap; 140 } 141 intrstr = pci_intr_string(psc->psc_pc, ih); 142 psc->psc_ih = pci_intr_establish(psc->psc_pc, ih, IPL_BIO, 143 qlw_intr, sc, DEVNAME(sc)); 144 if (psc->psc_ih == NULL) { 145 printf(": unable to establish interrupt"); 146 if (intrstr != NULL) 147 printf(" at %s", intrstr); 148 printf("\n"); 149 goto deintr; 150 } 151 152 printf(": %s\n", intrstr); 153 154 pcictl = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 155 pcictl |= PCI_COMMAND_INVALIDATE_ENABLE | 156 PCI_COMMAND_PARITY_ENABLE | PCI_COMMAND_SERR_ENABLE; 157 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, pcictl); 158 159 pcictl = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG); 160 pcictl &= ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT); 161 pcictl &= ~(PCI_CACHELINE_MASK << PCI_CACHELINE_SHIFT); 162 pcictl |= (0x80 << PCI_LATTIMER_SHIFT); 163 pcictl |= (0x10 << PCI_CACHELINE_SHIFT); 164 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG, pcictl); 165 166 pcictl = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG); 167 pcictl &= ~1; 168 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, pcictl); 169 170 switch (PCI_PRODUCT(pa->pa_id)) { 171 case PCI_PRODUCT_QLOGIC_ISP1020: 172 sc->sc_isp_gen = QLW_GEN_ISP1040; 173 switch (PCI_REVISION(pa->pa_class)) { 174 case 0: 175 sc->sc_isp_type = QLW_ISP1020; 176 break; 177 case 1: 178 sc->sc_isp_type = QLW_ISP1020A; 179 break; 180 case 2: 181 sc->sc_isp_type = QLW_ISP1040; 182 break; 183 case 3: 184 sc->sc_isp_type = QLW_ISP1040A; 185 break; 186 case 4: 187 sc->sc_isp_type = QLW_ISP1040B; 188 break; 189 case 5: 190 default: 191 sc->sc_isp_type = QLW_ISP1040C; 192 break; 193 } 194 sc->sc_numbusses = 1; 195 if (PCI_REVISION(pa->pa_class) < 2) 196 sc->sc_clock = 40; /* ISP1020/1020A */ 197 else 198 sc->sc_clock = 60; /* ISP1040/1040A/1040B/1040C */ 199 break; 200 201 case PCI_PRODUCT_QLOGIC_ISP1240: 202 sc->sc_isp_gen = QLW_GEN_ISP1080; 203 sc->sc_isp_type = QLW_ISP1240; 204 sc->sc_numbusses = 2; 205 sc->sc_clock = 60; 206 break; 207 208 case PCI_PRODUCT_QLOGIC_ISP1080: 209 sc->sc_isp_gen = QLW_GEN_ISP1080; 210 sc->sc_isp_type = QLW_ISP1080; 211 sc->sc_numbusses = 1; 212 sc->sc_clock = 100; 213 break; 214 215 case PCI_PRODUCT_QLOGIC_ISP1280: 216 sc->sc_isp_gen = QLW_GEN_ISP1080; 217 sc->sc_isp_type = QLW_ISP1280; 218 sc->sc_numbusses = 2; 219 sc->sc_clock = 100; 220 break; 221 222 case PCI_PRODUCT_QLOGIC_ISP10160: 223 sc->sc_isp_gen = QLW_GEN_ISP12160; 224 sc->sc_isp_type = QLW_ISP10160; 225 sc->sc_numbusses = 1; 226 sc->sc_clock = 100; 227 break; 228 229 case PCI_PRODUCT_QLOGIC_ISP12160: 230 sc->sc_isp_gen = QLW_GEN_ISP12160; 231 sc->sc_isp_type = QLW_ISP12160; 232 sc->sc_numbusses = 2; 233 sc->sc_clock = 100; 234 break; 235 236 default: 237 printf("unknown pci id %x", pa->pa_id); 238 return; 239 } 240 241 #ifndef ISP_NOFIRMWARE 242 switch (sc->sc_isp_gen) { 243 case QLW_GEN_ISP1040: 244 sc->sc_firmware = isp_1040_risc_code; 245 break; 246 case QLW_GEN_ISP1080: 247 sc->sc_firmware = isp_1080_risc_code; 248 break; 249 case QLW_GEN_ISP12160: 250 sc->sc_firmware = isp_12160_risc_code; 251 break; 252 default: 253 break; 254 } 255 #endif 256 257 /* 258 * The standard SCSI initiator ID is 7. 259 * Add-on cards should have a valid nvram, which will override 260 * these defaults. 261 */ 262 sc->sc_initiator[0] = sc->sc_initiator[1] = 7; 263 264 #ifdef __sparc64__ 265 /* 266 * Walk up the Open Firmware device tree until we find a 267 * "scsi-initiator-id" property. 268 */ 269 node = PCITAG_NODE(pa->pa_tag); 270 while (node) { 271 if (OF_getprop(node, "scsi-initiator-id", 272 &initiator, sizeof(initiator)) == sizeof(initiator)) { 273 /* 274 * Override the SCSI initiator ID provided by 275 * the nvram. 276 */ 277 sc->sc_flags |= QLW_FLAG_INITIATOR; 278 sc->sc_initiator[0] = sc->sc_initiator[1] = initiator; 279 break; 280 } 281 node = OF_parent(node); 282 } 283 #endif 284 285 sc->sc_host_cmd_ctrl = QLW_HOST_CMD_CTRL_PCI; 286 sc->sc_mbox_base = QLW_MBOX_BASE_PCI; 287 288 if (qlw_attach(sc) != 0) { 289 /* error printed by qlw_attach */ 290 goto deintr; 291 } 292 293 return; 294 295 deintr: 296 pci_intr_disestablish(psc->psc_pc, psc->psc_ih); 297 psc->psc_ih = NULL; 298 unmap: 299 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); 300 sc->sc_ios = 0; 301 } 302 303 int 304 qlw_pci_detach(struct device *self, int flags) 305 { 306 struct qlw_pci_softc *psc = (struct qlw_pci_softc *)self; 307 struct qlw_softc *sc = &psc->psc_qlw; 308 int rv; 309 310 if (psc->psc_ih == NULL) { 311 /* we didnt attach properly, so nothing to detach */ 312 return (0); 313 } 314 315 rv = qlw_detach(sc, flags); 316 if (rv != 0) 317 return (rv); 318 319 pci_intr_disestablish(psc->psc_pc, psc->psc_ih); 320 psc->psc_ih = NULL; 321 322 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); 323 sc->sc_ios = 0; 324 325 return (0); 326 } 327