Beispiel #1
0
int
we_config(device_t self, struct we_softc *wsc, const char *typestr)
{
	struct dp8390_softc *sc = &wsc->sc_dp8390;
	u_int8_t x;
	int i, forced_16bit = 0;

	/*
	 * Allow user to override 16-bit mode.  8-bit takes precedence.
	 */
	if (device_cfdata(self)->cf_flags & DP8390_FORCE_16BIT_MODE) {
		wsc->sc_flags |= WE_16BIT_ENABLE;
		forced_16bit = 1;
	}
	if (device_cfdata(self)->cf_flags & DP8390_FORCE_8BIT_MODE)
		wsc->sc_flags &= ~WE_16BIT_ENABLE;

	/* Registers are linear. */
	for (i = 0; i < 16; i++)
		sc->sc_reg_map[i] = i;

	/* Now we can use the NIC_{GET,PUT}() macros. */

	aprint_normal_dev(self, "%s Ethernet (%s-bit)\n",
	    typestr, wsc->sc_flags & WE_16BIT_ENABLE ? "16" : "8");

	/* Get station address from EEPROM. */
	for (i = 0; i < ETHER_ADDR_LEN; i++)
		sc->sc_enaddr[i] = bus_space_read_1(wsc->sc_asict,
					wsc->sc_asich, WE_PROM + i);

	/*
	 * Set upper address bits and 8/16 bit access to shared memory.
	 */
	if (sc->is790) {
		wsc->sc_laar_proto =
		    bus_space_read_1(wsc->sc_asict, wsc->sc_asich, WE_LAAR) &
		    ~WE_LAAR_M16EN;
		bus_space_write_1(wsc->sc_asict, wsc->sc_asich, WE_LAAR,
		    wsc->sc_laar_proto | (wsc->sc_flags & WE_16BIT_ENABLE ? WE_LAAR_M16EN : 0));
	} else if ((wsc->sc_type & WE_SOFTCONFIG) ||
#ifdef TOSH_ETHER
	    (wsc->sc_type == WE_TYPE_TOSHIBA1) ||
	    (wsc->sc_type == WE_TYPE_TOSHIBA4) ||
#endif
	    (forced_16bit) ||
	    (wsc->sc_type == WE_TYPE_WD8013EBT)) {
		wsc->sc_laar_proto = (wsc->sc_maddr >> 19) & WE_LAAR_ADDRHI;
		if (wsc->sc_flags & WE_16BIT_ENABLE)
			wsc->sc_laar_proto |= WE_LAAR_L16EN;
		bus_space_write_1(wsc->sc_asict, wsc->sc_asich, WE_LAAR,
		    wsc->sc_laar_proto | (wsc->sc_flags & WE_16BIT_ENABLE ? WE_LAAR_M16EN : 0));
	}
void
vrisabattach(device_t parent, device_t self, void *aux)
{
	struct hpcio_attach_args *haa = aux;
	struct vrisab_softc *sc = device_private(self);
	struct isabus_attach_args iba;
	struct bus_space_tag_hpcmips *iot, *memt;
	bus_addr_t offset;
	int i;
    
	sc->sc_hc = (*haa->haa_getchip)(haa->haa_sc, VRIP_IOCHIP_VRGIU);
	sc->sc_isa_ic.ic_sc = sc;

	iba.iba_ic	= &sc->sc_isa_ic;
	iba.iba_dmat    = 0; /* XXX not yet */

	/* Allocate ISA memory space */
	memt = hpcmips_alloc_bus_space_tag();
	offset = device_cfdata(self)->cf_loc[VRISABIFCF_ISAMEMOFFSET];
	hpcmips_init_bus_space(memt,
	    (struct bus_space_tag_hpcmips *)haa->haa_iot, "ISA mem",
	    VR_ISA_MEM_BASE + offset, VR_ISA_MEM_SIZE - offset);
	iba.iba_memt = &memt->bst;

	/* Allocate ISA port space */
	iot = hpcmips_alloc_bus_space_tag();
	offset = device_cfdata(self)->cf_loc[VRISABIFCF_ISAPORTOFFSET];
	hpcmips_init_bus_space(iot,
	    (struct bus_space_tag_hpcmips *)haa->haa_iot, "ISA port",
	    VR_ISA_PORT_BASE + offset, VR_ISA_PORT_SIZE - offset);
	iba.iba_iot = &iot->bst;

#ifdef DEBUG_FIND_PCIC
#warning DEBUG_FIND_PCIC
	__find_pcic();
#else
	/* Initialize ISA IRQ <-> GPIO mapping */
	for (i = 0; i < INTR_NIRQS; i++)
		sc->sc_intr_map[i] = -1;
	printf(": ISA port %#x-%#x mem %#x-%#x\n",
	    iot->base, iot->base + iot->size,
	    memt->base, memt->base + memt->size);
	config_found_ia(self, "isabus", &iba, vrisabprint);
#endif

#ifdef DEBUG_FIND_COMPORT
#warning DEBUG_FIND_COMPORT
	__find_comport();
#endif
}
Beispiel #3
0
static void
aedattach(device_t parent, device_t self, void *aux)
{
	struct adb_attach_args *aa_args = (struct adb_attach_args *)aux;
	struct aed_softc *sc = device_private(self);

	callout_init(&sc->sc_repeat_ch, 0);
	selinit(&sc->sc_selinfo);

	sc->origaddr = aa_args->origaddr;
	sc->adbaddr = aa_args->adbaddr;
	sc->handler_id = aa_args->handler_id;

	sc->sc_evq_tail = 0;
	sc->sc_evq_len = 0;

	sc->sc_rptdelay = 20;
	sc->sc_rptinterval = 6;
	sc->sc_repeating = -1;          /* not repeating */

	/* Pull in the options flags. */ 
	sc->sc_options = (device_cfdata(self)->cf_flags | aed_options);

	sc->sc_ioproc = NULL;
	
	sc->sc_buttons = 0;

	sc->sc_open = 0;

	aed_sc = sc;

	printf("ADB Event device\n");

	return;
}
Beispiel #4
0
int
booted_sd(device_t dev, void *aux)
{
	struct scsipibus_attach_args *sa = aux;
	device_t ppdev;

	/* Is this a SCSI device? */
	if (jmfr("sd", dev, BDEV_SD) && jmfr("sd", dev, BDEV_SDN) &&
	    jmfr("cd", dev, BDEV_SD) && jmfr("cd", dev, BDEV_SDN))
		return 0;

	if (sa->sa_periph->periph_channel->chan_bustype->bustype_type !=
	    SCSIPI_BUSTYPE_SCSI)
		return 0; /* ``Cannot happen'' */

	if (sa->sa_periph->periph_target != (rpb.unit/100) ||
	    sa->sa_periph->periph_lun != (rpb.unit % 100))
		return 0; /* Wrong unit */

	ppdev = device_parent(device_parent(dev));

	/* VS3100 NCR 53C80 (si) & VS4000 NCR 53C94 (asc) */
	if ((jmfr("si",  ppdev, BDEV_SD) == 0 ||	/* new name */
	     jmfr("asc", ppdev, BDEV_SD) == 0 ||
	     jmfr("asc", ppdev, BDEV_SDN) == 0) &&
	    (device_cfdata(ppdev)->cf_loc[VSBUSCF_CSR] == rpb.csrphy))
			return 1;

	return 0; /* Where did we come from??? */
}
Beispiel #5
0
static void
wdc_pnpbus_attach(device_t parent, device_t self, void *aux)
{
	struct wdc_pnpbus_softc *sc = device_private(self);
	struct wdc_regs *wdr;
	struct pnpbus_dev_attach_args *pna = aux;
	int cmd_iobase, cmd_len, aux_iobase, aux_len, i;

	sc->sc_wdcdev.sc_atac.atac_dev = self;
	sc->sc_wdcdev.regs = wdr = &sc->sc_wdc_regs;

	wdr->cmd_iot = pna->pna_iot;
	wdr->ctl_iot = pna->pna_iot;
	pnpbus_getioport(&pna->pna_res, 0, &cmd_iobase, &cmd_len);
	pnpbus_getioport(&pna->pna_res, 1, &aux_iobase, &aux_len);

	if (pnpbus_io_map(&pna->pna_res, 0, &wdr->cmd_iot, &wdr->cmd_baseioh) ||
	    pnpbus_io_map(&pna->pna_res, 1, &wdr->ctl_iot, &wdr->ctl_ioh)) {
		aprint_error_dev(self, "couldn't map registers\n");
	}

	for (i = 0; i < cmd_len; i++) {
		if (bus_space_subregion(wdr->cmd_iot,
		      wdr->cmd_baseioh, i, i == 0 ? 4 : 1,
		      &wdr->cmd_iohs[i]) != 0) {
			aprint_error(": couldn't subregion registers\n");
			return;
		}
	}

	wdr->data32iot = wdr->cmd_iot;
	wdr->data32ioh = wdr->cmd_iohs[0];

	sc->sc_wdcdev.cap |= WDC_CAPABILITY_PREATA;
	sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA16;
	if (device_cfdata(sc->sc_wdcdev.sc_atac.atac_dev)->cf_flags &
	    WDC_OPTIONS_32)
		sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA32;

	sc->sc_wdcdev.sc_atac.atac_pio_cap = 0;
	sc->sc_chanlist[0] = &sc->sc_channel;
	sc->sc_wdcdev.sc_atac.atac_channels = sc->sc_chanlist;
	sc->sc_wdcdev.sc_atac.atac_nchannels = 1;
	sc->sc_channel.ch_channel = 0;
	sc->sc_channel.ch_atac = &sc->sc_wdcdev.sc_atac;
	sc->sc_channel.ch_queue = &sc->sc_chqueue;
	sc->sc_channel.ch_ndrive = 2;
	wdc_init_shadow_regs(&sc->sc_channel);

	sc->sc_ih = pnpbus_intr_establish(0, IPL_BIO, IST_PNP,
	    wdcintr, &sc->sc_channel, &pna->pna_res);

	aprint_normal("\n");
	wdcattach(&sc->sc_channel);
}
Beispiel #6
0
void
wsmouse_attach(device_t parent, device_t self, void *aux)
{
        struct wsmouse_softc *sc = device_private(self);
	struct wsmousedev_attach_args *ap = aux;
#if NWSMUX > 0
	int mux, error;
#endif

	sc->sc_base.me_dv = self;
	sc->sc_accessops = ap->accessops;
	sc->sc_accesscookie = ap->accesscookie;

	/* Initialize button repeating. */
	memset(&sc->sc_repeat, 0, sizeof(sc->sc_repeat));
	sc->sc_repeat_button = -1;
	sc->sc_repeat_delay = 0;
	callout_init(&sc->sc_repeat_callout, 0);
	callout_setfunc(&sc->sc_repeat_callout, wsmouse_repeat, sc);

#if NWSMUX > 0
	sc->sc_base.me_ops = &wsmouse_srcops;
	mux = device_cfdata(self)->wsmousedevcf_mux;
	if (mux >= 0) {
		error = wsmux_attach_sc(wsmux_getmux(mux), &sc->sc_base);
		if (error)
			aprint_error(" attach error=%d", error);
		else
			aprint_normal(" mux %d", mux);
	}
#else
	if (device_cfdata(self)->wsmousedevcf_mux >= 0)
		aprint_normal(" (mux ignored)");
#endif

	aprint_naive("\n");
	aprint_normal("\n");

	if (!pmf_device_register(self, NULL, NULL))
		aprint_error_dev(self, "couldn't establish power handler\n");
}
Beispiel #7
0
int
tap_clone_destroyer(device_t dev)
{
	cfdata_t cf = device_cfdata(dev);
	int error;

	if ((error = config_detach(dev, 0)) != 0)
		aprint_error_dev(dev, "unable to detach instance\n");
	free(cf, M_DEVBUF);

	return (error);
}
Beispiel #8
0
/*
 * Feature negotiation.
 */
uint32_t
virtio_negotiate_features(struct virtio_softc *sc, uint32_t guest_features)
{
	uint32_t r;

	if (!(device_cfdata(sc->sc_dev)->cf_flags & 1) &&
	    !(device_cfdata(sc->sc_child)->cf_flags & 1)) /* XXX */
		guest_features |= VIRTIO_F_RING_INDIRECT_DESC;
	r = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
			     VIRTIO_CONFIG_DEVICE_FEATURES);
	r &= guest_features;
	bus_space_write_4(sc->sc_iot, sc->sc_ioh,
			  VIRTIO_CONFIG_GUEST_FEATURES, r);
	sc->sc_features = r;
	if (r & VIRTIO_F_RING_INDIRECT_DESC)
		sc->sc_indirect = true;
	else
		sc->sc_indirect = false;

	return r;
}
Beispiel #9
0
static void 
bwtwoattach_any(device_t parent, device_t self, void *aux)
{
	struct bwtwosun2_softc *scsun2 = device_private(self);
	struct bwtwo_softc *sc = &scsun2->sc;
	struct mainbus_attach_args *ma = aux;
	struct fbdevice *fb = &sc->sc_fb;
	bus_space_handle_t bh;
	int isconsole;
	const char *name;

	sc->sc_dev = self;

	/* Remember cookies for bwtwo_mmap() */
	sc->sc_bustag = ma->ma_bustag;
	sc->sc_paddr = ma->ma_paddr;

	fb->fb_flags = device_cfdata(self)->cf_flags;
	fb->fb_type.fb_depth = 1;
	fb_setsize_eeprom(fb, fb->fb_type.fb_depth, 1152, 900);

	isconsole = fb_is_console(0);

	/* A plain bwtwo */
	sc->sc_reg = NULL;
	fb->fb_pfour = NULL;
	name = "bwtwo";
	sc->sc_pixeloffset = BWREG_MEM;
	sc->sc_get_video = bwtwo_get_video_sun2;
	sc->sc_set_video = bwtwo_set_video_sun2;

	/* Map the registers. */
	if (bus_space_map(ma->ma_bustag, ma->ma_paddr + BWREG_REG,
			  sizeof(struct bwtworeg), 0, &scsun2->bh)) {
		printf("%s: cannot map regs\n", device_xname(self));
		return;
	}

	if (isconsole) {
		int ramsize = fb->fb_type.fb_height * fb->fb_linebytes;
		if (bus_space_map(ma->ma_bustag,
				  ma->ma_paddr + sc->sc_pixeloffset,
				  ramsize,
				  BUS_SPACE_MAP_LINEAR, &bh) != 0) {
			printf("%s: cannot map pixels\n", device_xname(self));
			return;
		}
		sc->sc_fb.fb_pixels = (char *)bh;
	}

	bwtwoattach(sc, name, isconsole);
}
Beispiel #10
0
static int
cgd_destroy(device_t dev)
{
	int error;
	cfdata_t cf;

	cf = device_cfdata(dev);
	error = config_detach(dev, DETACH_QUIET);
	if (error)
		return error;
	free(cf, M_DEVBUF);
	return 0;
}
Beispiel #11
0
/*
 * downgrade the transfer mode of a drive after an error. return 1 if
 * downgrade was possible, 0 otherwise.
 *
 * MUST BE CALLED AT splbio()!
 */
