Ejemplo n.º 1
0
static void
nca_pci_attach(device_t parent, device_t self, void *aux)
{
	struct ncr5380_softc *sc = device_private(self);
	struct pci_attach_args *pa = aux;

	sc->sc_dev = self;

	pci_aprint_devinfo(pa, "SCSI controller");

	if (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_IO, 0,
            &sc->sc_regt, &sc->sc_regh, NULL, NULL)) {
                aprint_error_dev(self, "could not map IO space\n");
                return;
        }
	
	/* The Domex 536 seems to be driven by polling,
	 * don't bother mapping an interrupt handler.
	 */
	
	sc->sc_rev = NCR_VARIANT_CXD1180;
	sc->sci_r0 = 0;
	sc->sci_r1 = 1;
	sc->sci_r2 = 2;
	sc->sci_r3 = 3;
	sc->sci_r4 = 4;
	sc->sci_r5 = 5;
	sc->sci_r6 = 6;
	sc->sci_r7 = 7;

	sc->sc_pio_out = ncr5380_pio_out;
	sc->sc_pio_in =  ncr5380_pio_in;
	sc->sc_dma_alloc = NULL;
	sc->sc_dma_free  = NULL;
	sc->sc_dma_setup = NULL;
	sc->sc_dma_start = NULL;
	sc->sc_dma_poll  = NULL;
	sc->sc_dma_eop   = NULL;
	sc->sc_dma_stop  = NULL;
	sc->sc_intr_on   = NULL;
	sc->sc_intr_off  = NULL;

	sc->sc_flags |= NCR5380_FORCE_POLLING;

	sc->sc_min_dma_len = 0;

	sc->sc_adapter.adapt_request = ncr5380_scsipi_request;
	sc->sc_adapter.adapt_minphys = minphys;

	sc->sc_channel.chan_id = 7;

	ncr5380_attach(sc);
}
Ejemplo n.º 2
0
void
hcsc_attach(device_t parent, device_t self, void *aux)
{
	struct hcsc_softc *sc = device_private(self);
	struct ncr5380_softc *ncr_sc = &sc->sc_ncr5380;
	struct podulebus_attach_args *pa = aux;
#ifndef NCR5380_USE_BUS_SPACE
	uint8_t *iobase;
#endif
	char hi_option[sizeof(self->dv_xname) + 8];

	ncr_sc->sc_dev = self;
	ncr_sc->sc_min_dma_len = 0;
	ncr_sc->sc_no_disconnect = 0;
	ncr_sc->sc_parity_disable = 0;

	ncr_sc->sc_dma_alloc = NULL;
	ncr_sc->sc_dma_free = NULL;
	ncr_sc->sc_dma_poll = NULL;
	ncr_sc->sc_dma_setup = NULL;
	ncr_sc->sc_dma_start = NULL;
	ncr_sc->sc_dma_eop = NULL;
	ncr_sc->sc_dma_stop = NULL;
	ncr_sc->sc_intr_on = NULL;
	ncr_sc->sc_intr_off = NULL;

#ifdef NCR5380_USE_BUS_SPACE
	ncr_sc->sc_regt = pa->pa_fast_t;
	bus_space_map(ncr_sc->sc_regt,
	    pa->pa_fast_base + HCSC_DP8490_OFFSET, 8, 0,
	    &ncr_sc->sc_regh);
	ncr_sc->sci_r0 = 0;
	ncr_sc->sci_r1 = 1;
	ncr_sc->sci_r2 = 2;
	ncr_sc->sci_r3 = 3;
	ncr_sc->sci_r4 = 4;
	ncr_sc->sci_r5 = 5;
	ncr_sc->sci_r6 = 6;
	ncr_sc->sci_r7 = 7;
#else
	iobase = (u_char *)pa->pa_fast_base + HCSC_DP8490_OFFSET;
	ncr_sc->sci_r0 = iobase + 0;
	ncr_sc->sci_r1 = iobase + 4;
	ncr_sc->sci_r2 = iobase + 8;
	ncr_sc->sci_r3 = iobase + 12;
	ncr_sc->sci_r4 = iobase + 16;
	ncr_sc->sci_r5 = iobase + 20;
	ncr_sc->sci_r6 = iobase + 24;
	ncr_sc->sci_r7 = iobase + 28;
#endif
	sc->sc_pdmat = pa->pa_mod_t;
	bus_space_map(sc->sc_pdmat, pa->pa_mod_base + HCSC_PDMA_OFFSET, 1, 0,
	    &sc->sc_pdmah);

	ncr_sc->sc_rev = NCR_VARIANT_DP8490;

	ncr_sc->sc_pio_in = hcsc_pdma_in;
	ncr_sc->sc_pio_out = hcsc_pdma_out;

	/* Provide an override for the host id */
	ncr_sc->sc_channel.chan_id = 7;
	snprintf(hi_option, sizeof(hi_option), "%s.hostid",
	    device_xname(self));
	(void)get_bootconf_option(boot_args, hi_option,
	    BOOTOPT_TYPE_INT, &ncr_sc->sc_channel.chan_id);
	ncr_sc->sc_adapter.adapt_minphys = minphys;

	aprint_normal(": host ID %d\n", ncr_sc->sc_channel.chan_id);

	evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
	    device_xname(self), "intr");
	sc->sc_ih = podulebus_irq_establish(pa->pa_ih, IPL_BIO, ncr5380_intr,
	    sc, &sc->sc_intrcnt);

	ncr5380_attach(ncr_sc);
}
Ejemplo n.º 3
0
static void
sbc_obio_attach(device_t parent, device_t self, void *aux)
{
	struct sbc_softc *sc = device_private(self);
	struct ncr5380_softc *ncr_sc = &sc->ncr_sc;
	struct obio_attach_args *oa = aux;
	char bits[64];
	extern vaddr_t SCSIBase;

	ncr_sc->sc_dev = self;
	/* Pull in the options flags. */ 
	sc->sc_options = ((device_cfdata(self)->cf_flags |
			   sbc_options) & SBC_OPTIONS_MASK);

	/*
	 * Set up offsets to 5380 registers and GLUE I/O space, and turn
	 * off options we know we can't support on certain models.
	 */
	switch (current_mac_model->machineid) {
	case MACH_MACIIFX:	/* Note: the IIfx isn't (yet) supported. */
		sc->sc_regs = (struct sbc_regs *)(SCSIBase + SBC_REG_OFS_IIFX);
		sc->sc_drq_addr = (vaddr_t)(SCSIBase + SBC_HSK_OFS_IIFX);
		sc->sc_nodrq_addr = (vaddr_t)(SCSIBase + SBC_DMA_OFS_IIFX);
		sc->sc_options &= ~(SBC_INTR | SBC_RESELECT);
		break;
	case MACH_MACPB500:
		sc->sc_regs = (struct sbc_regs *)(SCSIBase + SBC_REG_OFS);
		sc->sc_drq_addr = (vaddr_t)(SCSIBase + SBC_HSK_OFS); /*??*/
		sc->sc_nodrq_addr = (vaddr_t)(SCSIBase + SBC_DMA_OFS_PB500);
		sc->sc_options &= ~(SBC_INTR | SBC_RESELECT);
		break;
	case MACH_MACPB210:
	case MACH_MACPB230:
	case MACH_MACPB250:
	case MACH_MACPB270:
	case MACH_MACPB280:
	case MACH_MACPB280C:
		if (oa->oa_addr == 1) {
			sc->sc_regs = (struct sbc_regs *)(0xfee00000 + SBC_REG_OFS_DUO2);
			sc->sc_drq_addr = (vaddr_t)(0xfee00000 + SBC_HSK_OFS_DUO2);
			sc->sc_nodrq_addr = (vaddr_t)(0xfee00000 + SBC_DMA_OFS_DUO2);
			break;
		}
		/*FALLTHROUGH*/
	default:
		sc->sc_regs = (struct sbc_regs *)(SCSIBase + SBC_REG_OFS);
		sc->sc_drq_addr = (vaddr_t)(SCSIBase + SBC_HSK_OFS);
		sc->sc_nodrq_addr = (vaddr_t)(SCSIBase + SBC_DMA_OFS);
		break;
	}

	/*
	 * Initialize fields used by the MI code
	 */
	ncr_sc->sci_r0 = &sc->sc_regs->sci_pr0.sci_reg;
	ncr_sc->sci_r1 = &sc->sc_regs->sci_pr1.sci_reg;
	ncr_sc->sci_r2 = &sc->sc_regs->sci_pr2.sci_reg;
	ncr_sc->sci_r3 = &sc->sc_regs->sci_pr3.sci_reg;
	ncr_sc->sci_r4 = &sc->sc_regs->sci_pr4.sci_reg;
	ncr_sc->sci_r5 = &sc->sc_regs->sci_pr5.sci_reg;
	ncr_sc->sci_r6 = &sc->sc_regs->sci_pr6.sci_reg;
	ncr_sc->sci_r7 = &sc->sc_regs->sci_pr7.sci_reg;

	ncr_sc->sc_rev = NCR_VARIANT_NCR5380;

	/*
	 * MD function pointers used by the MI code.
	 */
	if (sc->sc_options & SBC_PDMA) {
		ncr_sc->sc_pio_out   = sbc_pdma_out;
		ncr_sc->sc_pio_in    = sbc_pdma_in;
	} else {
		ncr_sc->sc_pio_out   = ncr5380_pio_out;
		ncr_sc->sc_pio_in    = ncr5380_pio_in;
	}
	ncr_sc->sc_dma_alloc = NULL;
	ncr_sc->sc_dma_free  = NULL;
	ncr_sc->sc_dma_poll  = NULL;
	ncr_sc->sc_intr_on   = NULL;
	ncr_sc->sc_intr_off  = NULL;
	ncr_sc->sc_dma_setup = NULL;
	ncr_sc->sc_dma_start = NULL;
	ncr_sc->sc_dma_eop   = NULL;
	ncr_sc->sc_dma_stop  = NULL;
	ncr_sc->sc_flags = 0;
	ncr_sc->sc_min_dma_len = MIN_DMA_LEN;

	if (sc->sc_options & SBC_INTR) {
		ncr_sc->sc_dma_alloc = sbc_dma_alloc;
		ncr_sc->sc_dma_free  = sbc_dma_free;
		ncr_sc->sc_dma_poll  = sbc_dma_poll;
		ncr_sc->sc_dma_setup = sbc_dma_setup;
		ncr_sc->sc_dma_start = sbc_dma_start;
		ncr_sc->sc_dma_eop   = sbc_dma_eop;
		ncr_sc->sc_dma_stop  = sbc_dma_stop;
		via2_register_irq(VIA2_SCSIDRQ, sbc_drq_intr, ncr_sc);
	}

	via2_register_irq(VIA2_SCSIIRQ, sbc_irq_intr, ncr_sc);
	sc->sc_clrintr = sbc_obio_clrintr;

	if ((sc->sc_options & SBC_RESELECT) == 0)
		ncr_sc->sc_no_disconnect = 0xff;

	if (sc->sc_options) {
		snprintb(bits, sizeof(bits), SBC_OPTIONS_BITS, sc->sc_options);
		aprint_normal(": options=%s", bits);
	}
	aprint_normal("\n");

	if (sc->sc_options & (SBC_INTR|SBC_RESELECT)) {
		/* Enable SCSI interrupts through VIA2 */
		sbc_intr_enable(ncr_sc);
	}

#ifdef SBC_DEBUG
	if (sbc_debug)
		aprint_debug_dev(self, "softc=%p regs=%p\n", sc, sc->sc_regs);
#endif

	ncr_sc->sc_channel.chan_id = 7;
	ncr_sc->sc_adapter.adapt_minphys = minphys;

	/*
	 *  Initialize the SCSI controller itself.
	 */
	ncr5380_attach(ncr_sc);
}
Ejemplo n.º 4
0
static void 
se_attach(device_t parent, device_t self, void *args)
{
	struct se_softc *sc = device_private(self);
	struct ncr5380_softc *ncr_sc = &sc->ncr_sc;
	struct cfdata *cf = device_cfdata(self);
	struct sebuf_attach_args *aa = args;
	volatile struct se_regs *regs;
	int i;

	ncr_sc->sc_dev = self;

	/* Get options from config flags if specified. */
	if (cf->cf_flags)
		sc->sc_options = cf->cf_flags;
	else
		sc->sc_options = se_options;

	aprint_normal(": options=0x%x\n", sc->sc_options);

	sc->sc_adapter_type = aa->ca.ca_bustype;
	sc->sc_adapter_iv = aa->ca.ca_intvec;
	sc->sc_regs = regs = aa->regs;

	/*
	 * MD function pointers used by the MI code.
	 */
	ncr_sc->sc_pio_out = ncr5380_pio_out;
	ncr_sc->sc_pio_in =  ncr5380_pio_in;

#if 0	/* XXX - not yet... */
	ncr_sc->sc_dma_alloc = se_dma_alloc;
	ncr_sc->sc_dma_free  = se_dma_free;
	ncr_sc->sc_dma_setup = se_dma_setup;
	ncr_sc->sc_dma_start = se_dma_start;
	ncr_sc->sc_dma_poll  = se_dma_poll;
	ncr_sc->sc_dma_eop   = se_dma_eop;
	ncr_sc->sc_dma_stop  = se_dma_stop;
	ncr_sc->sc_intr_on   = se_intr_on;
	ncr_sc->sc_intr_off  = se_intr_off;
#endif	/* XXX */

	/* Attach interrupt handler. */
	isr_add_vectored(se_intr, (void *)sc,
	    aa->ca.ca_intpri, aa->ca.ca_intvec);

	/* Reset the hardware. */
	se_reset(ncr_sc);

	/* Do the common attach stuff. */

	/*
	 * Support the "options" (config file flags).
	 * Disconnect/reselect is a per-target mask.
	 * Interrupts and DMA are per-controller.
	 */
	ncr_sc->sc_no_disconnect =
	    (sc->sc_options & SE_NO_DISCONNECT);
	ncr_sc->sc_parity_disable = 
	    (sc->sc_options & SE_NO_PARITY_CHK) >> 8;
	if (sc->sc_options & SE_FORCE_POLLING)
		ncr_sc->sc_flags |= NCR5380_FORCE_POLLING;

#if 1	/* XXX - Temporary */
	/* XXX - In case we think DMA is completely broken... */
	if (sc->sc_options & SE_DISABLE_DMA) {
		/* Override this function pointer. */
		ncr_sc->sc_dma_alloc = NULL;
	}
#endif
	ncr_sc->sc_min_dma_len = MIN_DMA_LEN;

	/*
	 * Initialize fields used by the MI code
	 */
	ncr_sc->sci_r0 = &regs->ncrregs[0];
	ncr_sc->sci_r1 = &regs->ncrregs[1];
	ncr_sc->sci_r2 = &regs->ncrregs[2];
	ncr_sc->sci_r3 = &regs->ncrregs[3];
	ncr_sc->sci_r4 = &regs->ncrregs[4];
	ncr_sc->sci_r5 = &regs->ncrregs[5];
	ncr_sc->sci_r6 = &regs->ncrregs[6];
	ncr_sc->sci_r7 = &regs->ncrregs[7];

	ncr_sc->sc_rev = NCR_VARIANT_NCR5380;

	/*
	 * Allocate DMA handles.
	 */
	i = SCI_OPENINGS * sizeof(struct se_dma_handle);
	sc->sc_dma = malloc(i, M_DEVBUF, M_WAITOK);
	if (sc->sc_dma == NULL)
		panic("se: dma_malloc failed");
	for (i = 0; i < SCI_OPENINGS; i++)
		sc->sc_dma[i].dh_flags = 0;

	ncr_sc->sc_channel.chan_id = 7;
	ncr_sc->sc_adapter.adapt_minphys = se_minphys;

	/*
	 *  Initialize se board itself.
	 */
	ncr5380_attach(ncr_sc);
}
Ejemplo n.º 5
0
void
csa_attach(device_t parent, device_t self, void *aux)
{
	struct csa_softc *sc = device_private(self);
	struct ncr5380_softc *ncr_sc = &sc->sc_ncr5380;
	struct podule_attach_args *pa = aux;
	uint8_t *iobase;
	char hi_option[sizeof(self->dv_xname) + 8];

	ncr_sc->sc_dev = self;

	/* Note the podule number and validate */

	if (pa->pa_podule_number == -1)
		panic("Podule has disappeared !");

	sc->sc_podule_number = pa->pa_podule_number;
	sc->sc_podule = pa->pa_podule;
	podules[sc->sc_podule_number].attached = 1;

	ncr_sc->sc_flags |= NCR5380_FORCE_POLLING;
	ncr_sc->sc_min_dma_len = 0;
	ncr_sc->sc_no_disconnect = 0x00;
	ncr_sc->sc_parity_disable = 0x00;

	ncr_sc->sc_dma_alloc = NULL;
	ncr_sc->sc_dma_free = NULL;
	ncr_sc->sc_dma_poll = NULL;
	ncr_sc->sc_dma_setup = NULL;
	ncr_sc->sc_dma_start = NULL;
	ncr_sc->sc_dma_eop = NULL;
	ncr_sc->sc_dma_stop = NULL;
	ncr_sc->sc_intr_on = NULL;
	ncr_sc->sc_intr_off = NULL;

	iobase = (uint8_t *)pa->pa_podule->slow_base + CSA_NCR5380_OFFSET;
	ncr_sc->sci_r0 = iobase + 0;
	ncr_sc->sci_r1 = iobase + 4;
	ncr_sc->sci_r2 = iobase + 8;
	ncr_sc->sci_r3 = iobase + 12;
	ncr_sc->sci_r4 = iobase + 16;
	ncr_sc->sci_r5 = iobase + 20;
	ncr_sc->sci_r6 = iobase + 24;
	ncr_sc->sci_r7 = iobase + 28;

	ncr_sc->sc_rev = NCR_VARIANT_NCR5380;

	sc->sc_ctrl = (uint8_t *)pa->pa_podule->slow_base + CSA_CTRL_OFFSET;
	sc->sc_status = (uint8_t *)pa->pa_podule->slow_base + CSA_STAT_OFFSET;
	sc->sc_data = (uint8_t *)pa->pa_podule->slow_base + CSA_DATA_OFFSET;

	ncr_sc->sc_pio_in = ncr5380_pio_in;
	ncr_sc->sc_pio_out = ncr5380_pio_out;

	/* Provide an override for the host id */
	ncr_sc->sc_channel.chan_id = 7;
	sprintf(hi_option, "%s.hostid", device_xname(self));
	(void)get_bootconf_option(boot_args, hi_option,
	    BOOTOPT_TYPE_INT, &ncr_sc->sc_channel.chan_id);
	ncr_sc->sc_adapter.adapt_minphys = minphys;

	aprint_normal(": host=%d, using 8 bit PIO",
	    ncr_sc->sc_channel.chan_id);

	sc->sc_irqstatus =
	    (uint8_t *)pa->pa_podule->slow_base + CSA_INTR_OFFSET;
	sc->sc_irqmask = CSA_INTR_MASK;

	evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
	    device_xname(self), "intr");
	sc->sc_ih = podulebus_irq_establish(pa->pa_ih, IPL_BIO, csa_intr, sc,
	    &sc->sc_intrcnt);
	if (sc->sc_ih == NULL)
		ncr_sc->sc_flags |= NCR5380_FORCE_POLLING;

	if (ncr_sc->sc_flags & NCR5380_FORCE_POLLING)
		aprint_normal(", polling");
	aprint_normal("\n");
	*sc->sc_ctrl = 0;

	ncr5380_attach(ncr_sc);
}
Ejemplo n.º 6
0
Archivo: oak.c Proyecto: MarginC/kame
void
oak_attach(struct device *parent, struct device *self, void *aux)
{
	struct oak_softc *sc = (struct oak_softc *)self;
	struct podulebus_attach_args *pa = aux;
#ifndef NCR5380_USE_BUS_SPACE
	u_char *iobase;
#endif
	char hi_option[sizeof(sc->sc_ncr5380.sc_dev.dv_xname) + 8];

	sc->sc_ncr5380.sc_flags |= NCR5380_FORCE_POLLING;
	sc->sc_ncr5380.sc_min_dma_len = 0;
	sc->sc_ncr5380.sc_no_disconnect = 0xff;
	sc->sc_ncr5380.sc_parity_disable = 0;

	sc->sc_ncr5380.sc_dma_alloc = NULL;
	sc->sc_ncr5380.sc_dma_free = NULL;
	sc->sc_ncr5380.sc_dma_poll = NULL;
	sc->sc_ncr5380.sc_dma_setup = NULL;
	sc->sc_ncr5380.sc_dma_start = NULL;
	sc->sc_ncr5380.sc_dma_eop = NULL;
	sc->sc_ncr5380.sc_dma_stop = NULL;
	sc->sc_ncr5380.sc_intr_on = NULL;
	sc->sc_ncr5380.sc_intr_off = NULL;

#ifdef NCR5380_USE_BUS_SPACE
	sc->sc_ncr5380.sc_regt = pa->pa_mod_t;
	bus_space_map(sc->sc_ncr5380.sc_regt, pa->pa_mod_base, 8, 0,
	    &sc->sc_ncr5380.sc_regh);
	sc->sc_ncr5380.sci_r0 = 0;
	sc->sc_ncr5380.sci_r1 = 1;
	sc->sc_ncr5380.sci_r2 = 2;
	sc->sc_ncr5380.sci_r3 = 3;
	sc->sc_ncr5380.sci_r4 = 4;
	sc->sc_ncr5380.sci_r5 = 5;
	sc->sc_ncr5380.sci_r6 = 6;
	sc->sc_ncr5380.sci_r7 = 7;
#else
	iobase = (u_char *)pa->pa_mod_base;
	sc->sc_ncr5380.sci_r0 = iobase + 0;
	sc->sc_ncr5380.sci_r1 = iobase + 4;
	sc->sc_ncr5380.sci_r2 = iobase + 8;
	sc->sc_ncr5380.sci_r3 = iobase + 12;
	sc->sc_ncr5380.sci_r4 = iobase + 16;
	sc->sc_ncr5380.sci_r5 = iobase + 20;
	sc->sc_ncr5380.sci_r6 = iobase + 24;
	sc->sc_ncr5380.sci_r7 = iobase + 28;
#endif
	sc->sc_pdmat = pa->pa_mod_t;
	bus_space_map(sc->sc_pdmat, pa->pa_mod_base + OAK_PDMA_OFFSET, 0x20, 0,
	    &sc->sc_pdmah);

	sc->sc_ncr5380.sc_rev = NCR_VARIANT_NCR5380;

	sc->sc_ncr5380.sc_pio_in = ncr5380_pio_in;
	sc->sc_ncr5380.sc_pio_out = ncr5380_pio_out;

	/* Provide an override for the host id */
	sc->sc_ncr5380.sc_channel.chan_id = 7;
	sprintf(hi_option, "%s.hostid", sc->sc_ncr5380.sc_dev.dv_xname);
	(void)get_bootconf_option(boot_args, hi_option,
	    BOOTOPT_TYPE_INT, &sc->sc_ncr5380.sc_channel.chan_id);
	sc->sc_ncr5380.sc_adapter.adapt_minphys = minphys;

	printf(": host=%d, using 8 bit PIO\n",
	    sc->sc_ncr5380.sc_channel.chan_id);

	ncr5380_attach(&sc->sc_ncr5380);
}
Ejemplo n.º 7
0
static void
sw_attach(device_t parent, device_t self, void *aux)
{
	struct sw_softc *sc = device_private(self);
	struct ncr5380_softc *ncr_sc = &sc->ncr_sc;
	union obio_attach_args *uoba = aux;
	struct obio4_attach_args *oba = &uoba->uoba_oba4;
	bus_space_handle_t bh;
	char bits[64];
	int i;

	ncr_sc->sc_dev = self;
	sc->sc_dmatag = oba->oba_dmatag;

	/* Map the controller registers. */
	if (bus_space_map(oba->oba_bustag, oba->oba_paddr,
			  SWREG_BANK_SZ,
			  BUS_SPACE_MAP_LINEAR,
			  &bh) != 0) {
		aprint_error(": cannot map registers\n");
		return;
	}

	ncr_sc->sc_regt = oba->oba_bustag;
	ncr_sc->sc_regh = bh;

	sc->sc_options = sw_options;

	ncr_sc->sc_dma_setup = sw_dma_setup;
	ncr_sc->sc_dma_start = sw_dma_start;
	ncr_sc->sc_dma_eop   = sw_dma_stop;
	ncr_sc->sc_dma_stop  = sw_dma_stop;
	ncr_sc->sc_intr_on   = sw_intr_on;
	ncr_sc->sc_intr_off  = sw_intr_off;

	/*
	 * Establish interrupt channel.
	 * Default interrupt priority always is 3.  At least, that's
	 * what my board seems to be at.  --thorpej
	 */
	if (oba->oba_pri == -1)
		oba->oba_pri = 3;

	(void)bus_intr_establish(oba->oba_bustag, oba->oba_pri, IPL_BIO,
				 sw_intr, sc);

	aprint_normal(" pri %d\n", oba->oba_pri);


	/*
	 * Pull in the options flags.  Allow the user to completely
	 * override the default values.
	 */
	if ((device_cfdata(self)->cf_flags & SW_OPTIONS_MASK) != 0)
		sc->sc_options =
		    device_cfdata(self)->cf_flags & SW_OPTIONS_MASK;

	/*
	 * Initialize fields used by the MI code
	 */

	/* NCR5380 register bank offsets */
	ncr_sc->sci_r0 = 0;
	ncr_sc->sci_r1 = 1;
	ncr_sc->sci_r2 = 2;
	ncr_sc->sci_r3 = 3;
	ncr_sc->sci_r4 = 4;
	ncr_sc->sci_r5 = 5;
	ncr_sc->sci_r6 = 6;
	ncr_sc->sci_r7 = 7;

	ncr_sc->sc_rev = NCR_VARIANT_NCR5380;

	/*
	 * MD function pointers used by the MI code.
	 */
	ncr_sc->sc_pio_out = ncr5380_pio_out;
	ncr_sc->sc_pio_in =  ncr5380_pio_in;
	ncr_sc->sc_dma_alloc = sw_dma_alloc;
	ncr_sc->sc_dma_free  = sw_dma_free;
	ncr_sc->sc_dma_poll  = sw_dma_poll;

	ncr_sc->sc_flags = 0;
	if ((sc->sc_options & SW_DO_RESELECT) == 0)
		ncr_sc->sc_no_disconnect = 0xFF;
	if ((sc->sc_options & SW_DMA_INTR) == 0)
		ncr_sc->sc_flags |= NCR5380_FORCE_POLLING;
	ncr_sc->sc_min_dma_len = MIN_DMA_LEN;


	/*
	 * Allocate DMA handles.
	 */
	i = SCI_OPENINGS * sizeof(struct sw_dma_handle);
	sc->sc_dma = (struct sw_dma_handle *)malloc(i, M_DEVBUF, M_NOWAIT);
	if (sc->sc_dma == NULL)
		panic("sw: DMA handle malloc failed");

	for (i = 0; i < SCI_OPENINGS; i++) {
		sc->sc_dma[i].dh_flags = 0;

		/* Allocate a DMA handle */
		if (bus_dmamap_create(
				sc->sc_dmatag,	/* tag */
				MAXPHYS,	/* size */
				1,		/* nsegments */
				MAXPHYS,	/* maxsegsz */
				0,		/* boundary */
				BUS_DMA_NOWAIT,
				&sc->sc_dma[i].dh_dmamap) != 0) {

			aprint_error_dev(self, "DMA buffer map create error\n");
			return;
		}
	}

	if (sc->sc_options) {
		aprint_normal_dev(self, "options=%s\n",
		    bitmask_snprintf(sc->sc_options, SW_OPTIONS_BITS,
		    bits, sizeof(bits)));
	}

	ncr_sc->sc_channel.chan_id = 7;
	ncr_sc->sc_adapter.adapt_minphys = sw_minphys;

	/* Initialize sw board */
	sw_reset_adapter(ncr_sc);

	/* Attach the ncr5380 chip driver */
	ncr5380_attach(ncr_sc);
}