Annotation of sys/dev/pci/siop_pci_common.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: siop_pci_common.c,v 1.15 2006/04/20 20:31:12 miod Exp $ */
! 2: /* $NetBSD: siop_pci_common.c,v 1.25 2005/06/28 00:28:42 thorpej Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 2000 Manuel Bouyer.
! 6: *
! 7: * Redistribution and use in source and binary forms, with or without
! 8: * modification, are permitted provided that the following conditions
! 9: * are met:
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: * 2. Redistributions in binary form must reproduce the above copyright
! 13: * notice, this list of conditions and the following disclaimer in the
! 14: * documentation and/or other materials provided with the distribution.
! 15: * 3. All advertising materials mentioning features or use of this software
! 16: * must display the following acknowledgement:
! 17: * This product includes software developed by Manuel Bouyer.
! 18: * 4. The name of the author may not be used to endorse or promote products
! 19: * derived from this software without specific prior written permission.
! 20: *
! 21: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 22: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 23: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 24: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
! 25: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
! 26: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! 27: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! 28: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 29: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
! 30: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 31: */
! 32:
! 33: /* SYM53c8xx PCI-SCSI I/O Processors driver: PCI front-end */
! 34:
! 35: #include <sys/param.h>
! 36: #include <sys/systm.h>
! 37: #include <sys/device.h>
! 38: #include <sys/malloc.h>
! 39: #include <sys/buf.h>
! 40: #include <sys/kernel.h>
! 41:
! 42: #include <machine/endian.h>
! 43:
! 44: #include <dev/pci/pcireg.h>
! 45: #include <dev/pci/pcivar.h>
! 46: #include <dev/pci/pcidevs.h>
! 47:
! 48: #include <scsi/scsi_all.h>
! 49: #include <scsi/scsiconf.h>
! 50:
! 51: #include <dev/ic/siopreg.h>
! 52: #include <dev/ic/siopvar_common.h>
! 53: #include <dev/pci/siop_pci_common.h>
! 54:
! 55: /* List (array, really :) of chips we know how to handle */
! 56: const struct siop_product_desc siop_products[] = {
! 57: { PCI_PRODUCT_SYMBIOS_810,
! 58: 0x00,
! 59: SF_PCI_RL | SF_CHIP_LS,
! 60: 4, 8, 3, 250, 0
! 61: },
! 62: { PCI_PRODUCT_SYMBIOS_810,
! 63: 0x10,
! 64: SF_PCI_RL | SF_PCI_BOF | SF_CHIP_PF | SF_CHIP_LS,
! 65: 4, 8, 3, 250, 0
! 66: },
! 67: { PCI_PRODUCT_SYMBIOS_815,
! 68: 0x00,
! 69: SF_PCI_RL | SF_PCI_BOF,
! 70: 4, 8, 3, 250, 0
! 71: },
! 72: { PCI_PRODUCT_SYMBIOS_820,
! 73: 0x00,
! 74: SF_PCI_RL | SF_CHIP_LS | SF_BUS_WIDE,
! 75: 4, 8, 3, 250, 0
! 76: },
! 77: { PCI_PRODUCT_SYMBIOS_825,
! 78: 0x00,
! 79: SF_PCI_RL | SF_PCI_BOF | SF_BUS_WIDE,
! 80: 4, 8, 3, 250, 0
! 81: },
! 82: { PCI_PRODUCT_SYMBIOS_825,
! 83: 0x10,
! 84: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
! 85: SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_LS | SF_CHIP_10REGS |
! 86: SF_BUS_WIDE,
! 87: 7, 8, 3, 250, 4096
! 88: },
! 89: { PCI_PRODUCT_SYMBIOS_860,
! 90: 0x00,
! 91: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
! 92: SF_CHIP_PF | SF_CHIP_LS |
! 93: SF_BUS_ULTRA,
! 94: 4, 8, 5, 125, 0
! 95: },
! 96: { PCI_PRODUCT_SYMBIOS_875,
! 97: 0x00,
! 98: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
! 99: SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_LS | SF_CHIP_10REGS |
! 100: SF_BUS_ULTRA | SF_BUS_WIDE,
! 101: 7, 16, 5, 125, 4096
! 102: },
! 103: { PCI_PRODUCT_SYMBIOS_875,
! 104: 0x02,
! 105: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
! 106: SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_DBLR |
! 107: SF_CHIP_LS | SF_CHIP_10REGS |
! 108: SF_BUS_ULTRA | SF_BUS_WIDE,
! 109: 7, 16, 5, 125, 4096
! 110: },
! 111: { PCI_PRODUCT_SYMBIOS_875J,
! 112: 0x00,
! 113: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
! 114: SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_DBLR |
! 115: SF_CHIP_LS | SF_CHIP_10REGS |
! 116: SF_BUS_ULTRA | SF_BUS_WIDE,
! 117: 7, 16, 5, 125, 4096
! 118: },
! 119: { PCI_PRODUCT_SYMBIOS_885,
! 120: 0x00,
! 121: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
! 122: SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_DBLR |
! 123: SF_CHIP_LS | SF_CHIP_10REGS |
! 124: SF_BUS_ULTRA | SF_BUS_WIDE,
! 125: 7, 16, 5, 125, 4096
! 126: },
! 127: { PCI_PRODUCT_SYMBIOS_895,
! 128: 0x00,
! 129: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
! 130: SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_QUAD |
! 131: SF_CHIP_LS | SF_CHIP_10REGS |
! 132: SF_BUS_ULTRA2 | SF_BUS_WIDE,
! 133: 7, 31, 7, 62, 4096
! 134: },
! 135: { PCI_PRODUCT_SYMBIOS_896,
! 136: 0x00,
! 137: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
! 138: SF_CHIP_LEDC | SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_QUAD |
! 139: SF_CHIP_LS | SF_CHIP_10REGS |
! 140: SF_BUS_ULTRA2 | SF_BUS_WIDE,
! 141: 7, 31, 7, 62, 8192
! 142: },
! 143: { PCI_PRODUCT_SYMBIOS_895A,
! 144: 0x00,
! 145: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
! 146: SF_CHIP_LEDC | SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_QUAD |
! 147: SF_CHIP_LS | SF_CHIP_10REGS |
! 148: SF_BUS_ULTRA2 | SF_BUS_WIDE,
! 149: 7, 31, 7, 62, 8192
! 150: },
! 151: { PCI_PRODUCT_SYMBIOS_1010,
! 152: 0x00,
! 153: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
! 154: SF_CHIP_LEDC | SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM |
! 155: SF_CHIP_LS | SF_CHIP_10REGS | SF_CHIP_DFBC | SF_CHIP_DBLR |
! 156: SF_CHIP_GEBUG |
! 157: SF_BUS_ULTRA3 | SF_BUS_WIDE,
! 158: 7, 31, 0, 62, 8192
! 159: },
! 160: { PCI_PRODUCT_SYMBIOS_1010,
! 161: 0x01,
! 162: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
! 163: SF_CHIP_LEDC | SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM |
! 164: SF_CHIP_LS | SF_CHIP_10REGS | SF_CHIP_DFBC | SF_CHIP_DBLR | SF_CHIP_DT |
! 165: SF_CHIP_GEBUG |
! 166: SF_BUS_ULTRA3 | SF_BUS_WIDE,
! 167: 7, 62, 0, 62, 8192
! 168: },
! 169: { PCI_PRODUCT_SYMBIOS_1010_2,
! 170: 0x00,
! 171: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
! 172: SF_CHIP_LEDC | SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM |
! 173: SF_CHIP_LS | SF_CHIP_10REGS | SF_CHIP_DFBC | SF_CHIP_DBLR | SF_CHIP_DT |
! 174: SF_CHIP_AAIP |
! 175: SF_BUS_ULTRA3 | SF_BUS_WIDE,
! 176: 7, 62, 0, 62, 8192
! 177: },
! 178: { PCI_PRODUCT_SYMBIOS_1510D,
! 179: 0x00,
! 180: SF_PCI_RL | SF_PCI_CLS | SF_PCI_WRI | SF_PCI_RM |
! 181: SF_CHIP_FIFO | SF_CHIP_PF | SF_CHIP_RAM | SF_CHIP_QUAD |
! 182: SF_CHIP_LS | SF_CHIP_10REGS |
! 183: SF_BUS_ULTRA2 | SF_BUS_WIDE,
! 184: 7, 31, 7, 62, 4096
! 185: },
! 186: { 0,
! 187: 0x00,
! 188: 0x00,
! 189: 0, 0, 0, 0, 0
! 190: },
! 191: };
! 192:
! 193: const struct siop_product_desc *
! 194: siop_lookup_product(u_int32_t id, int rev)
! 195: {
! 196: const struct siop_product_desc *pp;
! 197: const struct siop_product_desc *rp = NULL;
! 198:
! 199: if (PCI_VENDOR(id) != PCI_VENDOR_SYMBIOS)
! 200: return NULL;
! 201:
! 202: for (pp = siop_products; pp->product != 0; pp++) {
! 203: if (PCI_PRODUCT(id) == pp->product && pp->revision <= rev)
! 204: if (rp == NULL || pp->revision > rp->revision)
! 205: rp = pp;
! 206: }
! 207: return rp;
! 208: }
! 209:
! 210: int
! 211: siop_pci_attach_common(struct siop_pci_common_softc *pci_sc,
! 212: struct siop_common_softc *siop_sc, struct pci_attach_args *pa,
! 213: int (*intr)(void*))
! 214: {
! 215: pci_chipset_tag_t pc = pa->pa_pc;
! 216: pcitag_t tag = pa->pa_tag;
! 217: const char *intrstr;
! 218: pci_intr_handle_t intrhandle;
! 219: bus_space_tag_t iot, memt;
! 220: bus_space_handle_t ioh, memh;
! 221: pcireg_t memtype;
! 222: int memh_valid, ioh_valid;
! 223: bus_addr_t ioaddr, memaddr;
! 224: bus_size_t memsize, iosize;
! 225:
! 226: pci_sc->sc_pp =
! 227: siop_lookup_product(pa->pa_id, PCI_REVISION(pa->pa_class));
! 228: if (pci_sc->sc_pp == NULL) {
! 229: printf(": broken match/attach!\n");
! 230: return 0;
! 231: }
! 232: /* copy interesting infos about the chip */
! 233: siop_sc->features = pci_sc->sc_pp->features;
! 234: #ifdef SIOP_SYMLED /* XXX Should be a devprop! */
! 235: siop_sc->features |= SF_CHIP_LED0;
! 236: #endif
! 237: siop_sc->maxburst = pci_sc->sc_pp->maxburst;
! 238: siop_sc->maxoff = pci_sc->sc_pp->maxoff;
! 239: siop_sc->clock_div = pci_sc->sc_pp->clock_div;
! 240: siop_sc->clock_period = pci_sc->sc_pp->clock_period;
! 241: siop_sc->ram_size = pci_sc->sc_pp->ram_size;
! 242:
! 243: siop_sc->sc_reset = siop_pci_reset;
! 244: pci_sc->sc_pc = pc;
! 245: pci_sc->sc_tag = tag;
! 246: siop_sc->sc_dmat = pa->pa_dmat;
! 247:
! 248: memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, 0x14);
! 249: switch (memtype) {
! 250: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
! 251: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
! 252: memh_valid = (pci_mapreg_map(pa, 0x14, memtype, 0,
! 253: &memt, &memh, &memaddr, NULL, 0) == 0);
! 254: break;
! 255: default:
! 256: memh_valid = 0;
! 257: }
! 258:
! 259: ioh_valid = (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_IO, 0,
! 260: &iot, &ioh, &ioaddr, &iosize, 0) == 0);
! 261:
! 262: if (memh_valid) {
! 263: siop_sc->sc_rt = memt;
! 264: siop_sc->sc_rh = memh;
! 265: siop_sc->sc_raddr = memaddr;
! 266: } else if (ioh_valid) {
! 267: siop_sc->sc_rt = iot;
! 268: siop_sc->sc_rh = ioh;
! 269: siop_sc->sc_raddr = ioaddr;
! 270: } else {
! 271: printf(": unable to map device registers\n");
! 272: return 0;
! 273: }
! 274:
! 275: if (pci_intr_map(pa, &intrhandle) != 0) {
! 276: printf(": couldn't map interrupt\n");
! 277: bus_space_unmap(siop_sc->sc_rt, siop_sc->sc_rh, iosize);
! 278: return 0;
! 279: }
! 280: intrstr = pci_intr_string(pa->pa_pc, intrhandle);
! 281: pci_sc->sc_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_BIO,
! 282: intr, siop_sc, siop_sc->sc_dev.dv_xname);
! 283: if (pci_sc->sc_ih != NULL) {
! 284: printf(": %s",
! 285: intrstr ? intrstr : "?");
! 286: } else {
! 287: printf(": couldn't establish interrupt");
! 288: if (intrstr != NULL)
! 289: printf(" at %s", intrstr);
! 290: printf("\n");
! 291: bus_space_unmap(siop_sc->sc_rt, siop_sc->sc_rh, iosize);
! 292: return 0;
! 293: }
! 294:
! 295: if (siop_sc->features & SF_CHIP_RAM) {
! 296: int bar;
! 297: switch (memtype) {
! 298: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
! 299: bar = 0x18;
! 300: break;
! 301: case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
! 302: bar = 0x1c;
! 303: break;
! 304: default:
! 305: printf(": invalid memory type %d\n", memtype);
! 306: return 0;
! 307: }
! 308: if (pci_mapreg_map(pa, bar, memtype, 0,
! 309: &siop_sc->sc_ramt, &siop_sc->sc_ramh,
! 310: &siop_sc->sc_scriptaddr, &memsize, 0) == 0) {
! 311: printf(", using %luK of on-board RAM",
! 312: (u_long)memsize / 1024);
! 313: } else {
! 314: printf(", can't map on-board RAM");
! 315: siop_sc->features &= ~SF_CHIP_RAM;
! 316: }
! 317: }
! 318:
! 319: printf("\n");
! 320:
! 321: return 1;
! 322: }
! 323:
! 324: void
! 325: siop_pci_reset(struct siop_common_softc *sc)
! 326: {
! 327: int dmode;
! 328:
! 329: dmode = bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_DMODE);
! 330: if (sc->features & SF_PCI_RL)
! 331: dmode |= DMODE_ERL;
! 332: if (sc->features & SF_PCI_RM)
! 333: dmode |= DMODE_ERMP;
! 334: if (sc->features & SF_PCI_BOF)
! 335: dmode |= DMODE_BOF;
! 336: if (sc->features & SF_PCI_CLS)
! 337: bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_DCNTL,
! 338: bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_DCNTL) |
! 339: DCNTL_CLSE);
! 340: if (sc->features & SF_PCI_WRI)
! 341: bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST3,
! 342: bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST3) |
! 343: CTEST3_WRIE);
! 344: if (sc->maxburst) {
! 345: int ctest5 = bus_space_read_1(sc->sc_rt, sc->sc_rh,
! 346: SIOP_CTEST5);
! 347: bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST4,
! 348: bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST4) &
! 349: ~CTEST4_BDIS);
! 350: dmode &= ~DMODE_BL_MASK;
! 351: dmode |= ((sc->maxburst - 1) << DMODE_BL_SHIFT) & DMODE_BL_MASK;
! 352: ctest5 &= ~CTEST5_BBCK;
! 353: ctest5 |= (sc->maxburst - 1) & CTEST5_BBCK;
! 354: bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST5, ctest5);
! 355: } else {
! 356: bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST4,
! 357: bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST4) |
! 358: CTEST4_BDIS);
! 359: }
! 360: bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_DMODE, dmode);
! 361: }
CVSweb