int
ata_downgrade_mode(struct ata_drive_datas *drvp, int flags)
{
	struct ata_channel *chp = drvp->chnl_softc;
	struct atac_softc *atac = chp->ch_atac;
	device_t drv_dev = drvp->drv_softc;
	int cf_flags = device_cfdata(drv_dev)->cf_flags;

	/* if drive or controller don't know its mode, we can't do much */
	if ((drvp->drive_flags & ATA_DRIVE_MODE) == 0 ||
	    (atac->atac_set_modes == NULL))
		return 0;
	/* current drive mode was set by a config flag, let it this way */
	if ((cf_flags & ATA_CONFIG_PIO_SET) ||
	    (cf_flags & ATA_CONFIG_DMA_SET) ||
	    (cf_flags & ATA_CONFIG_UDMA_SET))
		return 0;

#if NATA_UDMA
	/*
	 * If we were using Ultra-DMA mode, downgrade to the next lower mode.
	 */
	if ((drvp->drive_flags & ATA_DRIVE_UDMA) && drvp->UDMA_mode >= 2) {
		drvp->UDMA_mode--;
		aprint_error_dev(drv_dev,
		    "transfer error, downgrading to Ultra-DMA mode %d\n",
		    drvp->UDMA_mode);
	}
#endif

	/*
	 * If we were using ultra-DMA, don't downgrade to multiword DMA.
	 */
	else if (drvp->drive_flags & (ATA_DRIVE_DMA | ATA_DRIVE_UDMA)) {
		drvp->drive_flags &= ~(ATA_DRIVE_DMA | ATA_DRIVE_UDMA);
		drvp->PIO_mode = drvp->PIO_cap;
		aprint_error_dev(drv_dev,
		    "transfer error, downgrading to PIO mode %d\n",
		    drvp->PIO_mode);
	} else /* already using PIO, can't downgrade */
		return 0;

	(*atac->atac_set_modes)(chp);
	ata_print_modes(chp);
	/* reset the channel, which will schedule all drives for setup */
	ata_reset_channel(chp, flags | AT_RST_NOCMD);
	return 1;
}
static void
via_vt6421_mapreg_dma(struct pciide_softc *sc, const struct pci_attach_args *pa)
{
	struct pciide_channel *pc;
	int chan, reg;
	bus_size_t size;

	sc->sc_dma_ok = (pci_mapreg_map(pa, PCIIDE_REG_BUS_MASTER_DMA,
	    PCI_MAPREG_TYPE_IO, 0, &sc->sc_dma_iot, &sc->sc_dma_ioh,
	    NULL, &sc->sc_dma_ios) == 0);
	sc->sc_dmat = pa->pa_dmat;
	if (sc->sc_dma_ok == 0) {
		aprint_verbose(", but unused (couldn't map registers)");
	} else {
		sc->sc_wdcdev.dma_arg = sc;
		sc->sc_wdcdev.dma_init = pciide_dma_init;
		sc->sc_wdcdev.dma_start = pciide_dma_start;
		sc->sc_wdcdev.dma_finish = pciide_dma_finish;
	}

	if (device_cfdata(sc->sc_wdcdev.sc_atac.atac_dev)->cf_flags &
	    PCIIDE_OPTIONS_NODMA) {
		aprint_verbose(
		    ", but unused (forced off by config file)");
		sc->sc_dma_ok = 0;
	}

	if (sc->sc_dma_ok == 0)
		return;

	for (chan = 0; chan < 4; chan++) {
		pc = &sc->pciide_channels[chan];
		for (reg = 0; reg < IDEDMA_NREGS; reg++) {
			size = 4;
			if (size > (IDEDMA_SCH_OFFSET - reg))
				size = IDEDMA_SCH_OFFSET - reg;
			if (bus_space_subregion(sc->sc_dma_iot, sc->sc_dma_ioh,
			    IDEDMA_SCH_OFFSET * chan + reg, size,
			    &pc->dma_iohs[reg]) != 0) {
				sc->sc_dma_ok = 0;
				aprint_verbose(", but can't subregion offset "
				               "%d size %lu",
					       reg, (u_long)size);
				return;
			}
		}
	}
}
static void
awin_com_attach(device_t parent, device_t self, void *aux)
{
	cfdata_t cf = device_cfdata(self);
	struct awin_com_softc * const asc = device_private(self);
	struct com_softc * const sc = &asc->asc_sc;
	struct awinio_attach_args * const aio = aux;
	const struct awin_locators * const loc = &aio->aio_loc;
	bus_space_tag_t iot = aio->aio_core_a4x_bst;
	const bus_addr_t iobase = AWIN_CORE_PBASE + loc->loc_offset;
	const struct awin_gpio_pinset *pinset;
	bus_space_handle_t ioh;

	if (awin_chip_id() == AWIN_CHIP_ID_A31) {
		pinset = awin_com_pinsets_a31;
	} else if (awin_chip_id() == AWIN_CHIP_ID_A80) {
		pinset = awin_com_pinsets_a80;
	} else {
		pinset = loc->loc_port + ((cf->cf_flags & 1) ?
		    awin_com_alt_pinsets : awin_com_pinsets);
	}

	awin_com_ports |= __BIT(loc->loc_port);

	awin_gpio_pinset_acquire(pinset);

	sc->sc_dev = self;
	sc->sc_frequency = AWIN_UART_FREQ;
	sc->sc_type = COM_TYPE_NORMAL;

	if (com_is_console(iot, iobase, &ioh) == 0
	    && bus_space_subregion(iot, aio->aio_core_bsh,
		loc->loc_offset / 4, loc->loc_size, &ioh)) {
		panic(": can't map registers");
	}
	COM_INIT_REGS(sc->sc_regs, iot, ioh, iobase);

	com_attach_subr(sc);
	aprint_naive("\n");

	KASSERT(loc->loc_intr != AWINIO_INTR_DEFAULT);
	asc->asc_ih = intr_establish(loc->loc_intr, IPL_SERIAL,
	    IST_EDGE | IST_MPSAFE, comintr, sc);
	if (asc->asc_ih == NULL)
		panic("%s: failed to establish interrupt %d",
		    device_xname(self), loc->loc_intr);
}
Beispiel #14
0
int
fss_close(dev_t dev, int flags, int mode, struct lwp *l)
{
	int mflag, error;
	cfdata_t cf;
	struct fss_softc *sc = device_lookup_private(&fss_cd, minor(dev));

	mflag = (mode == S_IFCHR ? FSS_CDEV_OPEN : FSS_BDEV_OPEN);
	error = 0;

	mutex_enter(&fss_device_lock);
restart:
	mutex_enter(&sc->sc_slock);
	if ((sc->sc_flags & (FSS_CDEV_OPEN|FSS_BDEV_OPEN)) != mflag) {
		sc->sc_flags &= ~mflag;
		mutex_exit(&sc->sc_slock);
		mutex_exit(&fss_device_lock);
		return 0;
	}
	if ((sc->sc_flags & FSS_ACTIVE) != 0 &&
	    (sc->sc_uflags & FSS_UNCONFIG_ON_CLOSE) != 0) {
		sc->sc_uflags &= ~FSS_UNCONFIG_ON_CLOSE;
		mutex_exit(&sc->sc_slock);
		error = fss_ioctl(dev, FSSIOCCLR, NULL, FWRITE, l);
		goto restart;
	}
	if ((sc->sc_flags & FSS_ACTIVE) != 0) {
		mutex_exit(&sc->sc_slock);
		mutex_exit(&fss_device_lock);
		return error;
	}

	KASSERT((sc->sc_flags & FSS_ACTIVE) == 0);
	KASSERT((sc->sc_flags & (FSS_CDEV_OPEN|FSS_BDEV_OPEN)) == mflag);
	mutex_exit(&sc->sc_slock);
	cf = device_cfdata(sc->sc_dev);
	error = config_detach(sc->sc_dev, DETACH_QUIET);
	if (! error)
		free(cf, M_DEVBUF);
	mutex_exit(&fss_device_lock);

	return error;
}
Beispiel #15
0
void
madattach(struct wss_softc *sc)
{
	struct ad1848_softc *ac;
	unsigned char cs4231_mode;
	int joy;

	ac = (struct ad1848_softc *)&sc->sc_ad1848;
	if (sc->mad_chip_type == MAD_NONE)
		return;

	/* Do we want the joystick disabled? */
	joy = device_cfdata(ac->sc_dev)->cf_flags & 2 ? MC1_JOYDISABLE : 0;

	/* enable WSS emulation at the I/O port */
	mad_write(sc, MC1_PORT, M_WSS_PORT_SELECT(sc->mad_ioindex) | joy);
	mad_write(sc, MC2_PORT, MC2_NO_CD_DRQ); /* disable CD */
	mad_write(sc, MC3_PORT, 0xf0); /* Disable SB */

	cs4231_mode =
		strncmp(ac->chip_name, "CS4248", 6) == 0 ||
		strncmp(ac->chip_name, "CS4231", 6) == 0 ? 0x02 : 0;

	if (sc->mad_chip_type == MAD_82C929) {
		mad_write(sc, MC4_PORT, 0x92);
		mad_write(sc, MC5_PORT, 0xA5 | cs4231_mode);
		mad_write(sc, MC6_PORT, 0x03);	/* Disable MPU401 */
	} else {
		mad_write(sc, MC4_PORT, 0x02);
		mad_write(sc, MC5_PORT, 0x30 | cs4231_mode);
	}

#ifdef AUDIO_DEBUG
	if (wssdebug) {
		int i;
		for (i = MC1_PORT; i <= MC7_PORT; i++)
			DPRINTF(("port %03x after init = %02x\n",
				 i, mad_read(sc, i)));
	}
#endif
}
Beispiel #16
0
static void
gtp_attach(device_t parent, device_t self, void *aux)
{
	struct gtp_softc *sc = device_private(self);
	struct pci_attach_args *pa = aux;
	cfdata_t cf = device_cfdata(self);
	pci_chipset_tag_t pc = pa->pa_pc;
	bus_size_t iosize;
	pcireg_t csr;

	pci_aprint_devinfo(pa, "Radio controller");

	/* Map I/O registers */
	if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0, &sc->tea.iot,
	    &sc->tea.ioh, NULL, &iosize)) {
		aprint_error(": can't map i/o space\n");
		return;
	}

	/* Enable the card */
	csr = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
	pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
	    csr | PCI_COMMAND_MASTER_ENABLE);

	sc->vol = 0;
	sc->mute = 0;
	sc->freq = MIN_FM_FREQ;
	sc->stereo = TEA5757_STEREO;
	sc->lock = TEA5757_S030;
	sc->tea.offset = 0;
	sc->tea.flags = cf->cf_flags;
	sc->tea.init = gtp_init;
	sc->tea.rset = gtp_rset;
	sc->tea.write_bit = gtp_write_bit;
	sc->tea.read = gtp_hardware_read;

	aprint_normal(": Gemtek PR103\n");

	radio_attach_mi(&gtp_hw_if, sc, self);
}
Beispiel #17
0
static void
xel_attach(device_t parent, device_t self, void *aux)
{
	struct xel_softc *sc = device_private(self);
	struct intio_attach_args *ia = aux;
	cfdata_t cf = device_cfdata(self);
	paddr_t addr;
	int r __diagused;

	addr = xel_addr(parent, cf, aux);
	sc->sc_bst = ia->ia_bst;
	ia->ia_addr = (int) addr;
	ia->ia_size = 0x4000;
	r = intio_map_allocate_region(parent, ia, INTIO_MAP_ALLOCATE);
#ifdef DIAGNOSTIC
	if (r)
		panic("IO map for Xellent30 corruption??");
#endif
	aprint_normal(": Xellent30 MPU Accelerator.\n");

	return;
}
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);
}
Beispiel #19
0
/*
 * Probe drive's capabilities, for use by the controller later
 * Assumes drvp points to an existing drive.
 */
