void oosiop_attach(struct oosiop_softc *sc) { struct scsibus_attach_args saa; bus_size_t scrsize; bus_dma_segment_t seg; struct oosiop_cb *cb; int err, i, nseg; /* * Allocate DMA-safe memory for the script and map it. */ scrsize = round_page(sizeof(oosiop_script)); err = bus_dmamem_alloc(sc->sc_dmat, scrsize, PAGE_SIZE, 0, &seg, 1, &nseg, BUS_DMA_NOWAIT | BUS_DMA_ZERO); if (err) { printf(": failed to allocate script memory, err=%d\n", err); return; } err = bus_dmamem_map(sc->sc_dmat, &seg, nseg, scrsize, (caddr_t *)&sc->sc_scr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT); if (err) { printf(": failed to map script memory, err=%d\n", err); return; } err = bus_dmamap_create(sc->sc_dmat, scrsize, 1, scrsize, 0, BUS_DMA_NOWAIT, &sc->sc_scrdma); if (err) { printf(": failed to create script map, err=%d\n", err); return; } err = bus_dmamap_load_raw(sc->sc_dmat, sc->sc_scrdma, &seg, nseg, scrsize, BUS_DMA_NOWAIT | BUS_DMA_WRITE); if (err) { printf(": failed to load script map, err=%d\n", err); return; } sc->sc_scrbase = sc->sc_scrdma->dm_segs[0].ds_addr; /* Initialize command block array */ TAILQ_INIT(&sc->sc_free_cb); TAILQ_INIT(&sc->sc_cbq); if (oosiop_alloc_cb(sc, OOSIOP_NCB) != 0) return; /* Use first cb to reselection msgin buffer */ cb = TAILQ_FIRST(&sc->sc_free_cb); sc->sc_reselbuf = cb->xferdma->dm_segs[0].ds_addr + offsetof(struct oosiop_xfer, msgin[0]); for (i = 0; i < OOSIOP_NTGT; i++) { sc->sc_tgt[i].nexus = NULL; sc->sc_tgt[i].flags = 0; } /* Setup asynchronous clock divisor parameters */ if (sc->sc_freq <= 25000000) { sc->sc_ccf = 10; sc->sc_dcntl = OOSIOP_DCNTL_CF_1; } else if (sc->sc_freq <= 37500000) { sc->sc_ccf = 15; sc->sc_dcntl = OOSIOP_DCNTL_CF_1_5; } else if (sc->sc_freq <= 50000000) { sc->sc_ccf = 20; sc->sc_dcntl = OOSIOP_DCNTL_CF_2; } else { sc->sc_ccf = 30; sc->sc_dcntl = OOSIOP_DCNTL_CF_3; } if (sc->sc_chip == OOSIOP_700) sc->sc_minperiod = oosiop_period(sc, 4, sc->sc_ccf); else sc->sc_minperiod = oosiop_period(sc, 4, 10); if (sc->sc_minperiod < 25) sc->sc_minperiod = 25; /* limit to 10MB/s */ mtx_init(&sc->sc_cb_mtx, IPL_BIO); scsi_iopool_init(&sc->sc_iopool, sc, oosiop_cb_alloc, oosiop_cb_free); printf(": NCR53C700%s rev %d, %dMHz\n", sc->sc_chip == OOSIOP_700_66 ? "-66" : "", oosiop_read_1(sc, OOSIOP_CTEST7) >> 4, sc->sc_freq / 1000000); /* * Reset all */ oosiop_reset(sc, TRUE); oosiop_reset_bus(sc); /* * Start SCRIPTS processor */ oosiop_load_script(sc); sc->sc_active = 0; oosiop_write_4(sc, OOSIOP_DSP, sc->sc_scrbase + Ent_wait_reselect); /* * Fill in the sc_link. */ sc->sc_link.adapter = &oosiop_adapter; sc->sc_link.adapter_softc = sc; sc->sc_link.openings = 1; /* XXX */ sc->sc_link.adapter_buswidth = OOSIOP_NTGT; sc->sc_link.adapter_target = sc->sc_id; sc->sc_link.pool = &sc->sc_iopool; sc->sc_link.quirks = ADEV_NODOORLOCK; bzero(&saa, sizeof(saa)); saa.saa_sc_link = &sc->sc_link; /* * Now try to attach all the sub devices. */ config_found(&sc->sc_dev, &saa, scsiprint); }
void oosiop_attach(struct oosiop_softc *sc) { bus_size_t scrsize; bus_dma_segment_t seg; struct oosiop_cb *cb; int err, i, nseg; /* * Allocate DMA-safe memory for the script and map it. */ scrsize = sizeof(oosiop_script); err = bus_dmamem_alloc(sc->sc_dmat, scrsize, PAGE_SIZE, 0, &seg, 1, &nseg, BUS_DMA_NOWAIT); if (err) { printf(": failed to allocate script memory, err=%d\n", err); return; } err = bus_dmamem_map(sc->sc_dmat, &seg, nseg, scrsize, (caddr_t *)&sc->sc_scr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT); if (err) { printf(": failed to map script memory, err=%d\n", err); return; } err = bus_dmamap_create(sc->sc_dmat, scrsize, 1, scrsize, 0, BUS_DMA_NOWAIT, &sc->sc_scrdma); if (err) { printf(": failed to create script map, err=%d\n", err); return; } err = bus_dmamap_load(sc->sc_dmat, sc->sc_scrdma, sc->sc_scr, scrsize, NULL, BUS_DMA_NOWAIT | BUS_DMA_WRITE); if (err) { printf(": failed to load script map, err=%d\n", err); return; } sc->sc_scrbase = sc->sc_scrdma->dm_segs[0].ds_addr; /* Initialize command block array */ TAILQ_INIT(&sc->sc_free_cb); TAILQ_INIT(&sc->sc_cbq); if (oosiop_alloc_cb(sc, OOSIOP_NCB) != 0) return; /* Use first cb to reselection msgin buffer */ cb = TAILQ_FIRST(&sc->sc_free_cb); sc->sc_reselbuf = cb->xferdma->dm_segs[0].ds_addr + offsetof(struct oosiop_xfer, msgin[0]); for (i = 0; i < OOSIOP_NTGT; i++) { sc->sc_tgt[i].nexus = NULL; sc->sc_tgt[i].flags = 0; } /* Setup asynchronous clock divisor parameters */ if (sc->sc_freq <= 25000000) { sc->sc_ccf = 10; sc->sc_dcntl = OOSIOP_DCNTL_CF_1; } else if (sc->sc_freq <= 37500000) { sc->sc_ccf = 15; sc->sc_dcntl = OOSIOP_DCNTL_CF_1_5; } else if (sc->sc_freq <= 50000000) { sc->sc_ccf = 20; sc->sc_dcntl = OOSIOP_DCNTL_CF_2; } else { sc->sc_ccf = 30; sc->sc_dcntl = OOSIOP_DCNTL_CF_3; } if (sc->sc_chip == OOSIOP_700) sc->sc_minperiod = oosiop_period(sc, 4, sc->sc_ccf); else sc->sc_minperiod = oosiop_period(sc, 4, 10); if (sc->sc_minperiod < 25) sc->sc_minperiod = 25; /* limit to 10MB/s */ printf(": NCR53C700%s rev %d, %dMHz, SCSI ID %d\n", sc->sc_chip == OOSIOP_700_66 ? "-66" : "", oosiop_read_1(sc, OOSIOP_CTEST7) >> 4, sc->sc_freq / 1000000, sc->sc_id); /* * Reset all */ oosiop_reset(sc); oosiop_reset_bus(sc); /* * Start SCRIPTS processor */ oosiop_load_script(sc); sc->sc_active = 0; oosiop_write_4(sc, OOSIOP_DSP, sc->sc_scrbase + Ent_wait_reselect); /* * Fill in the scsipi_adapter. */ sc->sc_adapter.adapt_dev = &sc->sc_dev; sc->sc_adapter.adapt_nchannels = 1; sc->sc_adapter.adapt_openings = OOSIOP_NCB; sc->sc_adapter.adapt_max_periph = 1; sc->sc_adapter.adapt_ioctl = NULL; sc->sc_adapter.adapt_minphys = oosiop_minphys; sc->sc_adapter.adapt_request = oosiop_scsipi_request; /* * Fill in the scsipi_channel. */ sc->sc_channel.chan_adapter = &sc->sc_adapter; sc->sc_channel.chan_bustype = &scsi_bustype; sc->sc_channel.chan_channel = 0; sc->sc_channel.chan_ntargets = OOSIOP_NTGT; sc->sc_channel.chan_nluns = 8; sc->sc_channel.chan_id = sc->sc_id; /* * Now try to attach all the sub devices. */ config_found(&sc->sc_dev, &sc->sc_channel, scsiprint); }