/* * Attach this instance, and then all the sub-devices */ static int esp_pci_attach(device_t dev) { struct esp_pci_softc *esc; struct ncr53c9x_softc *sc; int error; esc = device_get_softc(dev); sc = &esc->sc_ncr53c9x; NCR_LOCK_INIT(sc); esc->sc_dev = dev; sc->sc_glue = &esp_pci_glue; pci_enable_busmaster(dev); error = bus_alloc_resources(dev, esp_pci_res_spec, esc->sc_res); if (error != 0) { device_printf(dev, "failed to allocate resources\n"); bus_release_resources(dev, esp_pci_res_spec, esc->sc_res); return (error); } error = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, BUS_SPACE_MAXSIZE_32BIT, BUS_SPACE_UNRESTRICTED, BUS_SPACE_MAXSIZE_32BIT, 0, NULL, NULL, &esc->sc_pdmat); if (error != 0) { device_printf(dev, "cannot create parent DMA tag\n"); goto fail_res; } /* * XXX More of this should be in ncr53c9x_attach(), but * XXX should we really poke around the chip that much in * XXX the MI code? Think about this more... */ /* * Set up static configuration info. * * XXX we should read the configuration from the EEPROM. */ sc->sc_id = 7; sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB; sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_FE; sc->sc_cfg3 = NCRAMDCFG3_IDM | NCRAMDCFG3_FCLK; sc->sc_cfg4 = NCRAMDCFG4_GE12NS | NCRAMDCFG4_RADE; sc->sc_rev = NCR_VARIANT_AM53C974; sc->sc_features = NCR_F_FASTSCSI | NCR_F_DMASELECT; sc->sc_cfg3_fscsi = NCRAMDCFG3_FSCSI; sc->sc_freq = 40; /* MHz */ /* * This is the value used to start sync negotiations * Note that the NCR register "SYNCTP" is programmed * in "clocks per byte", and has a minimum value of 4. * The SCSI period used in negotiation is one-fourth * of the time (in nanoseconds) needed to transfer one byte. * Since the chip's clock is given in MHz, we have the following * formula: 4 * period = (1000 / freq) * 4 */ sc->sc_minsync = 1000 / sc->sc_freq; sc->sc_maxxfer = DFLTPHYS; /* see below */ sc->sc_maxoffset = 15; sc->sc_extended_geom = 1; #define MDL_SEG_SIZE 0x1000 /* 4kbyte per segment */ /* * Create the DMA tag and map for the data transfers. * * Note: given that bus_dma(9) only adheres to the requested alignment * for the first segment (and that also only for bus_dmamem_alloc()ed * DMA maps) we can't use the Memory Descriptor List. However, also * when not using the MDL, the maximum transfer size apparently is * limited to 4k so we have to split transfers up, which plain sucks. */ error = bus_dma_tag_create(esc->sc_pdmat, PAGE_SIZE, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MDL_SEG_SIZE, 1, MDL_SEG_SIZE, BUS_DMA_ALLOCNOW, busdma_lock_mutex, &sc->sc_lock, &esc->sc_xferdmat); if (error != 0) { device_printf(dev, "cannot create transfer DMA tag\n"); goto fail_pdmat; } error = bus_dmamap_create(esc->sc_xferdmat, 0, &esc->sc_xferdmam); if (error != 0) { device_printf(dev, "cannot create transfer DMA map\n"); goto fail_xferdmat; } error = bus_setup_intr(dev, esc->sc_res[ESP_PCI_RES_INTR], INTR_MPSAFE | INTR_TYPE_CAM, NULL, ncr53c9x_intr, sc, &esc->sc_ih); if (error != 0) { device_printf(dev, "cannot set up interrupt\n"); goto fail_xferdmam; } /* Do the common parts of attachment. */ sc->sc_dev = esc->sc_dev; error = ncr53c9x_attach(sc); if (error != 0) { device_printf(esc->sc_dev, "ncr53c9x_attach failed\n"); goto fail_intr; } return (0); fail_intr: bus_teardown_intr(esc->sc_dev, esc->sc_res[ESP_PCI_RES_INTR], esc->sc_ih); fail_xferdmam: bus_dmamap_destroy(esc->sc_xferdmat, esc->sc_xferdmam); fail_xferdmat: bus_dma_tag_destroy(esc->sc_xferdmat); fail_pdmat: bus_dma_tag_destroy(esc->sc_pdmat); fail_res: bus_release_resources(dev, esp_pci_res_spec, esc->sc_res); NCR_LOCK_DESTROY(sc); return (error); }
static int espattach(struct esp_softc *esc, const struct ncr53c9x_glue *gluep) { struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x; unsigned int uid = 0; int error, i; NCR_LOCK_INIT(sc); /* Attach the DMA engine. */ error = lsi64854_attach(esc->sc_dma); if (error != 0) { device_printf(esc->sc_dev, "lsi64854_attach failed\n"); goto fail_lock; } sc->sc_id = OF_getscsinitid(esc->sc_dev); #ifdef ESP_SBUS_DEBUG device_printf(esc->sc_dev, "%s: sc_id %d, freq %d\n", __func__, sc->sc_id, sc->sc_freq); #endif /* * The `ESC' DMA chip must be reset before we can access * the ESP registers. */ if (esc->sc_dma->sc_rev == DMAREV_ESC) DMA_RESET(esc->sc_dma); /* * Set up glue for MI code early; we use some of it here. */ sc->sc_glue = gluep; /* gimme MHz */ sc->sc_freq /= 1000000; /* * XXX More of this should be in ncr53c9x_attach(), but * XXX should we really poke around the chip that much in * XXX the MI code? Think about this more... */ /* * Read the part-unique ID code of the SCSI chip. The contained * value is only valid if all of the following conditions are met: * - After power-up or chip reset. * - Before any value is written to this register. * - The NCRCFG2_FE bit is set. * - A (NCRCMD_NOP | NCRCMD_DMA) command has been issued. */ NCRCMD(sc, NCRCMD_RSTCHIP); NCRCMD(sc, NCRCMD_NOP); sc->sc_cfg2 = NCRCFG2_FE; NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); NCRCMD(sc, NCRCMD_NOP | NCRCMD_DMA); uid = NCR_READ_REG(sc, NCR_UID); /* * It is necessary to try to load the 2nd config register here, * to find out what rev the esp chip is, else the ncr53c9x_reset * will not set up the defaults correctly. */ sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB; NCR_WRITE_REG(sc, NCR_CFG1, sc->sc_cfg1); sc->sc_cfg2 = 0; NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_RPE; NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); if ((NCR_READ_REG(sc, NCR_CFG2) & ~NCRCFG2_RSVD) != (NCRCFG2_SCSI2 | NCRCFG2_RPE)) { sc->sc_rev = NCR_VARIANT_ESP100; } else { sc->sc_cfg2 = NCRCFG2_SCSI2; NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2); sc->sc_cfg3 = 0; NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); sc->sc_cfg3 = (NCRCFG3_CDB | NCRCFG3_FCLK); NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); if (NCR_READ_REG(sc, NCR_CFG3) != (NCRCFG3_CDB | NCRCFG3_FCLK)) { sc->sc_rev = NCR_VARIANT_ESP100A; } else { /* NCRCFG2_FE enables > 64K transfers. */ sc->sc_cfg2 |= NCRCFG2_FE; sc->sc_cfg3 = 0; NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3); if (sc->sc_freq <= 25) sc->sc_rev = NCR_VARIANT_ESP200; else { switch ((uid & 0xf8) >> 3) { case 0x00: sc->sc_rev = NCR_VARIANT_FAS100A; break; case 0x02: if ((uid & 0x07) == 0x02) sc->sc_rev = NCR_VARIANT_FAS216; else sc->sc_rev = NCR_VARIANT_FAS236; break; case 0x0a: sc->sc_rev = NCR_VARIANT_FAS366; break; default: /* * We could just treat unknown chips * as ESP200 but then we would most * likely drive them out of specs. */ device_printf(esc->sc_dev, "Unknown chip\n"); goto fail_lsi; } } } } #ifdef ESP_SBUS_DEBUG printf("%s: revision %d, uid 0x%x\n", __func__, sc->sc_rev, uid); #endif /* * XXX minsync and maxxfer _should_ be set up in MI code, * XXX but it appears to have some dependency on what sort * XXX of DMA we're hooked up to, etc. */ /* * This is the value used to start sync negotiations * Note that the NCR register "SYNCTP" is programmed * in "clocks per byte", and has a minimum value of 4. * The SCSI period used in negotiation is one-fourth * of the time (in nanoseconds) needed to transfer one byte. * Since the chip's clock is given in MHz, we have the following * formula: 4 * period = (1000 / freq) * 4 */ sc->sc_minsync = 1000 / sc->sc_freq; sc->sc_maxoffset = 15; sc->sc_extended_geom = 1; /* * Alas, we must now modify the value a bit, because it's * only valid when can switch on FASTCLK and FASTSCSI bits * in config register 3... */ switch (sc->sc_rev) { case NCR_VARIANT_ESP100: sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT; sc->sc_maxxfer = 64 * 1024; sc->sc_minsync = 0; /* No synch on old chip? */ break; case NCR_VARIANT_ESP100A: sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT; sc->sc_maxxfer = 64 * 1024; /* Min clocks/byte is 5 */ sc->sc_minsync = ncr53c9x_cpb2stp(sc, 5); break; case NCR_VARIANT_ESP200: sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT; sc->sc_maxxfer = 16 * 1024 * 1024; /* Min clocks/byte is 5 */ sc->sc_minsync = ncr53c9x_cpb2stp(sc, 5); break; case NCR_VARIANT_FAS100A: case NCR_VARIANT_FAS216: case NCR_VARIANT_FAS236: /* * The onboard SCSI chips in Sun Ultra 1 are actually * documented to be NCR53C9X which use NCRCFG3_FCLK and * NCRCFG3_FSCSI. BSD/OS however probes these chips as * FAS100A and uses NCRF9XCFG3_FCLK and NCRF9XCFG3_FSCSI * instead which seems to be correct as otherwise sync * negotiation just doesn't work. Using NCRF9XCFG3_FCLK * and NCRF9XCFG3_FSCSI with these chips in fact also * yields Fast-SCSI speed. */ sc->sc_features = NCR_F_FASTSCSI; sc->sc_cfg3 = NCRF9XCFG3_FCLK; sc->sc_cfg3_fscsi = NCRF9XCFG3_FSCSI; sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT; sc->sc_maxxfer = 16 * 1024 * 1024; break; case NCR_VARIANT_FAS366: sc->sc_maxwidth = MSG_EXT_WDTR_BUS_16_BIT; sc->sc_maxxfer = 16 * 1024 * 1024; break; } /* Establish interrupt channel. */ i = 0; if ((esc->sc_irqres = bus_alloc_resource_any(esc->sc_dev, SYS_RES_IRQ, &i, RF_SHAREABLE|RF_ACTIVE)) == NULL) { device_printf(esc->sc_dev, "cannot allocate interrupt\n"); goto fail_lsi; } if (bus_setup_intr(esc->sc_dev, esc->sc_irqres, INTR_MPSAFE | INTR_TYPE_CAM, NULL, ncr53c9x_intr, sc, &esc->sc_irq)) { device_printf(esc->sc_dev, "cannot set up interrupt\n"); error = ENXIO; goto fail_ires; } /* Turn on target selection using the `DMA' method. */ if (sc->sc_rev != NCR_VARIANT_FAS366) sc->sc_features |= NCR_F_DMASELECT; /* Do the common parts of attachment. */ sc->sc_dev = esc->sc_dev; error = ncr53c9x_attach(sc); if (error != 0) { device_printf(esc->sc_dev, "ncr53c9x_attach failed\n"); goto fail_intr; } return (0); fail_intr: bus_teardown_intr(esc->sc_dev, esc->sc_irqres, esc->sc_irq); fail_ires: bus_release_resource(esc->sc_dev, SYS_RES_IRQ, rman_get_rid(esc->sc_irqres), esc->sc_irqres); fail_lsi: lsi64854_detach(esc->sc_dma); fail_lock: NCR_LOCK_DESTROY(sc); return (error); }