void
ata_probe_caps(struct ata_drive_datas *drvp)
{
	struct ataparams params, params2;
	struct ata_channel *chp = drvp->chnl_softc;
	struct atac_softc *atac = chp->ch_atac;
	device_t drv_dev = drvp->drv_softc;
	int i, printed, s;
	const char *sep = "";
	int cf_flags;

	if (ata_get_params(drvp, AT_WAIT, &params) != CMD_OK) {
		/* IDENTIFY failed. Can't tell more about the device */
		return;
	}
	if ((atac->atac_cap & (ATAC_CAP_DATA16 | ATAC_CAP_DATA32)) ==
	    (ATAC_CAP_DATA16 | ATAC_CAP_DATA32)) {
		/*
		 * Controller claims 16 and 32 bit transfers.
		 * Re-do an IDENTIFY with 32-bit transfers,
		 * and compare results.
		 */
		s = splbio();
		drvp->drive_flags |= ATA_DRIVE_CAP32;
		splx(s);
		ata_get_params(drvp, AT_WAIT, &params2);
		if (memcmp(&params, &params2, sizeof(struct ataparams)) != 0) {
			/* Not good. fall back to 16bits */
			s = splbio();
			drvp->drive_flags &= ~ATA_DRIVE_CAP32;
			splx(s);
		} else {
			aprint_verbose_dev(drv_dev, "32-bit data port\n");
		}
	}
#if 0 /* Some ultra-DMA drives claims to only support ATA-3. sigh */
	if (params.atap_ata_major > 0x01 &&
	    params.atap_ata_major != 0xffff) {
		for (i = 14; i > 0; i--) {
			if (params.atap_ata_major & (1 << i)) {
				aprint_verbose_dev(drv_dev,
				    "ATA version %d\n", i);
				drvp->ata_vers = i;
				break;
			}
		}
	}
#endif

	/* An ATAPI device is at last PIO mode 3 */
	if (drvp->drive_type == ATA_DRIVET_ATAPI)
		drvp->PIO_mode = 3;

	/*
	 * It's not in the specs, but it seems that some drive
	 * returns 0xffff in atap_extensions when this field is invalid
	 */
	if (params.atap_extensions != 0xffff &&
	    (params.atap_extensions & WDC_EXT_MODES)) {
		printed = 0;
		/*
		 * XXX some drives report something wrong here (they claim to
		 * support PIO mode 8 !). As mode is coded on 3 bits in
		 * SET FEATURE, limit it to 7 (so limit i to 4).
		 * If higher mode than 7 is found, abort.
		 */
		for (i = 7; i >= 0; i--) {
			if ((params.atap_piomode_supp & (1 << i)) == 0)
				continue;
			if (i > 4)
				return;
			/*
			 * See if mode is accepted.
			 * If the controller can't set its PIO mode,
			 * assume the defaults are good, so don't try
			 * to set it
			 */
			if (atac->atac_set_modes)
				/*
				 * It's OK to pool here, it's fast enough
				 * to not bother waiting for interrupt
				 */
				if (ata_set_mode(drvp, 0x08 | (i + 3),
				   AT_WAIT) != CMD_OK)
					continue;
			if (!printed) {
				aprint_verbose_dev(drv_dev,
				    "drive supports PIO mode %d", i + 3);
				sep = ",";
				printed = 1;
			}
			/*
			 * If controller's driver can't set its PIO mode,
			 * get the highter one for the drive.
			 */
			if (atac->atac_set_modes == NULL ||
			    atac->atac_pio_cap >= i + 3) {
				drvp->PIO_mode = i + 3;
				drvp->PIO_cap = i + 3;
				break;
			}
		}
		if (!printed) {
			/*
			 * We didn't find a valid PIO mode.
			 * Assume the values returned for DMA are buggy too
			 */
			return;
		}
		s = splbio();
		drvp->drive_flags |= ATA_DRIVE_MODE;
		splx(s);
		printed = 0;
		for (i = 7; i >= 0; i--) {
			if ((params.atap_dmamode_supp & (1 << i)) == 0)
				continue;
#if NATA_DMA
			if ((atac->atac_cap & ATAC_CAP_DMA) &&
			    atac->atac_set_modes != NULL)
				if (ata_set_mode(drvp, 0x20 | i, AT_WAIT)
				    != CMD_OK)
					continue;
#endif
			if (!printed) {
				aprint_verbose("%s DMA mode %d", sep, i);
				sep = ",";
				printed = 1;
			}
#if NATA_DMA
			if (atac->atac_cap & ATAC_CAP_DMA) {
				if (atac->atac_set_modes != NULL &&
				    atac->atac_dma_cap < i)
					continue;
				drvp->DMA_mode = i;
				drvp->DMA_cap = i;
				s = splbio();
				drvp->drive_flags |= ATA_DRIVE_DMA;
				splx(s);
			}
#endif
			break;
		}
		if (params.atap_extensions & WDC_EXT_UDMA_MODES) {
			printed = 0;
			for (i = 7; i >= 0; i--) {
				if ((params.atap_udmamode_supp & (1 << i))
				    == 0)
					continue;
#if NATA_UDMA
				if (atac->atac_set_modes != NULL &&
				    (atac->atac_cap & ATAC_CAP_UDMA))
					if (ata_set_mode(drvp, 0x40 | i,
					    AT_WAIT) != CMD_OK)
						continue;
#endif
				if (!printed) {
					aprint_verbose("%s Ultra-DMA mode %d",
					    sep, i);
					if (i == 2)
						aprint_verbose(" (Ultra/33)");
					else if (i == 4)
						aprint_verbose(" (Ultra/66)");
					else if (i == 5)
						aprint_verbose(" (Ultra/100)");
					else if (i == 6)
						aprint_verbose(" (Ultra/133)");
					sep = ",";
					printed = 1;
				}
#if NATA_UDMA
				if (atac->atac_cap & ATAC_CAP_UDMA) {
					if (atac->atac_set_modes != NULL &&
					    atac->atac_udma_cap < i)
						continue;
					drvp->UDMA_mode = i;
					drvp->UDMA_cap = i;
					s = splbio();
					drvp->drive_flags |= ATA_DRIVE_UDMA;
					splx(s);
				}
#endif
				break;
			}
		}
		aprint_verbose("\n");
	}

	s = splbio();
	drvp->drive_flags &= ~ATA_DRIVE_NOSTREAM;
	if (drvp->drive_type == ATA_DRIVET_ATAPI) {
		if (atac->atac_cap & ATAC_CAP_ATAPI_NOSTREAM)
			drvp->drive_flags |= ATA_DRIVE_NOSTREAM;
	} else {
		if (atac->atac_cap & ATAC_CAP_ATA_NOSTREAM)
			drvp->drive_flags |= ATA_DRIVE_NOSTREAM;
	}
	splx(s);

	/* Try to guess ATA version here, if it didn't get reported */
	if (drvp->ata_vers == 0) {
#if NATA_UDMA
		if (drvp->drive_flags & ATA_DRIVE_UDMA)
			drvp->ata_vers = 4; /* should be at last ATA-4 */
		else
#endif
		if (drvp->PIO_cap > 2)
			drvp->ata_vers = 2; /* should be at last ATA-2 */
	}
	cf_flags = device_cfdata(drv_dev)->cf_flags;
	if (cf_flags & ATA_CONFIG_PIO_SET) {
		s = splbio();
		drvp->PIO_mode =
		    (cf_flags & ATA_CONFIG_PIO_MODES) >> ATA_CONFIG_PIO_OFF;
		drvp->drive_flags |= ATA_DRIVE_MODE;
		splx(s);
	}
Beispiel #20
0
/*
 * Attach a display.  We need to notice if it is the console, too.
 */
static void 
bw2attach(device_t parent, device_t self, void *args)
{
	struct bw2_softc *sc = device_private(self);
	struct fbdevice *fb = &sc->sc_fb;
	struct confargs *ca = args;
	struct fbtype *fbt;
	void *p4reg;
	int p4id, tmp;
	int pixeloffset;		/* offset to framebuffer */

	sc->sc_dev = self;

	fbt = &fb->fb_fbtype;
	fbt->fb_type = FBTYPE_SUN2BW;
	fbt->fb_width = 1152;	/* default - see below */
	fbt->fb_height = 900;	/* default - see below */
	fbt->fb_depth = 1;
	fbt->fb_cmsize = 0;
	fbt->fb_size = BW2_FBSIZE;	/* default - see below */
	fb->fb_driver = &bw2fbdriver;
	fb->fb_private = sc;
	fb->fb_name  = device_xname(self);
	fb->fb_flags = device_cfdata(self)->cf_flags;

	/* Set up default pixel offset.  May be changed below. */
	pixeloffset = 0;

	/* Does it have a P4 register? */
	p4reg = bus_mapin(ca->ca_bustype, ca->ca_paddr, 4);
	p4id = fb_pfour_id(p4reg);
	if (p4id != P4_NOTFOUND)
		fb->fb_pfour = p4reg;
	else
		bus_mapout(p4reg, 4);

	switch (p4id) {
	case P4_NOTFOUND:
		pixeloffset = 0;
		break;

	case P4_ID_BW:
		pixeloffset = P4_BW_OFF;
		break;

	default:
		aprint_error("%s: bad p4id=0x%x\n", fb->fb_name, p4id);
		/* Must be some kinda color... */
		/* FALLTHROUGH */
	case P4_ID_COLOR8P1:
	case P4_ID_COLOR24:
		sc->sc_ovtype = p4id;
		pixeloffset = P4_COLOR_OFF_OVERLAY;
		break;
	}
	sc->sc_phys = ca->ca_paddr + pixeloffset;

	/*
	 * Determine width and height as follows:
	 * If it has a P4 register, use that;
	 * else if unit==0, use the EEPROM size,
	 * else make our best guess.
	 */
	if (fb->fb_pfour)
		fb_pfour_setsize(fb);
	/* XXX device_unit() abuse */
	else if (device_unit(self) == 0)
		fb_eeprom_setsize(fb);
	else {
		/* Guess based on machine ID. */
		switch (cpu_machine_id) {
#ifdef	_SUN3_
		case ID_SUN3_60:
			/*
			 * Only the model 60 can have hi-res.
			 * Look at the "resolution" jumper.
			 */
			tmp = bus_peek(BUS_OBMEM, BW2_CR_PADDR, 1);
			if ((tmp != -1) && (tmp & 0x80) == 0)
				goto high_res;
			break;

		case ID_SUN3_260:
			/* The Sun3/260 is ALWAYS high-resolution! */
			/* fall through */
		high_res:
			fbt->fb_width = 1600;
			fbt->fb_height = 1280;
			fbt->fb_size = BW2_FBSIZE_HIRES;
			break;
#endif	/* SUN3 */

		default:
			/* Leave the defaults set above. */
			break;
		}
	}
	aprint_normal(" (%dx%d)\n", fbt->fb_width, fbt->fb_height);

	/* Make sure video is on. */
	tmp = 1;
	bw2svideo(fb, &tmp);

	/* Let /dev/fb know we are here. */
	fb_attach(fb, 1);
}
Beispiel #21
0
void
cpi_nubus_attach(device_t parent, device_t self, void *aux)
{
	struct cpi_softc *sc;
	struct nubus_attach_args *na;
	int err, ii;

	sc = device_private(self);
	sc->sc_options = (device_cfdata(self)->cf_flags & CPI_OPTIONS_MASK);

	na = aux;
	sc->sc_bst = na->na_tag;
	memcpy(&sc->sc_slot, na->fmt, sizeof(nubus_slot));
	sc->sc_basepa = (bus_addr_t)NUBUS_SLOT2PA(na->slot);

	/*
	 * The CIO sits eight bit wide on the top byte lane of
	 * Nubus, so map 16 byte.
	 */
	if (TRACE_CONFIG) {
		printf("\n");
		printf("\tcpi_nubus_attach() mapping 8536 CIO at 0x%lx.\n",
		    sc->sc_basepa + CIO_BASE_OFFSET);
	}

	err = bus_space_map(sc->sc_bst, sc->sc_basepa + CIO_BASE_OFFSET,
	    (Z8536_IOSIZE << 4), 0, &sc->sc_bsh);
	if (err) {
		aprint_normal(": failed to map memory space.\n");
		return;
	}
	
	sc->sc_lpstate = LP_INITIAL;
	sc->sc_intcount = 0;
	sc->sc_bytestoport = 0;

	if (TRACE_CONFIG)
		printf("\tcpi_nubus_attach() about to set up 8536 CIO.\n");

	for (ii = 0; ii < sizeof(cio_reset); ii += 2)
		z8536_reg_set(sc->sc_bst, sc->sc_bsh, cio_reset[ii],
		    cio_reset[ii + 1]);
	
	delay(1000);		/* Give the CIO time to set itself up */
	for (ii = 0; ii < sizeof(cio_init); ii += 2) {
		z8536_reg_set(sc->sc_bst, sc->sc_bsh, cio_init[ii],
		    cio_init[ii + 1]);
	}
	
	if (TRACE_CONFIG)
		printf("\tcpi_nubus_attach() done with 8536 CIO setup.\n");
		
	/* XXX Get information strings from the card ROM */
	aprint_normal(": CSI Hurdler II Centronics\n");

	/* Attach CIO timers 1+2 as timecounter */
	if (sc->sc_options & CPI_CTC12_IS_TIMECOUNTER) {
		cpi_tc_initclock(sc);
	}

	callout_init(&sc->sc_wakeupchan, 0);	/* XXX */
	
	/* make sure interrupts are vectored to us */
	add_nubus_intr(na->slot, cpi_nubus_intr, sc);
}
Beispiel #22
0
/*
 * Initialization of interface; reinitialize UNIBUS usage.
 */
int
dmcinit(struct ifnet *ifp)
{
	struct dmc_softc *sc = ifp->if_softc;
	struct ifrw *ifrw;
	struct ifxmt *ifxp;
	struct dmcbufs *rp;
	struct dmc_command *qp;
	struct ifaddr *ifa;
	cfdata_t ui = device_cfdata(sc->sc_dev);
	int base;
	int s;

	/*
	 * Check to see that an address has been set
	 * (both local and destination for an address family).
	 */
	IFADDR_FOREACH(ifa, ifp)
		if (ifa->ifa_addr->sa_family && ifa->ifa_dstaddr->sa_family)
			break;
	if (ifa == (struct ifaddr *) 0)
		return 0;

	if ((DMC_RBYTE(DMC_BSEL1) & DMC_RUN) == 0) {
		printf("dmcinit: DMC not running\n");
		ifp->if_flags &= ~IFF_UP;
		return 0;
	}
	/* map base table */
	if ((sc->sc_flag & DMC_BMAPPED) == 0) {
		sc->sc_ui.ui_size = sizeof(struct dmc_base);
		sc->sc_ui.ui_vaddr = (void *)&sc->dmc_base;
		uballoc(device_private(device_parent(sc->sc_dev)), &sc->sc_ui, 0);
		sc->sc_flag |= DMC_BMAPPED;
	}
	/* initialize UNIBUS resources */
	sc->sc_iused = sc->sc_oused = 0;
	if ((ifp->if_flags & IFF_RUNNING) == 0) {
		if (if_ubaminit(&sc->sc_ifuba,
		    device_private(device_parent(sc->sc_dev)),
		    sizeof(struct dmc_header) + DMCMTU,
		    sc->sc_ifr, NRCV, sc->sc_ifw, NXMT) == 0) {
			aprint_error_dev(sc->sc_dev, "can't allocate uba resources\n");
			ifp->if_flags &= ~IFF_UP;
			return 0;
		}
		ifp->if_flags |= IFF_RUNNING;
	}
	sc->sc_flag &= ~DMC_ONLINE;
	sc->sc_flag |= DMC_RUNNING;
	/*
	 * Limit packets enqueued until we see if we're on the air.
	 */
	ifp->if_snd.ifq_maxlen = 3;

	/* initialize buffer pool */
	/* receives */
	ifrw = &sc->sc_ifr[0];
	for (rp = &sc->sc_rbufs[0]; rp < &sc->sc_rbufs[NRCV]; rp++) {
		rp->ubinfo = ifrw->ifrw_info;
		rp->cc = DMCMTU + sizeof (struct dmc_header);
		rp->flags = DBUF_OURS|DBUF_RCV;
		ifrw++;
	}
	/* transmits */
	ifxp = &sc->sc_ifw[0];
	for (rp = &sc->sc_xbufs[0]; rp < &sc->sc_xbufs[NXMT]; rp++) {
		rp->ubinfo = ifxp->ifw_info;
		rp->cc = 0;
		rp->flags = DBUF_OURS|DBUF_XMIT;
		ifxp++;
	}

	/* set up command queues */
	sc->sc_qfreeh = sc->sc_qfreet
		 = sc->sc_qhead = sc->sc_qtail = sc->sc_qactive =
		(struct dmc_command *)0;
	/* set up free command buffer list */
	for (qp = &sc->sc_cmdbuf[0]; qp < &sc->sc_cmdbuf[NCMDS]; qp++) {
		QUEUE_AT_HEAD(qp, sc->sc_qfreeh, sc->sc_qfreet);
	}

	/* base in */
	base = sc->sc_ui.ui_baddr;
	dmcload(sc, DMC_BASEI, (u_short)base, (base>>2) & DMC_XMEM);
	/* specify half duplex operation, flags tell if primary */
	/* or secondary station */
	if (ui->cf_flags == 0)
		/* use DDCMP mode in full duplex */
		dmcload(sc, DMC_CNTLI, 0, 0);
	else if (ui->cf_flags == 1)
		/* use MAINTENENCE mode */
		dmcload(sc, DMC_CNTLI, 0, DMC_MAINT );
	else if (ui->cf_flags == 2)
		/* use DDCMP half duplex as primary station */
		dmcload(sc, DMC_CNTLI, 0, DMC_HDPLX);
	else if (ui->cf_flags == 3)
		/* use DDCMP half duplex as secondary station */
		dmcload(sc, DMC_CNTLI, 0, DMC_HDPLX | DMC_SEC);

	/* enable operation done interrupts */
	while ((DMC_RBYTE(DMC_BSEL2) & DMC_IEO) == 0)
		DMC_WBYTE(DMC_BSEL2, DMC_RBYTE(DMC_BSEL2) | DMC_IEO);
	s = splnet();
	/* queue first NRCV buffers for DMC to fill */
	for (rp = &sc->sc_rbufs[0]; rp < &sc->sc_rbufs[NRCV]; rp++) {
		rp->flags |= DBUF_DMCS;
		dmcload(sc, DMC_READ, rp->ubinfo,
			(((rp->ubinfo>>2)&DMC_XMEM) | rp->cc));
		sc->sc_iused++;
	}
	splx(s);
	return 0;
}
Beispiel #23
0
/*
 * Attach a display.  We need to notice if it is the console, too.
 */
static void
cgeightattach(struct device *parent, struct device *self, void *aux)
{
#if defined(SUN4)
	union obio_attach_args *uoba = aux;
	struct obio4_attach_args *oba = &uoba->uoba_oba4;
	struct cgeight_softc *sc = device_private(self);
	struct fbdevice *fb = &sc->sc_fb;
	bus_space_handle_t bh;
	volatile struct bt_regs *bt;
	int ramsize, i, isconsole;

	sc->sc_bustag = oba->oba_bustag;
	sc->sc_paddr = (bus_addr_t)oba->oba_paddr;

	/* Map the pfour register. */
	if (bus_space_map(oba->oba_bustag, oba->oba_paddr,
			  sizeof(uint32_t),
			  BUS_SPACE_MAP_LINEAR,
			  &bh) != 0) {
		printf("%s: cannot map pfour register\n", self->dv_xname);
		return;
	}
	fb->fb_pfour = (volatile uint32_t *)bh;

	fb->fb_driver = &cgeightfbdriver;
	fb->fb_device = &sc->sc_dev;
	fb->fb_type.fb_type = FBTYPE_MEMCOLOR;
	fb->fb_flags = device_cfdata(&sc->sc_dev)->cf_flags & FB_USERMASK;
	fb->fb_flags |= FB_PFOUR;

	ramsize = PFOUR_COLOR_OFF_END - PFOUR_COLOR_OFF_OVERLAY;

	fb->fb_type.fb_depth = 24;
	fb_setsize_eeprom(fb, fb->fb_type.fb_depth, 1152, 900);

	sc->sc_fb.fb_type.fb_cmsize = 256;
	sc->sc_fb.fb_type.fb_size = ramsize;
	printf(": cgeight/p4, %d x %d",
		fb->fb_type.fb_width,
		fb->fb_type.fb_height);

	isconsole = 0;

	if (CPU_ISSUN4) {
		struct eeprom *eep = (struct eeprom *)eeprom_va;

		/*
		 * Assume this is the console if there's no eeprom info
		 * to be found.
		 */
		if (eep == NULL || eep->eeConsole == EE_CONS_P4OPT)
			isconsole = fb_is_console(0);
	}

#if 0
	/*
	 * We don't do any of the console handling here.  Instead,
	 * we let the bwtwo driver pick up the overlay plane and
	 * use it instead.  Rconsole should have better performance
	 * with the 1-bit depth.
	 *      -- Jason R. Thorpe <*****@*****.**>
	 */

	/*
	 * When the ROM has mapped in a cgfour display, the address
	 * maps only the video RAM, so in any case we have to map the
	 * registers ourselves.  We only need the video RAM if we are
	 * going to print characters via rconsole.
	 */

	if (isconsole) {
		/* XXX this is kind of a waste */
		fb->fb_pixels = mapiodev(ca->ca_ra.ra_reg,
					 PFOUR_COLOR_OFF_OVERLAY, ramsize);
	}
#endif

	/* Map the Brooktree. */
	if (bus_space_map(oba->oba_bustag,
			  oba->oba_paddr + PFOUR_COLOR_OFF_CMAP,
			  sizeof(struct fbcontrol),
			  BUS_SPACE_MAP_LINEAR,
			  &bh) != 0) {
		printf("%s: cannot map control registers\n", self->dv_xname);
		return;
	}
	sc->sc_fbc = (volatile struct fbcontrol *)bh;

#if 0	/* XXX thorpej ??? */
	/* tell the enable plane to look at the mono image */
	memset(ca->ca_ra.ra_vaddr, 0xff,
	    sc->sc_fb.fb_type.fb_width * sc->sc_fb.fb_type.fb_height / 8);
#endif

	/* grab initial (current) color map */
	bt = &sc->sc_fbc->fbc_dac;
	bt->bt_addr = 0;
	for (i = 0; i < 256 * 3 / 4; i++)
		sc->sc_cmap.cm_chip[i] = bt->bt_cmap;

	BT_INIT(bt, 0);

#if 0	/* see above */
	if (isconsole) {
		printf(" (console)\n");
#if defined(RASTERCONSOLE) && 0	/* XXX been told it doesn't work well. */
		fbrcons_init(fb);
#endif
	} else
#endif /* 0 */
		printf("\n");

	/*
	 * Even though we're not using rconsole, we'd still like
	 * to notice if we're the console framebuffer.
	 */
	fb_attach(&sc->sc_fb, isconsole);
#endif
}
Beispiel #24
0
void
njata32_attach(struct njata32_softc *sc)
{
	bus_addr_t dmaaddr;
	int i, devno, error;
	struct wdc_regs *wdr;

	/*
	 * allocate DMA resource
	 */
	if ((error = bus_dmamem_alloc(sc->sc_dmat,
	    sizeof(struct njata32_dma_page), PAGE_SIZE, 0,
	    &sc->sc_sgt_seg, 1, &sc->sc_sgt_nsegs, BUS_DMA_NOWAIT)) != 0) {
		aprint_error("%s: unable to allocate sgt page, error = %d\n",
		    NJATA32NAME(sc), error);
		return;
	}
	if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_sgt_seg,
	    sc->sc_sgt_nsegs, sizeof(struct njata32_dma_page),
	    (void **)&sc->sc_sgtpg,
	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
		aprint_error("%s: unable to map sgt page, error = %d\n",
		    NJATA32NAME(sc), error);
		goto fail1;
	}
	if ((error = bus_dmamap_create(sc->sc_dmat,
	    sizeof(struct njata32_dma_page), 1,
	    sizeof(struct njata32_dma_page), 0, BUS_DMA_NOWAIT,
	    &sc->sc_dmamap_sgt)) != 0) {
		aprint_error("%s: unable to create sgt DMA map, error = %d\n",
		    NJATA32NAME(sc), error);
		goto fail2;
	}
	if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_sgt,
	    sc->sc_sgtpg, sizeof(struct njata32_dma_page),
	    NULL, BUS_DMA_NOWAIT)) != 0) {
		aprint_error("%s: unable to load sgt DMA map, error = %d\n",
		    NJATA32NAME(sc), error);
		goto fail3;
	}

	dmaaddr = sc->sc_dmamap_sgt->dm_segs[0].ds_addr;

	for (devno = 0; devno < NJATA32_NUM_DEV; devno++) {
		sc->sc_dev[devno].d_sgt = sc->sc_sgtpg->dp_sg[devno];
		sc->sc_dev[devno].d_sgt_dma = dmaaddr +
		    offsetof(struct njata32_dma_page, dp_sg[devno]);

		error = bus_dmamap_create(sc->sc_dmat,
		    NJATA32_MAX_XFER,		/* max total map size */
		    NJATA32_NUM_SG,		/* max number of segments */
		    NJATA32_SGT_MAXSEGLEN,	/* max size of a segment */
		    0,				/* boundary */
		    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
		    &sc->sc_dev[devno].d_dmamap_xfer);
		if (error) {
			aprint_error("%s: failed to create DMA map "
			    "(error = %d)\n", NJATA32NAME(sc), error);
			goto fail4;
		}
	}

	/* device properties */
	sc->sc_wdcdev.sc_atac.atac_cap =
	    ATAC_CAP_DATA16 | ATAC_CAP_DATA32 | ATAC_CAP_PIOBM;
	sc->sc_wdcdev.irqack = njata32_irqack;
	sc->sc_wdcdev.sc_atac.atac_channels = sc->sc_wdc_chanarray;
	sc->sc_wdcdev.sc_atac.atac_nchannels = NJATA32_NCHAN;	/* 1 */
	sc->sc_wdcdev.sc_atac.atac_pio_cap = NJATA32_MODE_MAX_PIO;
#if 0	/* ATA DMA is currently unused */
	sc->sc_wdcdev.sc_atac.atac_dma_cap = NJATA32_MODE_MAX_DMA;
#endif
	sc->sc_wdcdev.sc_atac.atac_set_modes = njata32_setup_channel;

	/* DMA control functions */
	sc->sc_wdcdev.dma_arg = sc;
	sc->sc_wdcdev.dma_init = njata32_dma_init;
	sc->sc_wdcdev.piobm_start = njata32_piobm_start;
	sc->sc_wdcdev.dma_finish = njata32_dma_finish;
	sc->sc_wdcdev.piobm_done = njata32_piobm_done;

	sc->sc_wdcdev.cap |= WDC_CAPABILITY_NO_EXTRA_RESETS;

	sc->sc_wdcdev.regs = wdr = &sc->sc_wdc_regs;

	/* only one channel */
	sc->sc_wdc_chanarray[0] = &sc->sc_ch[0].ch_ata_channel;
	sc->sc_ch[0].ch_ata_channel.ch_channel = 0;
	sc->sc_ch[0].ch_ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac;
	sc->sc_ch[0].ch_ata_channel.ch_queue = &sc->sc_wdc_chqueue;
	sc->sc_ch[0].ch_ata_channel.ch_ndrive = 2; /* max number of drives */

	/* map ATA registers */
	for (i = 0; i < WDC_NREG; i++) {
		if (bus_space_subregion(NJATA32_REGT(sc), NJATA32_REGH(sc),
		    NJATA32_OFFSET_WDCREGS + i,
		    i == wd_data ? 4 : 1, &wdr->cmd_iohs[i]) != 0) {
			aprint_error("%s: couldn't subregion cmd regs\n",
			    NJATA32NAME(sc));
			goto fail4;
		}
	}
	wdc_init_shadow_regs(&sc->sc_ch[0].ch_ata_channel);
	wdr->data32iot = NJATA32_REGT(sc);
	wdr->data32ioh = wdr->cmd_iohs[wd_data];

	/* map ATA ctl reg */
	wdr->ctl_iot = NJATA32_REGT(sc);
	if (bus_space_subregion(NJATA32_REGT(sc), NJATA32_REGH(sc),
	    NJATA32_REG_WD_ALTSTATUS, 1, &wdr->ctl_ioh) != 0) {
		aprint_error("%s: couldn't subregion ctl regs\n",
		    NJATA32NAME(sc));
		goto fail4;
	}

	sc->sc_flags |= NJATA32_CMDPG_MAPPED;

	/* use flags value as busmaster wait */
	if ((sc->sc_atawait =
	    (uint8_t)device_cfdata(sc->sc_wdcdev.sc_atac.atac_dev)->cf_flags))
		aprint_normal("%s: ATA wait = %#x\n",
		    NJATA32NAME(sc), sc->sc_atawait);

	njata32_init(sc, cold);

	wdcattach(&sc->sc_ch[0].ch_ata_channel);

	return;

	/*
	 * cleanup
	 */
fail4:	while (--devno >= 0) {
		bus_dmamap_destroy(sc->sc_dmat,
		    sc->sc_dev[devno].d_dmamap_xfer);
	}
	bus_dmamap_unload(sc->sc_dmat, sc->sc_dmamap_sgt);
fail3:	bus_dmamap_destroy(sc->sc_dmat, sc->sc_dmamap_sgt);
fail2:	bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_sgtpg,
	    sizeof(struct njata32_dma_page));
fail1:	bus_dmamem_free(sc->sc_dmat, &sc->sc_sgt_seg, sc->sc_sgt_nsegs);
}
/*
 * Attach the card
 */
static void
isic_isa_attach(device_t parent, device_t self, void *aux)
{
	struct isic_softc *sc = device_private(self);
	struct isa_attach_args *ia = aux;
	int flags = device_cfdata(self)->cf_flags;
	int ret = 0, iobase, iosize, maddr, msize;
	struct isic_attach_args args;

	if (ia->ia_nio > 0) {
		iobase = ia->ia_io[0].ir_addr;
		iosize = ia->ia_io[0].ir_size;
	} else {
		iobase = ISA_UNKNOWN_PORT;
		iosize = 0;
	}
	if (ia->ia_niomem > 0) {
		maddr = ia->ia_iomem[0].ir_addr;
		msize = ia->ia_iomem[0].ir_size;
	} else {
		maddr = ISA_UNKNOWN_IOMEM;
		msize = 0;
	}

	/* Setup parameters */
	sc->sc_dev = self;
	sc->sc_irq = ia->ia_irq[0].ir_irq;
	sc->sc_maddr = maddr;
	sc->sc_num_mappings = 0;
	sc->sc_maps = NULL;
	switch(flags)
	{
		case FLAG_TELES_S0_8:
		case FLAG_TELES_S0_16:
		case FLAG_TELES_S0_163:
		case FLAG_AVM_A1:
		case FLAG_USR_ISDN_TA_INT:
			setup_io_map(flags, ia->ia_iot, ia->ia_memt, iobase, maddr,
					&(sc->sc_num_mappings), NULL, NULL, NULL);
			MALLOC_MAPS(sc);
			setup_io_map(flags, ia->ia_iot, ia->ia_memt, iobase, maddr,
					&(sc->sc_num_mappings), &(sc->sc_maps[0]), NULL, NULL);
			break;

		default:
			/* No card type given, try to figure ... */

			/* setup MI attach args */
			memset(&args, 0, sizeof(args));
			args.ia_flags = flags;

			/* Probe cards */
			if (iobase == ISA_UNKNOWN_PORT) {
				ret = 0;
#ifdef ISICISA_TEL_S0_8
				/* only Teles S0/8 will work without IO */
				args.ia_flags = FLAG_TELES_S0_8;
				setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, iobase, maddr,
					&args.ia_num_mappings, &args.ia_maps[0], NULL, NULL);
				ret = isic_probe_s08(&args);
				if (ret)
					goto found;
				args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
#endif /* ISICISA_TEL_S0_8 */
			} else if (maddr == ISA_UNKNOWN_IOMEM) {
				/* no shared memory, only a 16.3 based card,
				   AVM A1, the usr sportster or an ITK would work */
				ret = 0;
#ifdef	ISICISA_TEL_S0_16_3
				args.ia_flags = FLAG_TELES_S0_163;
				setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, iobase, maddr,
					&args.ia_num_mappings, &args.ia_maps[0], NULL, NULL);
				ret = isic_probe_s0163(&args);
				if (ret)
					goto found;
				args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
#endif /* ISICISA_TEL_S0_16_3 */
#ifdef ISICISA_AVM_A1
				args.ia_flags = FLAG_AVM_A1;
				setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, iobase, maddr,
					&args.ia_num_mappings, &args.ia_maps[0], NULL, NULL);
				ret = isic_probe_avma1(&args);
 				if (ret)
 					goto found;
 				args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
#endif /* ISICISA_AVM_A1 */
#ifdef ISICISA_USR_STI
 				args.ia_flags = FLAG_USR_ISDN_TA_INT;
 				setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, iobase, maddr,
 					&args.ia_num_mappings, &args.ia_maps[0], NULL, NULL);
 				ret = isic_probe_usrtai(&args);
				if (ret)
					goto found;
				args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
#endif /* ISICISA_USR_STI */
#ifdef ISICISA_ITKIX1
 				args.ia_flags = FLAG_ITK_IX1;
 				setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, iobase, maddr,
 					&args.ia_num_mappings, &args.ia_maps[0], NULL, NULL);
 				ret = isic_probe_itkix1(&args);
				if (ret)
					goto found;
				args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
#endif /* ISICISA_ITKIX1 */
			} else {
				/* could be anything */
				ret = 0;
#ifdef	ISICISA_TEL_S0_16_3
				args.ia_flags = FLAG_TELES_S0_163;
				setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, iobase, maddr,
					&args.ia_num_mappings, &args.ia_maps[0], NULL, NULL);
				ret = isic_probe_s0163(&args);
				if (ret)
					goto found;
				args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
#endif	/* ISICISA_TEL_S0_16_3 */
#ifdef	ISICISA_TEL_S0_16
				args.ia_flags = FLAG_TELES_S0_16;
				setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, iobase, maddr,
					&args.ia_num_mappings, &args.ia_maps[0], NULL, NULL);
				ret = isic_probe_s016(&args);
				if (ret)
					goto found;
				args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
#endif /* ISICISA_TEL_S0_16 */
#ifdef ISICISA_AVM_A1
				args.ia_flags = FLAG_AVM_A1;
				setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, iobase, maddr,
					&args.ia_num_mappings, &args.ia_maps[0], NULL, NULL);
				ret = isic_probe_avma1(&args);
				if (ret)
					goto found;
				args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
#endif /* ISICISA_AVM_A1 */
#ifdef ISICISA_TEL_S0_8
				args.ia_flags = FLAG_TELES_S0_8;
				setup_io_map(args.ia_flags, ia->ia_iot, ia->ia_memt, iobase, maddr,
					&args.ia_num_mappings, &args.ia_maps[0], NULL, NULL);
				ret = isic_probe_s08(&args);
				if (ret)
					goto found;
				args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
#endif /* ISICISA_TEL_S0_8 */
			}
			break;

		found:
			flags = args.ia_flags;
			sc->sc_num_mappings = args.ia_num_mappings;
			args_unmap(&args.ia_num_mappings, &args.ia_maps[0]);
			if (ret) {
				MALLOC_MAPS(sc);
				setup_io_map(flags, ia->ia_iot, ia->ia_memt, iobase, maddr,
					&(sc->sc_num_mappings), &(sc->sc_maps[0]), NULL, NULL);
			} else {
				printf(": could not determine card type - not configured!\n");
				return;
			}
			break;
	}

	/* MI initialization of card */
	isicattach(flags, sc);

	/*
	 * Try to get a level-triggered interrupt first. If that doesn't
	 * work (like on NetBSD/Atari, try to establish an edge triggered
	 * interrupt.
	 */
	if (isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq, IST_LEVEL,
				IPL_NET, isicintr, sc) == NULL) {
		if(isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq, IST_EDGE,
				IPL_NET, isicintr, sc) == NULL) {
			args_unmap(&(sc->sc_num_mappings), &(sc->sc_maps[0]));
			free((sc)->sc_maps, M_DEVBUF);
		}
		else {
			/*
			 * XXX: This is a hack that probably needs to be
			 * solved by setting an interrupt type in the sc
			 * structure. I don't feel familiar enough with the
			 * code to do this currently. Feel free to contact
			 * me about it ([email protected]).
			 */
			isicintr(sc);
		}
	}
}
Beispiel #26
0
/*
 * XXX Ugly bit of code.  But, this is the only safe time that the
 * match between BIOS disks and native disks can be done.
 */
static void
matchbiosdisks(void)
{
	struct btinfo_biosgeom *big;
	struct bi_biosgeom_entry *be;
	device_t dv;
	deviter_t di;
	int i, ck, error, m, n;
	struct vnode *tv;
	char mbr[DEV_BSIZE];
	int dklist_size;
	int numbig;

	if (x86_ndisks)
		return;
	big = lookup_bootinfo(BTINFO_BIOSGEOM);

	numbig = big ? big->num : 0;

	/* First, count all native disks. */
	for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL;
	     dv = deviter_next(&di)) {
		if (is_valid_disk(dv))
			x86_ndisks++;
	}
	deviter_release(&di);

	dklist_size = sizeof(struct disklist) + (x86_ndisks - 1) *
	    sizeof(struct nativedisk_info);

	/* XXX M_TEMP is wrong */
	x86_alldisks = malloc(dklist_size, M_TEMP, M_NOWAIT | M_ZERO);
	if (x86_alldisks == NULL)
		return;

	x86_alldisks->dl_nnativedisks = x86_ndisks;
	x86_alldisks->dl_nbiosdisks = numbig;
	for (i = 0; i < numbig; i++) {
		x86_alldisks->dl_biosdisks[i].bi_dev = big->disk[i].dev;
		x86_alldisks->dl_biosdisks[i].bi_sec = big->disk[i].sec;
		x86_alldisks->dl_biosdisks[i].bi_head = big->disk[i].head;
		x86_alldisks->dl_biosdisks[i].bi_cyl = big->disk[i].cyl;
		x86_alldisks->dl_biosdisks[i].bi_lbasecs = big->disk[i].totsec;
		x86_alldisks->dl_biosdisks[i].bi_flags = big->disk[i].flags;
		DPRINTF(("%s: disk %x: flags %x",
		    __func__, big->disk[i].dev, big->disk[i].flags));
#ifdef BIOSDISK_EXTINFO_V3
		DPRINTF((", interface %x, device %llx",
		    big->disk[i].interface_path, big->disk[i].device_path));
#endif
		DPRINTF(("\n"));
	}

	/* XXX Code duplication from findroot(). */
	n = -1;
	for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST); dv != NULL;
	     dv = deviter_next(&di)) {
		if (!is_valid_disk(dv))
			continue;
		DPRINTF(("%s: trying to match (%s) %s: ", __func__,
		    device_xname(dv), device_cfdata(dv)->cf_name));
		n++;
		snprintf(x86_alldisks->dl_nativedisks[n].ni_devname,
		    sizeof(x86_alldisks->dl_nativedisks[n].ni_devname),
		    "%s", device_xname(dv));

		if ((tv = opendisk(dv)) == NULL) {
			DPRINTF(("cannot open\n"));
			continue;
		}

		error = vn_rdwr(UIO_READ, tv, mbr, DEV_BSIZE, 0, UIO_SYSSPACE,
		    0, NOCRED, NULL, NULL);
		VOP_CLOSE(tv, FREAD, NOCRED);
		vput(tv);
		if (error) {
			DPRINTF(("MBR read failure %d\n", error));
			continue;
		}

		for (ck = i = 0; i < DEV_BSIZE; i++)
			ck += mbr[i];
		for (m = i = 0; i < numbig; i++) {
			be = &big->disk[i];
			if (be->flags & BI_GEOM_INVALID)
				continue;
			DPRINTF(("matched with %d dev ck %x bios ck %x\n",
			    i, ck, be->cksum));
			if (be->cksum == ck && memcmp(&mbr[MBR_PART_OFFSET],
			    be->mbrparts, MBR_PART_COUNT
			    * sizeof(struct mbr_partition)) == 0) {
				DPRINTF(("%s: matched BIOS disk %x with %s\n",
				    __func__, be->dev, device_xname(dv)));
				x86_alldisks->dl_nativedisks[n].
				    ni_biosmatches[m++] = i;
			}
		}
		x86_alldisks->dl_nativedisks[n].ni_nmatches = m;
	}
	deviter_release(&di);
}
Beispiel #27
0
/*
 * Attempt to find the device from which we were booted.  If we can do so,
 * and not instructed not to do so, change rootdev to correspond to the
 * load device.
 */
static void
findroot(void)
{
	struct btinfo_rootdevice *biv;
	struct btinfo_bootdisk *bid;
	struct btinfo_bootwedge *biw;
	struct btinfo_biosgeom *big;
	device_t dv;
	deviter_t di;

	if (booted_device)
		return;
	
	if (lookup_bootinfo(BTINFO_NETIF) != NULL) {
		/*
		 * We got netboot interface information, but device_register()
		 * failed to match it to a configured device.  Boot disk
		 * information cannot be present at the same time, so give
		 * up.
		 */
		printf("%s: netboot interface not found.\n", __func__);
		return;
	}

	if ((biv = lookup_bootinfo(BTINFO_ROOTDEVICE)) != NULL) {
		for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST);
		     dv != NULL;
		     dv = deviter_next(&di)) {
			cfdata_t cd;
			size_t len;

			if (device_class(dv) != DV_DISK)
				continue;

			cd = device_cfdata(dv);
			len = strlen(cd->cf_name);

			if (strncmp(cd->cf_name, biv->devname, len) == 0 &&
			    biv->devname[len] - '0' == device_unit(dv)) {
				booted_device = dv;
				booted_partition = biv->devname[len + 1] - 'a';
				booted_nblks = 0;
				break;
			}
		}
		DPRINTF(("%s: BTINFO_ROOTDEVICE %s\n", __func__,
		    booted_device ? device_xname(booted_device) : "not found"));
		deviter_release(&di);
		if (dv != NULL)
			return;
	}

	bid = lookup_bootinfo(BTINFO_BOOTDISK);
	biw = lookup_bootinfo(BTINFO_BOOTWEDGE);

	if (biw != NULL) {
		/*
		 * Scan all disk devices for ones that match the passed data.
		 * Don't break if one is found, to get possible multiple
		 * matches - for problem tracking.  Use the first match anyway
		 * because lower devices numbers are more likely to be the
		 * boot device.
		 */
		for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST);
		     dv != NULL;
		     dv = deviter_next(&di)) {
			if (is_valid_disk(dv)) {
				/*
				 * Don't trust BIOS device numbers, try
				 * to match the information passed by the
				 * boot loader instead.
				 */
				if ((biw->biosdev & 0x80) == 0 ||
				    match_bootwedge(dv, biw) == 0)
				    	continue;
				goto bootwedge_found;
			}

			continue;
 bootwedge_found:
			if (booted_device) {
				dmatch(__func__, dv);
				continue;
			}
			booted_device = dv;
			booted_partition = bid != NULL ? bid->partition : 0;
			booted_nblks = biw->nblks;
			booted_startblk = biw->startblk;
		}
		deviter_release(&di);

		DPRINTF(("%s: BTINFO_BOOTWEDGE %s\n", __func__,
		    booted_device ? device_xname(booted_device) : "not found"));
		if (booted_nblks)
			return;
	}

	if (bid != NULL) {
		/*
		 * Scan all disk devices for ones that match the passed data.
		 * Don't break if one is found, to get possible multiple
		 * matches - for problem tracking.  Use the first match anyway
		 * because lower device numbers are more likely to be the
		 * boot device.
		 */
		for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST);
		     dv != NULL;
		     dv = deviter_next(&di)) {

			if (device_is_a(dv, "fd") &&
			    device_class(dv) == DV_DISK) {
				/*
				 * Assume the configured unit number matches
				 * the BIOS device number.  (This is the old
				 * behavior.)  Needs some ideas how to handle
				 * the BIOS's "swap floppy drive" options.
				 */
				/* XXX device_unit() abuse */
				if ((bid->biosdev & 0x80) != 0 ||
				    device_unit(dv) != bid->biosdev)
				    	continue;
				goto bootdisk_found;
			}

			if (is_valid_disk(dv)) {
				/*
				 * Don't trust BIOS device numbers, try
				 * to match the information passed by the
				 * boot loader instead.
				 */
				if ((bid->biosdev & 0x80) == 0 ||
				    match_bootdisk(dv, bid) == 0)
				    	continue;
				goto bootdisk_found;
			}

			continue;
 bootdisk_found:
			if (booted_device) {
				dmatch(__func__, dv);
				continue;
			}
			booted_device = dv;
			booted_partition = bid->partition;
			booted_nblks = 0;
		}
		deviter_release(&di);

		DPRINTF(("%s: BTINFO_BOOTDISK %s\n", __func__,
		    booted_device ? device_xname(booted_device) : "not found"));
		if (booted_device)
			return;

		/*
		 * No booted device found; check CD-ROM boot at last.
		 *
		 * Our bootloader assumes CD-ROM boot if biosdev is larger
		 * or equal than the number of hard drives recognized by the
		 * BIOS. The number of drives can be found in BTINFO_BIOSGEOM
		 * here. For example, if we have wd0, wd1, and cd0:
		 *
		 *	big->num = 2 (for wd0 and wd1)
		 *	bid->biosdev = 0x80 (wd0)
		 *	bid->biosdev = 0x81 (wd1)
		 *	bid->biosdev = 0x82 (cd0)
		 *
		 * See src/sys/arch/i386/stand/boot/devopen.c and
		 * src/sys/arch/i386/stand/lib/bootinfo_biosgeom.c .
		 */
		if ((big = lookup_bootinfo(BTINFO_BIOSGEOM)) != NULL &&
		    bid->biosdev >= 0x80 + big->num) {
			/*
			 * XXX
			 * There is no proper way to detect which unit is
			 * recognized as a bootable CD-ROM drive by the BIOS.
			 * Assume the first unit is the one.
			 */
			for (dv = deviter_first(&di, DEVITER_F_ROOT_FIRST);
			     dv != NULL;
			     dv = deviter_next(&di)) {
				if (device_class(dv) == DV_DISK &&
				    device_is_a(dv, "cd")) {
					booted_device = dv;
					booted_partition = 0;
					booted_nblks = 0;
					break;
				}
			}
			deviter_release(&di);
			DPRINTF(("%s: BTINFO_BIOSGEOM %s\n", __func__,
			    booted_device ? device_xname(booted_device) :
			    "not found"));
		}
	}
}
Beispiel #28
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);
}
Beispiel #29
0
/*
 * Attach a found zs.
 */
static void
zs_attach(device_t parent, device_t self, void *aux)
{
	struct zsc_softc *zsc = device_private(self);
	struct cfdata *cf = device_cfdata(self);
	struct hb_attach_args *ha = aux;
	struct zsc_attach_args zsc_args;
	struct zsdevice *zs;
	struct zschan *zc;
	struct zs_chanstate *cs;
	int s, channel, clk;

	zsc->zsc_dev = self;

	zs = (void *)IIOV(ha->ha_address);

	clk = cf->cf_flags;
	if (clk < 0 || clk >= NPCLK)
		clk = 0;

	aprint_normal("\n");

	/*
	 * Initialize software state for each channel.
	 */
	for (channel = 0; channel < 2; channel++) {
		zsc_args.channel = channel;
		cs = &zsc->zsc_cs_store[channel];

		zsc->zsc_cs[channel] = cs;
		zc = (channel == 0) ? &zs->zs_chan_a : &zs->zs_chan_b;

		if (ha->ha_vect != -1)
			zs_init_reg[2] = ha->ha_vect;

		if (zc == zc_cons) {
			memcpy(cs, zs_conschan, sizeof(struct zs_chanstate));
			zs_conschan = cs;
			zsc_args.hwflags = ZS_HWFLAG_CONSOLE;
		} else {
			cs->cs_reg_csr  = &zc->zc_csr;
			cs->cs_reg_data = &zc->zc_data;
			memcpy(cs->cs_creg, zs_init_reg, 16);
			memcpy(cs->cs_preg, zs_init_reg, 16);
			cs->cs_defspeed = zs_defspeed;
			zsc_args.hwflags = 0;
		}

		zs_lock_init(cs);
		cs->cs_defcflag = zs_def_cflag;

		cs->cs_channel = channel;
		cs->cs_private = NULL;
		cs->cs_ops = &zsops_null;
		cs->cs_brg_clk = pclk[clk] / 16;

		/* Make these correspond to cs_defcflag (-crtscts) */
		cs->cs_rr0_dcd = ZSRR0_DCD;
		cs->cs_rr0_cts = 0;
		cs->cs_wr5_dtr = ZSWR5_DTR | ZSWR5_RTS;
		cs->cs_wr5_rts = 0;

		/*
		 * Clear the master interrupt enable.
		 * The INTENA is common to both channels,
		 * so just do it on the A channel.
		 */
		if (channel == 0) {
			s = splhigh();
			zs_write_reg(cs, 9, 0);
			splx(s);
		}

		/*
		 * Look for a child driver for this channel.
		 * The child attach will setup the hardware.
		 */
		if (!config_found(self, (void *)&zsc_args, zs_print)) {
			/* No sub-driver.  Just reset it. */
			uint8_t reset = (channel == 0) ?
				ZSWR9_A_RESET : ZSWR9_B_RESET;
			s = splhigh();
			zs_write_reg(cs,  9, reset);
			splx(s);
		}
	}

	/*
	 * Now safe to install interrupt handlers.
	 */
	hb_intr_establish(zs_init_reg[2], zshard, ZSHARD_PRI, zsc);
	zsc->zsc_softintr_cookie = softint_establish(SOFTINT_SERIAL,
	    (void (*)(void *))zsc_intr_soft, zsc);

	/*
	 * Set the master interrupt enable and interrupt vector.
	 * (common to both channels, do it on A)
	 */
	cs = zsc->zsc_cs[0];
	s = splhigh();
	/* interrupt vector */
	zs_write_reg(cs, 2, zs_init_reg[2]);
	/* master interrupt control (enable) */
	zs_write_reg(cs, 9, zs_init_reg[9]);
	splx(s);

}
Beispiel #30
0
static void
zx_attach(device_t parent, device_t self, void *args)
{
	struct zx_softc *sc;
	struct sbus_attach_args *sa;
	bus_space_handle_t bh;
	bus_space_tag_t bt;
	struct fbdevice *fb;
#if NWSDISPLAY > 0
	struct wsemuldisplaydev_attach_args aa;
	struct rasops_info *ri = &zx_console_screen.scr_ri;
	unsigned long defattr;
#endif
	int isconsole, width, height;

	sc = device_private(self);
	sc->sc_dv = self;

	sa = args;
	fb = &sc->sc_fb;
	bt = sa->sa_bustag;
	sc->sc_bt = bt;
	sc->sc_paddr = sbus_bus_addr(bt, sa->sa_slot, sa->sa_offset);

	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_SS0,
	    0x800000, BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_LARGE, &bh) != 0) {
		aprint_error_dev(self, "can't map bits\n");
		return;
	}
	fb->fb_pixels = (void *)bus_space_vaddr(bt, bh);
	sc->sc_pixels = (uint32_t *)fb->fb_pixels;

	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LC_SS0_USR,
	    PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) {
		aprint_error_dev(self, "can't map zc\n");
		return;
	}

	sc->sc_bhzc = bh;

	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LD_SS0,
	    PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) {
		aprint_error_dev(self, "can't map ld/ss0\n");
		return;
	}
	sc->sc_bhzdss0 = bh;

	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LD_SS1,
	    PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) {
		aprint_error_dev(self, "can't map ld/ss1\n");
		return;
	}
	sc->sc_bhzdss1 = bh;

	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LX_CROSS,
	    PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) {
		aprint_error_dev(self, "can't map zx\n");
		return;
	}
	sc->sc_bhzx = bh;

	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset + ZX_OFF_LX_CURSOR,
	    PAGE_SIZE, BUS_SPACE_MAP_LINEAR, &bh) != 0) {
		aprint_error_dev(self, "can't map zcu\n");
		return;
	}
	sc->sc_bhzcu = bh;

	fb->fb_driver = &zx_fbdriver;
	fb->fb_device = sc->sc_dv;
	fb->fb_flags = device_cfdata(sc->sc_dv)->cf_flags & FB_USERMASK;
	fb->fb_pfour = NULL;
	fb->fb_linebytes = prom_getpropint(sa->sa_node, "linebytes", 8192);

	width = prom_getpropint(sa->sa_node, "width", 1280);
	height = prom_getpropint(sa->sa_node, "height", 1024);
	fb_setsize_obp(fb, 32, width, height, sa->sa_node);

	fb->fb_type.fb_cmsize = 256;
	fb->fb_type.fb_depth = 32;
	fb->fb_type.fb_size = fb->fb_type.fb_height * fb->fb_linebytes;
	fb->fb_type.fb_type = FBTYPE_SUNLEO;

	printf(": %d x %d", fb->fb_type.fb_width, fb->fb_type.fb_height);
	isconsole = fb_is_console(sa->sa_node);
	if (isconsole)
		printf(" (console)");
	printf("\n");

	if (sa->sa_nintr != 0)
		bus_intr_establish(bt, sa->sa_pri, IPL_NONE, zx_intr, sc);

	sc->sc_cmap = malloc(768, M_DEVBUF, M_NOWAIT);
	zx_reset(sc);

#if NWSDISPLAY > 0
	sc->sc_width = fb->fb_type.fb_width;
	sc->sc_stride = 8192; /* 32 bit */
	sc->sc_height = fb->fb_type.fb_height;

	/* setup rasops and so on for wsdisplay */
	wsfont_init();
	sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
	sc->sc_bg = WS_DEFAULT_BG;

	vcons_init(&sc->vd, sc, &zx_defaultscreen, &zx_accessops);
	sc->vd.init_screen = zx_init_screen;

	if (isconsole) {
		/* we mess with zx_console_screen only once */
		vcons_init_screen(&sc->vd, &zx_console_screen, 1,
		    &defattr);
		zx_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
		
		zx_defaultscreen.textops = &ri->ri_ops;
		zx_defaultscreen.capabilities = WSSCREEN_WSCOLORS;
		zx_defaultscreen.nrows = ri->ri_rows;
		zx_defaultscreen.ncols = ri->ri_cols;
		zx_fillrect(sc, 0, 0, width, height,
		     ri->ri_devcmap[defattr >> 16], ZX_STD_ROP);
		wsdisplay_cnattach(&zx_defaultscreen, ri, 0, 0, defattr);
		vcons_replay_msgbuf(&zx_console_screen);
	} else {
		/* 
		 * we're not the console so we just clear the screen and don't 
		 * set up any sort of text display
		 */
		if (zx_defaultscreen.textops == NULL) {