コード例 #1
0
ファイル: panel.c プロジェクト: lacombar/netbsd-alc
static void
panel_attach(device_t parent, device_t self, void *aux)
{
	struct panel_softc *sc = device_private(self);
	struct mainbus_attach_args *maa = aux;
	struct hd44780_io io;
	static struct lcdkp_xlate keys[] = {
		{ 0xfa, 'h' },
		{ 0xf6, 'k' },
		{ 0xde, 'l' },
		{ 0xee, 'j' },
		{ 0x7e, 's' },
		{ 0xbe, 'e' }
	};

	sc->sc_lcd.sc_dev = self;
	sc->sc_lcd.sc_iot = maa->ma_iot;
	if (bus_space_map(sc->sc_lcd.sc_iot, maa->ma_addr, PANEL_REGION,
	    0, &sc->sc_lcd.sc_ioir)) {
		aprint_error(": unable to map registers\n");
		return;
	}
	bus_space_subregion(sc->sc_lcd.sc_iot, sc->sc_lcd.sc_ioir, DATA_OFFSET,
	    1, &sc->sc_lcd.sc_iodr);

	sc->sc_lcd.sc_dev_ok = 1;
	sc->sc_lcd.sc_cols = PANEL_COLS;
	sc->sc_lcd.sc_vcols = PANEL_VCOLS;
	sc->sc_lcd.sc_flags = HD_8BIT | HD_MULTILINE | HD_KEYPAD;

	sc->sc_lcd.sc_writereg = panel_cbt_hdwritereg;
	sc->sc_lcd.sc_readreg = panel_cbt_hdreadreg;

	hd44780_attach_subr(&sc->sc_lcd);

	/* Hello World */
	io.dat = 0;
	io.len = PANEL_VCOLS * PANEL_ROWS;
	memcpy(io.buf, &startup_message, io.len);
	hd44780_ddram_io(&sc->sc_lcd, sc->sc_lcd.sc_curchip, &io,
	    HD_DDRAM_WRITE);

	shutdownhook_establish(panel_shutdown, sc);

	sc->sc_kp.sc_iot = maa->ma_iot;
	sc->sc_kp.sc_ioh = MIPS_PHYS_TO_KSEG1(PANEL_BASE); /* XXX */

	sc->sc_kp.sc_knum = sizeof(keys) / sizeof(struct lcdkp_xlate);
	sc->sc_kp.sc_kpad = keys;
	sc->sc_kp.sc_rread = panel_cbt_kprread;

	lcdkp_attach_subr(&sc->sc_kp);

	callout_init(&sc->sc_callout, 0);
	selinit(&sc->sc_selq);

	printf("\n");
}
コード例 #2
0
void
wdog_register(void *cb_arg, int (*cb)(void *, int))
{
	if (wdog_ctl_cb != NULL)
		return;

	wdog_ctl_cb = cb;
	wdog_ctl_cb_arg = cb_arg;
	timeout_set(&wdog_timeout, wdog_tickle, NULL);
	wdog_cookie = shutdownhook_establish(wdog_shutdown, NULL);
}
コード例 #3
0
static void
slugled_defer(device_t self)
{
	struct slugled_softc *sc = device_private(self);
	struct ixp425_softc *ixsc = ixp425_softc;
	uint32_t reg;
	int s;

	s = splhigh();

	/* Configure LED GPIO pins as output */
	reg = GPIO_CONF_READ_4(ixsc, IXP425_GPIO_GPOER);
	reg &= ~(LEDBITS_USB0 | LEDBITS_USB1);
	reg &= ~(LEDBITS_READY | LEDBITS_STATUS);
	GPIO_CONF_WRITE_4(ixsc, IXP425_GPIO_GPOER, reg);

	/* All LEDs off */
	reg = GPIO_CONF_READ_4(ixsc, IXP425_GPIO_GPOUTR);
	reg |= LEDBITS_USB0 | LEDBITS_USB1;
	reg &= ~(LEDBITS_STATUS | LEDBITS_READY);
	GPIO_CONF_WRITE_4(ixsc, IXP425_GPIO_GPOUTR, reg);

	splx(s);

	if (shutdownhook_establish(slugled_shutdown, sc) == NULL)
		aprint_error_dev(self, "WARNING - Failed to register shutdown hook\n");

	callout_init(&sc->sc_usb0, 0);
	callout_setfunc(&sc->sc_usb0, slugled_callout,
	    (void *)(uintptr_t)LEDBITS_USB0);

	callout_init(&sc->sc_usb1, 0);
	callout_setfunc(&sc->sc_usb1, slugled_callout,
	    (void *)(uintptr_t)LEDBITS_USB1);

	callout_init(&sc->sc_usb2, 0);
	callout_setfunc(&sc->sc_usb2, slugled_callout,
	    (void *)(uintptr_t)(LEDBITS_USB0 | LEDBITS_USB1));

	sc->sc_usb0_ih = ixp425_intr_establish(PCI_INT_A, IPL_USB,
	    slugled_intr0, sc);
	KDASSERT(sc->sc_usb0_ih != NULL);
	sc->sc_usb1_ih = ixp425_intr_establish(PCI_INT_B, IPL_USB,
	    slugled_intr1, sc);
	KDASSERT(sc->sc_usb1_ih != NULL);
	sc->sc_usb2_ih = ixp425_intr_establish(PCI_INT_C, IPL_USB,
	    slugled_intr2, sc);
	KDASSERT(sc->sc_usb2_ih != NULL);

	sc->sc_tmr_ih = ixp425_intr_establish(IXP425_INT_TMR0, IPL_CLOCK,
	    slugled_tmr, NULL);
	KDASSERT(sc->sc_tmr_ih != NULL);
}
コード例 #4
0
ファイル: ld.c プロジェクト: MarginC/kame
void
ldattach(struct ld_softc *sc)
{
	char buf[9];

	if ((sc->sc_flags & LDF_ENABLED) == 0) {
		printf("%s: disabled\n", sc->sc_dv.dv_xname);
		return;
	}

	/* Initialise and attach the disk structure. */
	sc->sc_dk.dk_driver = &lddkdriver;
	sc->sc_dk.dk_name = sc->sc_dv.dv_xname;
	disk_attach(&sc->sc_dk);

	if (sc->sc_maxxfer > MAXPHYS)
		sc->sc_maxxfer = MAXPHYS;

	/* Build synthetic geometry. */
	if (sc->sc_secperunit <= 528 * 2048)		/* 528MB */
		sc->sc_nheads = 16;
	else if (sc->sc_secperunit <= 1024 * 2048)	/* 1GB */
		sc->sc_nheads = 32;
	else if (sc->sc_secperunit <= 21504 * 2048)	/* 21GB */
		sc->sc_nheads = 64;
	else if (sc->sc_secperunit <= 43008 * 2048)	/* 42GB */
		sc->sc_nheads = 128;
	else
		sc->sc_nheads = 255;

	sc->sc_nsectors = 63;
	sc->sc_ncylinders = sc->sc_secperunit / 
	    (sc->sc_nheads * sc->sc_nsectors);

	format_bytes(buf, sizeof(buf), (u_int64_t)sc->sc_secperunit *
	    sc->sc_secsize);
	printf("%s: %s, %d cyl, %d head, %d sec, %d bytes/sect x %d sectors\n",
	    sc->sc_dv.dv_xname, buf, sc->sc_ncylinders, sc->sc_nheads,
	    sc->sc_nsectors, sc->sc_secsize, sc->sc_secperunit);

#if NRND > 0
	/* Attach the device into the rnd source list. */
	rnd_attach_source(&sc->sc_rnd_source, sc->sc_dv.dv_xname,
	    RND_TYPE_DISK, 0);
#endif

	/* Set the `shutdownhook'. */
	if (ld_sdh == NULL)
		ld_sdh = shutdownhook_establish(ldshutdown, NULL);
	BUFQ_INIT(&sc->sc_bufq);
}
コード例 #5
0
ファイル: sysmon_wdog.c プロジェクト: MarginC/kame
/*
 * sysmonopen_wdog:
 *
 *	Open the system monitor device.
 */
int
sysmonopen_wdog(dev_t dev, int flag, int mode, struct proc *p)
{

	simple_lock(&sysmon_wdog_list_slock);
	if (sysmon_wdog_sdhook == NULL) {
		sysmon_wdog_sdhook =
		    shutdownhook_establish(sysmon_wdog_shutdown, NULL);
		if (sysmon_wdog_sdhook == NULL)
			printf("WARNING: unable to register watchdog "
			    "shutdown hook\n");
	}
	simple_unlock(&sysmon_wdog_list_slock);

	return (0);
}
コード例 #6
0
int
sysctl_wdog(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
    size_t newlen)
{
	int error, period;

	if (wdog_ctl_cb == NULL)
		return (EOPNOTSUPP);

	switch (name[0]) {
	case KERN_WATCHDOG_PERIOD:
		period = wdog_period;
		error = sysctl_int(oldp, oldlenp, newp, newlen, &period);
		if (error)
			return (error);
		if (newp) {
			timeout_del(&wdog_timeout);
			wdog_period = (*wdog_ctl_cb)(wdog_ctl_cb_arg, period);
		}
		break;
	case KERN_WATCHDOG_AUTO:
		error = sysctl_int(oldp, oldlenp, newp, newlen, &wdog_auto);
		if (error)
			return (error);
		if (wdog_auto && wdog_cookie == NULL)
			wdog_cookie = shutdownhook_establish(wdog_shutdown,
			    NULL);
		else if (!wdog_auto && wdog_cookie) {
			shutdownhook_disestablish(wdog_cookie);
			wdog_cookie = NULL;
		}
		break;
	default:
		return (EINVAL);
	} 

	if (wdog_auto && wdog_period > 0) {
		(void) (*wdog_ctl_cb)(wdog_ctl_cb_arg, wdog_period);
		timeout_add(&wdog_timeout, wdog_period * hz / 2);
	} else
		timeout_del(&wdog_timeout);

	return (error);
}
コード例 #7
0
void
mb8795_config(struct mb8795_softc *sc, int *media, int nmedia, int defmedia)
{
	struct ifnet *ifp = &sc->sc_ethercom.ec_if;

	DPRINTF(("%s: mb8795_config()\n",device_xname(sc->sc_dev)));

	/* Initialize ifnet structure. */
	memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
	ifp->if_softc = sc;
	ifp->if_start = mb8795_start;
	ifp->if_ioctl = mb8795_ioctl;
	ifp->if_watchdog = mb8795_watchdog;
	ifp->if_flags =
		IFF_BROADCAST | IFF_NOTRAILERS;

	/* Initialize media goo. */
	ifmedia_init(&sc->sc_media, 0, mb8795_mediachange,
		     mb8795_mediastatus);
	if (media != NULL) {
		int i;
		for (i = 0; i < nmedia; i++)
			ifmedia_add(&sc->sc_media, media[i], 0, NULL);
		ifmedia_set(&sc->sc_media, defmedia);
	} else {
		ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
		ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
	}

  /* Attach the interface. */
  if_attach(ifp);
  ether_ifattach(ifp, sc->sc_enaddr);

  sc->sc_sh = shutdownhook_establish(mb8795_shutdown, sc);
  if (sc->sc_sh == NULL)
    panic("mb8795_config: can't establish shutdownhook");

  rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev),
                    RND_TYPE_NET, RND_FLAG_DEFAULT);

	DPRINTF(("%s: leaving mb8795_config()\n",device_xname(sc->sc_dev)));
}
コード例 #8
0
ファイル: powsw.c プロジェクト: ryo/netbsd-src
static void
powsw_attach(device_t parent, device_t self, void *aux)
{
	struct powsw_softc *sc = device_private(self);
	powsw_desc_t *desc;
	const char *xname;
	int unit;
	int sw;

	unit = device_unit(self);
	xname = device_xname(self);
	desc = &powsw_desc[unit];

	memset(sc, 0, sizeof(*sc));
	sc->sc_dev = self;
	sc->sc_mask = desc->mask;
	sc->sc_prev = -1;
	powsw_reset_counter(sc);

	sysmon_task_queue_init();
	sc->sc_smpsw.smpsw_name = xname;
	sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_POWER;
	if (sysmon_pswitch_register(&sc->sc_smpsw) != 0)
		panic("can't register with sysmon");

	callout_init(&sc->sc_callout, 0);
	callout_setfunc(&sc->sc_callout, powsw_softintr, sc);

	if (shutdownhook_establish(powsw_shutdown_check, sc) == NULL)
		panic("%s: can't establish shutdown hook", xname);

	if (intio_intr_establish(desc->vector, xname, powsw_intr, sc) < 0)
		panic("%s: can't establish interrupt", xname);

	/* Set AER and enable interrupt */
	sw = (mfp_get_gpip() & sc->sc_mask);
	powsw_set_aer(sc, sw ? 0 : 1);
	mfp_bit_set_ierb(sc->sc_mask);

	aprint_normal(": %s\n", desc->name);
}
コード例 #9
0
ファイル: if_fta.c プロジェクト: MarginC/kame
static void
pdq_tc_attach(
    struct device * const parent,
    struct device * const self,
    void * const aux)
{
    pdq_softc_t * const sc = (pdq_softc_t *) self;
    struct tc_attach_args * const ta = (struct tc_attach_args *) aux;

    /*
     * NOTE: sc_bc is an alias for sc_csrtag and sc_membase is an
     * alias for sc_csrhandle.  sc_iobase is not used in this front-end.
     */
    sc->sc_csrtag = ta->ta_memt;
    bcopy(sc->sc_dev.dv_xname, sc->sc_if.if_xname, IFNAMSIZ);
    sc->sc_if.if_flags = 0;
    sc->sc_if.if_softc = sc;

    if (bus_space_map(sc->sc_csrtag, ta->ta_addr + PDQ_TC_CSR_OFFSET,
		    PDQ_TC_CSR_SPACE, 0, &sc->sc_csrhandle)) {
        printf("\n%s: can't map card memory!\n", sc->sc_dev.dv_xname);
	return;
    }

    sc->sc_pdq = pdq_initialize(sc->sc_csrtag, sc->sc_csrhandle,
				sc->sc_if.if_xname, 0,
				(void *) sc, PDQ_DEFTA);
    if (sc->sc_pdq == NULL) {
	printf("%s: initialization failed\n", sc->sc_dev.dv_xname);
	return;
    }
    bcopy((caddr_t) sc->sc_pdq->pdq_hwaddr.lanaddr_bytes, sc->sc_ac.ac_enaddr, 6);
    pdq_ifattach(sc, NULL);

    tc_intr_establish(parent, ta->ta_cookie, TC_IPL_NET,
		      (int (*)(void *)) pdq_interrupt, sc->sc_pdq);

    sc->sc_ats = shutdownhook_establish((void (*)(void *)) pdq_hwreset, sc->sc_pdq);
    if (sc->sc_ats == NULL)
	printf("%s: warning: couldn't establish shutdown hook\n", self->dv_xname);
}
コード例 #10
0
void
apm_attach(struct device *parent, struct device *self, void *aux)
{
	struct zapm_softc *sc = (struct zapm_softc *)self;

	pxa2x0_gpio_set_function(GPIO_AC_IN_C3000, GPIO_IN);
	pxa2x0_gpio_set_function(GPIO_CHRG_CO_C3000, GPIO_IN);
	pxa2x0_gpio_set_function(GPIO_BATT_COVER_C3000, GPIO_IN);

	(void)pxa2x0_gpio_intr_establish(GPIO_AC_IN_C3000,
	    IST_EDGE_BOTH, IPL_BIO, zapm_acintr, sc, "apm_ac");
	(void)pxa2x0_gpio_intr_establish(GPIO_BATT_COVER_C3000,
	    IST_EDGE_BOTH, IPL_BIO, zapm_bcintr, sc, "apm_bc");

	sc->sc_event = APM_NOEVENT;
	sc->sc.sc_get_event = zapm_get_event;
	sc->sc.sc_power_info = zapm_power_info;
	sc->sc.sc_suspend = zapm_suspend;
	sc->sc.sc_resume = zapm_resume;

	timeout_set(&sc->sc_poll, &zapm_poll, sc);

	/* Get initial battery voltage. */
	zapm_enable_charging(sc, 0);
	if (zapm_ac_on()) {
		/* C3000: discharge 100 ms when AC is on. */
		scoop_discharge_battery(1);
		delay(100000);
	}
	sc->sc_batt_volt = zapm_batt_volt();
	scoop_discharge_battery(0);

	pxa2x0_apm_attach_sub(&sc->sc);

#if 0
	(void)shutdownhook_establish(zapm_shutdown, NULL);
#endif

	cpu_setperf = pxa2x0_setperf;
	cpu_cpuspeed = pxa2x0_cpuspeed;
}
コード例 #11
0
static int
lemac_isa_find(lemac_softc_t *sc, const char *xname, struct isa_attach_args *ia, int attach)
{
	bus_addr_t maddr;
	bus_size_t msiz;
	int rv = 0, irq;

	if (ia->ia_nio < 1)
		return (0);
	if (ia->ia_niomem < 1)
		return (0);
	if (ia->ia_nirq < 1)
		return (0);

	if (ISA_DIRECT_CONFIG(ia))
		return (0);

	/*
	 * Disallow wildcarded i/o addresses.
	 */
	if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT)
		return 0;

	/*
	 * Make sure this is a valid LEMAC address.
	 */
	if (ia->ia_io[0].ir_addr & (LEMAC_IOSIZE - 1))
		return 0;

	sc->sc_iot = ia->ia_iot;

	if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr, LEMAC_IOSIZE, 0,
	    &sc->sc_ioh)) {
		if (attach)
			printf(": can't map i/o space\n");
		return 0;
	}

	/*
	 * Read the Ethernet address from the EEPROM.
	 * It must start with one of the DEC OUIs and pass the
	 * DEC ethernet checksum test.
	 */
	if (lemac_port_check(sc->sc_iot, sc->sc_ioh) == 0)
		goto outio;

	/*
	 * Get information about memory space and attempt to map it.
	 */
	lemac_info_get(sc->sc_iot, sc->sc_ioh, &maddr, &msiz, &irq);

	if (ia->ia_iomem[0].ir_addr != ISA_UNKNOWN_IOMEM &&
	    ia->ia_iomem[0].ir_addr != maddr)
		goto outio;

	if (attach) {
		if (msiz == 0) {
			printf(": memory configuration is invalid\n");
			goto outio;
		}

		sc->sc_memt = ia->ia_memt;
		if (bus_space_map(ia->ia_memt, maddr, msiz, 0, &sc->sc_memh)) {
			printf(": can't map mem space\n");
			goto outio;
		}
	}

	/*
	 * Double-check IRQ configuration.
	 */
	if (ia->ia_irq[0].ir_irq != ISA_UNKNOWN_IRQ &&
	    ia->ia_irq[0].ir_irq != irq)
		printf("%s: overriding IRQ %d to %d\n", xname,
		       ia->ia_irq[0].ir_irq, irq);

	if (attach) {
		sc->sc_ats = shutdownhook_establish(lemac_shutdown, sc);
		if (sc->sc_ats == NULL) {
			aprint_normal("\n");
			aprint_error("%s: warning: can't establish shutdown hook\n", xname);
		}

		lemac_ifattach(sc);

		sc->sc_ih = isa_intr_establish(ia->ia_ic, irq, IST_EDGE,
		    IPL_NET, lemac_intr, sc);
	}

	/*
	 * I guess we've found one.
	 */
	rv = 1;

	ia->ia_nio = 1;
	ia->ia_io[0].ir_size = LEMAC_IOSIZE;

	ia->ia_niomem = 1;
	ia->ia_iomem[0].ir_addr = maddr;
	ia->ia_iomem[0].ir_size = msiz;

	ia->ia_nirq = 1;
	ia->ia_irq[0].ir_irq = irq;

	ia->ia_ndrq = 0;

outio:
	if (rv == 0 || !attach)
		bus_space_unmap(sc->sc_iot, sc->sc_ioh, LEMAC_IOSIZE);
	return rv;
}
コード例 #12
0
void
rapide_attach(device_t parent, device_t self, void *aux)
{
	struct rapide_softc *sc = device_private(self);
	struct podule_attach_args *pa = (void *)aux;
	bus_space_tag_t iot;
	bus_space_handle_t ctlioh;
	u_int iobase;
	int channel, i;
	struct rapide_channel *rcp;
	struct ata_channel *cp;
	struct wdc_regs *wdr;
	irqhandler_t *ihp;

	/* Note the podule number and validate */
	if (pa->pa_podule_number == -1)
		panic("Podule has disappeared !");

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

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

	set_easi_cycle_type(sc->sc_podule_number, EASI_CYCLE_TYPE_C);

	/*
	 * Duplicate the podule bus space tag and provide alternative
	 * bus_space_read_multi_4() and bus_space_write_multi_4()
	 * functions.
	 */
	rapide_bs_tag = *pa->pa_iot;
	rapide_bs_tag.bs_rm_4 = rapide_bs_rm_4;
	rapide_bs_tag.bs_wm_4 = rapide_bs_wm_4;
	sc->sc_ctliot = iot = &rapide_bs_tag;

	if (bus_space_map(iot, pa->pa_podule->easi_base +
	    CONTROL_REGISTERS_OFFSET, CONTROL_REGISTER_SPACE, 0, &ctlioh))
		panic("%s: Cannot map control registers", device_xname(self));

	sc->sc_ctlioh = ctlioh;
	sc->sc_version = bus_space_read_1(iot, ctlioh, VERSION_REGISTER_OFFSET) & VERSION_REGISTER_MASK;
/*	bus_space_unmap(iot, ctl_ioh, CONTROL_REGISTER_SPACE);*/

	aprint_normal(": Issue %d\n", sc->sc_version + 1);
	if (sc->sc_version != VERSION_2_ID)
		return;

	if (shutdownhook_establish(rapide_shutdown, (void *)sc) == NULL)
		panic("%s: Cannot install shutdown handler", device_xname(self));

	/* Set the interrupt info for this podule */
	sc->sc_podule->irq_addr = pa->pa_podule->easi_base
	    + CONTROL_REGISTERS_OFFSET + IRQ_REQUEST_REGISTER_BYTE_OFFSET;
	sc->sc_podule->irq_mask = IRQ_MASK;

	iobase = pa->pa_podule->easi_base;

	/* Fill in wdc and channel infos */
	sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA32;
	sc->sc_wdcdev.sc_atac.atac_pio_cap = 0;
	sc->sc_wdcdev.sc_atac.atac_channels = sc->sc_chanarray;
	sc->sc_wdcdev.sc_atac.atac_nchannels = 2;
	sc->sc_wdcdev.wdc_maxdrives = 2;
	for (channel = 0 ; channel < 2; channel++) {
		rcp = &sc->rapide_channels[channel];
		sc->sc_chanarray[channel] = &rcp->rc_channel;
		cp = &rcp->rc_channel;
		wdr = &sc->sc_wdc_regs[channel];

		cp->ch_channel = channel;
		cp->ch_atac = &sc->sc_wdcdev.sc_atac;
		cp->ch_queue = &rcp->rc_chqueue;
		wdr->cmd_iot = iot;
		wdr->ctl_iot = iot;
		wdr->data32iot = iot;

		if (bus_space_map(iot, iobase + rapide_info[channel].registers,
		    DRIVE_REGISTERS_SPACE, 0, &wdr->cmd_baseioh))
			continue;
		for (i = 0; i < WDC_NREG; i++) {
			if (bus_space_subregion(wdr->cmd_iot, wdr->cmd_baseioh,
				i, i == 0 ? 4 : 1, &wdr->cmd_iohs[i]) != 0) {
				bus_space_unmap(iot, wdr->cmd_baseioh,
				    DRIVE_REGISTERS_SPACE);
				continue;
			}
		}
		wdc_init_shadow_regs(cp);
		if (bus_space_map(iot, iobase +
		    rapide_info[channel].aux_register, 4, 0, &wdr->ctl_ioh)) {
			bus_space_unmap(iot, wdr->cmd_baseioh,
			   DRIVE_REGISTERS_SPACE);
			continue;
		}
		if (bus_space_map(iot, iobase +
		    rapide_info[channel].data_register, 4, 0, &wdr->data32ioh)) {
			bus_space_unmap(iot, wdr->cmd_baseioh,
			   DRIVE_REGISTERS_SPACE);
			bus_space_unmap(iot, wdr->ctl_ioh, 4);
			continue;
		}
		/* Disable interrupts and clear any pending interrupts */
		rcp->rc_irqmask = rapide_info[channel].irq_mask;
		sc->sc_intr_enable_mask &= ~rcp->rc_irqmask;
		bus_space_write_1(iot, sc->sc_ctlioh, IRQ_MASK_REGISTER_OFFSET,
		    sc->sc_intr_enable_mask);
		/* XXX - Issue 1 cards will need to clear any pending interrupts */
		ihp = &rcp->rc_ih;
		ihp->ih_func = rapide_intr;
		ihp->ih_arg = rcp;
		ihp->ih_level = IPL_BIO;
		ihp->ih_name = "rapide";
		ihp->ih_maskaddr = pa->pa_podule->irq_addr;
		ihp->ih_maskbits = rcp->rc_irqmask;
		if (irq_claim(sc->sc_podule->interrupt, ihp))
			panic("%s: Cannot claim interrupt %d",
			    device_xname(self), sc->sc_podule->interrupt);
		/* clear any pending interrupts and enable interrupts */
		sc->sc_intr_enable_mask |= rcp->rc_irqmask;
		bus_space_write_1(iot, sc->sc_ctlioh,
		    IRQ_MASK_REGISTER_OFFSET, sc->sc_intr_enable_mask);
		/* XXX - Issue 1 cards will need to clear any pending interrupts */
		wdcattach(cp);
	}
}
コード例 #13
0
ファイル: tft_ll.c プロジェクト: lacombar/netbsd-alc
static void
ll_tft_attach(struct device *parent, struct device *self, void *aux)
{
	struct xcvbus_attach_args *vaa = aux;
	struct ll_dmac 		*tx = vaa->vaa_tx_dmac;
	struct ll_tft_softc 	*lsc = (struct ll_tft_softc *)self;
	struct tft_softc 	*sc = &lsc->lsc_sc;
	int 			nseg, error;

	KASSERT(tx);

	lsc->lsc_dma_iot 	= tx->dmac_iot;
	lsc->lsc_dmat 		= vaa->vaa_dmat;
	sc->sc_iot 		= vaa->vaa_iot;

	printf(": LL_TFT\n");

	if ((error = bus_space_map(sc->sc_iot, vaa->vaa_addr, TFT_SIZE,
	    0, &sc->sc_ioh)) != 0) {
	    	printf("%s: could not map device registers\n",
		    device_xname(self));
	    	goto fail_0;
	}
	if ((error = bus_space_map(lsc->lsc_dma_iot, tx->dmac_ctrl_addr,
	    CDMAC_CTRL_SIZE, 0, &lsc->lsc_dma_ioh)) != 0) {
		printf("%s: could not map dmac registers\n",
		    device_xname(self));
		goto fail_1;
	}

	/* Fill in resolution, depth, size. */
	tft_mode(&sc->sc_dev);

	/* Allocate and map framebuffer control data. */
	if ((error = bus_dmamem_alloc(lsc->lsc_dmat,
	    sizeof(struct ll_tft_control) + sc->sc_size, 8, 0,
	    &lsc->lsc_seg, 1, &nseg, 0)) != 0) {
	    	printf("%s: could not allocate framebuffer\n",
		    device_xname(self));
		goto fail_2;
	}
	if ((error = bus_dmamem_map(lsc->lsc_dmat, &lsc->lsc_seg, nseg,
	    sizeof(struct ll_tft_control) + sc->sc_size,
	    (void **)&lsc->lsc_cd, BUS_DMA_COHERENT)) != 0) {
	    	printf("%s: could not map framebuffer\n",
		    device_xname(self));
		goto fail_3;
	}
	if ((error = bus_dmamap_create(lsc->lsc_dmat,
	    sizeof(struct ll_tft_control) + sc->sc_size, 1,
	    sizeof(struct ll_tft_control) + sc->sc_size, 0, 0,
	    &lsc->lsc_dmap)) != 0) {
	    	printf("%s: could not create framebuffer DMA map\n",
		    device_xname(self));
		goto fail_4;
	}
	if ((error = bus_dmamap_load(lsc->lsc_dmat, lsc->lsc_dmap, lsc->lsc_cd,
	    sizeof(struct ll_tft_control) + sc->sc_size, NULL, 0)) != 0) {
	    	printf("%s: could not load framebuffer DMA map\n",
		    device_xname(self));
		goto fail_5;
	}

	/* Clear screen, setup descriptor. */
	memset(lsc->lsc_cd, 0x00, sizeof(struct ll_tft_control));
	sc->sc_image = lsc->lsc_cd->cd_img;

	lsc->lsc_cd->cd_dsc.desc_next = lsc->lsc_dmap->dm_segs[0].ds_addr;
	lsc->lsc_cd->cd_dsc.desc_addr = lsc->lsc_dmap->dm_segs[0].ds_addr +
	    offsetof(struct ll_tft_control, cd_img);
	lsc->lsc_cd->cd_dsc.desc_size = sc->sc_size;
	lsc->lsc_cd->cd_dsc.desc_stat = CDMAC_STAT_SOP;

	bus_dmamap_sync(lsc->lsc_dmat, lsc->lsc_dmap, 0,
	    sizeof(struct ll_tft_control) + sc->sc_size,
	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);

	sc->sc_sdhook = shutdownhook_establish(ll_tft_shutdown, sc);
	if (sc->sc_sdhook == NULL)
		printf("%s: WARNING: unable to establish shutdown hook\n",
		    device_xname(self));

	tft_attach(self, &ll_tft_accessops);

	printf("%s: video memory pa 0x%08x\n", device_xname(self),
	    (uint32_t)lsc->lsc_cd->cd_dsc.desc_addr);

	/* Timing sensitive... */
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, TFT_CTRL, CTRL_RESET);
	bus_space_write_4(sc->sc_iot, sc->sc_ioh, TFT_CTRL, CTRL_ENABLE);
	bus_space_write_4(lsc->lsc_dma_iot, lsc->lsc_dma_ioh, CDMAC_CURDESC,
	    lsc->lsc_dmap->dm_segs[0].ds_addr);

	return ;

 fail_5:
 	bus_dmamap_destroy(lsc->lsc_dmat, lsc->lsc_dmap);
 fail_4:
 	bus_dmamem_unmap(lsc->lsc_dmat, (void *)lsc->lsc_cd,
 	    sizeof(struct ll_tft_control) + sc->sc_size);
 fail_3:
 	bus_dmamem_free(lsc->lsc_dmat, &lsc->lsc_seg, nseg);
 fail_2:
	bus_space_unmap(lsc->lsc_dma_iot, lsc->lsc_dma_ioh, CDMAC_CTRL_SIZE);
 fail_1:
	bus_space_unmap(sc->sc_iot, sc->sc_ioh, TFT_SIZE);
 fail_0:
	printf("%s: error %d\n", device_xname(self), error);
}
コード例 #14
0
ファイル: cac.c プロジェクト: repos-holder/openbsd-patches
/*
 * Initialise our interface to the controller.
 */
int
cac_init(struct cac_softc *sc, int startfw)
{
	struct scsibus_attach_args saa;
	struct cac_controller_info cinfo;
	int error, rseg, size, i;
	bus_dma_segment_t seg[1];
	struct cac_ccb *ccb;

	SIMPLEQ_INIT(&sc->sc_ccb_free);
	SIMPLEQ_INIT(&sc->sc_ccb_queue);

        size = sizeof(struct cac_ccb) * CAC_MAX_CCBS;

	if ((error = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, seg, 1,
	    &rseg, BUS_DMA_NOWAIT)) != 0) {
		printf("%s: unable to allocate CCBs, error = %d\n",
		    sc->sc_dv.dv_xname, error);
		return (-1);
	}

	if ((error = bus_dmamem_map(sc->sc_dmat, seg, rseg, size,
	    &sc->sc_ccbs, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
		printf("%s: unable to map CCBs, error = %d\n",
		    sc->sc_dv.dv_xname, error);
		return (-1);
	}

	if ((error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
	    BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) {
		printf("%s: unable to create CCB DMA map, error = %d\n",
		    sc->sc_dv.dv_xname, error);
		return (-1);
	}

	if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_ccbs,
	    size, NULL, BUS_DMA_NOWAIT)) != 0) {
		printf("%s: unable to load CCB DMA map, error = %d\n",
		    sc->sc_dv.dv_xname, error);
		return (-1);
	}

	sc->sc_ccbs_paddr = sc->sc_dmamap->dm_segs[0].ds_addr;
	memset(sc->sc_ccbs, 0, size);
	ccb = (struct cac_ccb *)sc->sc_ccbs;

	for (i = 0; i < CAC_MAX_CCBS; i++, ccb++) {
		/* Create the DMA map for this CCB's data */
		error = bus_dmamap_create(sc->sc_dmat, CAC_MAX_XFER,
		    CAC_SG_SIZE, CAC_MAX_XFER, 0,
		    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
		    &ccb->ccb_dmamap_xfer);

		if (error) {
			printf("%s: can't create ccb dmamap (%d)\n",
			    sc->sc_dv.dv_xname, error);
			break;
		}

		ccb->ccb_paddr = sc->sc_ccbs_paddr + i * sizeof(struct cac_ccb);
		SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_free, ccb, ccb_chain);
	}

	/* Start firmware background tasks, if needed. */
	if (startfw) {
		if (cac_cmd(sc, CAC_CMD_START_FIRMWARE, &cinfo, sizeof(cinfo),
		    0, 0, CAC_CCB_DATA_IN, NULL)) {
			printf("%s: CAC_CMD_START_FIRMWARE failed\n",
			    sc->sc_dv.dv_xname);
			return (-1);
		}
	}

	if (cac_cmd(sc, CAC_CMD_GET_CTRL_INFO, &cinfo, sizeof(cinfo), 0, 0,
	    CAC_CCB_DATA_IN, NULL)) {
		printf("%s: CAC_CMD_GET_CTRL_INFO failed\n",
		    sc->sc_dv.dv_xname);
		return (-1);
	}

	if (!cinfo.num_drvs) {
		printf("%s: no volumes defined\n", sc->sc_dv.dv_xname);
		return (-1);
	}

	sc->sc_nunits = cinfo.num_drvs;
	sc->sc_dinfos = malloc(cinfo.num_drvs * sizeof(struct cac_drive_info),
	    M_DEVBUF, M_NOWAIT | M_ZERO);
	if (sc->sc_dinfos == NULL) {
		printf("%s: cannot allocate memory for drive_info\n",
		    sc->sc_dv.dv_xname);
		return (-1);
	}

	sc->sc_link.adapter_softc = sc;
	sc->sc_link.adapter = &cac_switch;
	sc->sc_link.adapter_target = cinfo.num_drvs;
	sc->sc_link.adapter_buswidth = cinfo.num_drvs;
	sc->sc_link.device = &cac_dev;
	sc->sc_link.openings = CAC_MAX_CCBS / sc->sc_nunits;
	if (sc->sc_link.openings < 4 )
		sc->sc_link.openings = 4;

	bzero(&saa, sizeof(saa));
	saa.saa_sc_link = &sc->sc_link;

	config_found(&sc->sc_dv, &saa, scsiprint);

	/* Set our `shutdownhook' before we start any device activity. */
	if (cac_sdh == NULL)
		cac_sdh = shutdownhook_establish(cac_shutdown, NULL);

	(*sc->sc_cl->cl_intr_enable)(sc, 1);

	return (0);
}
コード例 #15
0
ファイル: if_mec.c プロジェクト: repos-holder/openbsd-patches
void
mec_attach(struct device *parent, struct device *self, void *aux)
{
	struct mec_softc *sc = (void *)self;
	struct confargs *ca = aux;
	struct ifnet *ifp = &sc->sc_ac.ac_if;
	uint32_t command;
	struct mii_softc *child;
	bus_dma_segment_t seg;
	int i, err, rseg;

	sc->sc_st = ca->ca_iot;
	if (bus_space_map(sc->sc_st, ca->ca_baseaddr, MEC_NREGS, 0,
	    &sc->sc_sh) != 0) {
		printf(": can't map i/o space\n");
		return;
	}

	/* Set up DMA structures. */
	sc->sc_dmat = ca->ca_dmat;

	/*
	 * Allocate the control data structures, and create and load the
	 * DMA map for it.
	 */
	if ((err = bus_dmamem_alloc(sc->sc_dmat,
	    sizeof(struct mec_control_data), MEC_CONTROL_DATA_ALIGN, 0,
	    &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
		printf(": unable to allocate control data, error = %d\n", err);
		goto fail_0;
	}

	/*
	 * XXX needs re-think...
	 * control data structures contain whole RX data buffer, so
	 * BUS_DMA_COHERENT (which disables cache) may cause some performance
	 * issue on copying data from the RX buffer to mbuf on normal memory,
	 * though we have to make sure all bus_dmamap_sync(9) ops are called
	 * properly in that case.
	 */
	if ((err = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
	    sizeof(struct mec_control_data),
	    (caddr_t *)&sc->sc_control_data, /*BUS_DMA_COHERENT*/ 0)) != 0) {
		printf(": unable to map control data, error = %d\n", err);
		goto fail_1;
	}
	memset(sc->sc_control_data, 0, sizeof(struct mec_control_data));

	if ((err = bus_dmamap_create(sc->sc_dmat,
	    sizeof(struct mec_control_data), 1,
	    sizeof(struct mec_control_data), 0, 0, &sc->sc_cddmamap)) != 0) {
		printf(": unable to create control data DMA map, error = %d\n",
		    err);
		goto fail_2;
	}
	if ((err = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap,
	    sc->sc_control_data, sizeof(struct mec_control_data), NULL,
	    BUS_DMA_NOWAIT)) != 0) {
		printf(": unable to load control data DMA map, error = %d\n",
		    err);
		goto fail_3;
	}

	/* Create TX buffer DMA maps. */
	for (i = 0; i < MEC_NTXDESC; i++) {
		if ((err = bus_dmamap_create(sc->sc_dmat,
		    MCLBYTES, 1, MCLBYTES, 0, 0,
		    &sc->sc_txsoft[i].txs_dmamap)) != 0) {
			printf(": unable to create tx DMA map %d, error = %d\n",
			    i, err);
			goto fail_4;
		}
	}

	timeout_set(&sc->sc_tick_ch, mec_tick, sc);

	/* Use the Ethernet address from the ARCBIOS. */
	enaddr_aton(bios_enaddr, sc->sc_ac.ac_enaddr);

	/* Reset device. */
	mec_reset(sc);

	command = bus_space_read_8(sc->sc_st, sc->sc_sh, MEC_MAC_CONTROL);

	printf(": MAC-110 rev %d, address %s\n",
	    (command & MEC_MAC_REVISION) >> MEC_MAC_REVISION_SHIFT,
	    ether_sprintf(sc->sc_ac.ac_enaddr));

	/* Done, now attach everything. */

	sc->sc_mii.mii_ifp = ifp;
	sc->sc_mii.mii_readreg = mec_mii_readreg;
	sc->sc_mii.mii_writereg = mec_mii_writereg;
	sc->sc_mii.mii_statchg = mec_statchg;

	/* Set up PHY properties. */
	ifmedia_init(&sc->sc_mii.mii_media, 0, mec_mediachange,
	    mec_mediastatus);
	mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
	    MII_OFFSET_ANY, 0);

	child = LIST_FIRST(&sc->sc_mii.mii_phys);
	if (child == NULL) {
		/* No PHY attached. */
		ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL,
		    0, NULL);
		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_MANUAL);
	} else {
		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER | IFM_AUTO);
		sc->sc_phyaddr = child->mii_phy;
	}

	bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_ioctl = mec_ioctl;
	ifp->if_start = mec_start;
	ifp->if_watchdog = mec_watchdog;
	IFQ_SET_READY(&ifp->if_snd);

	if_attach(ifp);
	IFQ_SET_MAXLEN(&ifp->if_snd, MEC_NTXDESC - 1);
	ether_ifattach(ifp);

	/* Establish interrupt handler. */
	macebus_intr_establish(NULL, ca->ca_intr, IST_EDGE, IPL_NET,
	    mec_intr, sc, sc->sc_dev.dv_xname);

	/* Set hook to stop interface on shutdown. */
	sc->sc_sdhook = shutdownhook_establish(mec_shutdown, sc);

	return;

	/*
	 * Free any resources we've allocated during the failed attach
	 * attempt. Do this in reverse order and fall though.
	 */
 fail_4:
	for (i = 0; i < MEC_NTXDESC; i++) {
		if (sc->sc_txsoft[i].txs_dmamap != NULL)
			bus_dmamap_destroy(sc->sc_dmat,
			    sc->sc_txsoft[i].txs_dmamap);
	}
	bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
 fail_3:
	bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
 fail_2:
	bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_control_data,
	    sizeof(struct mec_control_data));
 fail_1:
	bus_dmamem_free(sc->sc_dmat, &seg, rseg);
 fail_0:
	return;
}
コード例 #16
0
ファイル: dp83932.c プロジェクト: Tommmster/netbsd-avr32
/*
 * sonic_attach:
 *
 *	Attach a SONIC interface to the system.
 */
void
sonic_attach(struct sonic_softc *sc, const uint8_t *enaddr)
{
	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
	int i, rseg, error;
	bus_dma_segment_t seg;
	size_t cdatasize;
	uint8_t *nullbuf;

	/*
	 * Allocate the control data structures, and create and load the
	 * DMA map for it.
	 */
	if (sc->sc_32bit)
		cdatasize = sizeof(struct sonic_control_data32);
	else
		cdatasize = sizeof(struct sonic_control_data16);

	if ((error = bus_dmamem_alloc(sc->sc_dmat, cdatasize + ETHER_PAD_LEN,
	     PAGE_SIZE, (64 * 1024), &seg, 1, &rseg,
	     BUS_DMA_NOWAIT)) != 0) {
		aprint_error_dev(sc->sc_dev,
		    "unable to allocate control data, error = %d\n", error);
		goto fail_0;
	}

	if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
	    cdatasize + ETHER_PAD_LEN, (void **) &sc->sc_cdata16,
	    BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
		aprint_error_dev(sc->sc_dev,
		    "unable to map control data, error = %d\n", error);
		goto fail_1;
	}
	nullbuf = (uint8_t *)sc->sc_cdata16 + cdatasize;
	memset(nullbuf, 0, ETHER_PAD_LEN);

	if ((error = bus_dmamap_create(sc->sc_dmat,
	     cdatasize, 1, cdatasize, 0, BUS_DMA_NOWAIT,
	     &sc->sc_cddmamap)) != 0) {
		aprint_error_dev(sc->sc_dev,
		    "unable to create control data DMA map, error = %d\n",
		    error);
		goto fail_2;
	}

	if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap,
	     sc->sc_cdata16, cdatasize, NULL, BUS_DMA_NOWAIT)) != 0) {
		aprint_error_dev(sc->sc_dev,
		    "unable to load control data DMA map, error = %d\n", error);
		goto fail_3;
	}

	/*
	 * Create the transmit buffer DMA maps.
	 */
	for (i = 0; i < SONIC_NTXDESC; i++) {
		if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
		     SONIC_NTXFRAGS, MCLBYTES, 0, BUS_DMA_NOWAIT,
		     &sc->sc_txsoft[i].ds_dmamap)) != 0) {
			aprint_error_dev(sc->sc_dev,
			    "unable to create tx DMA map %d, error = %d\n",
			    i, error);
			goto fail_4;
		}
	}

	/*
	 * Create the receive buffer DMA maps.
	 */
	for (i = 0; i < SONIC_NRXDESC; i++) {
		if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
		     MCLBYTES, 0, BUS_DMA_NOWAIT,
		     &sc->sc_rxsoft[i].ds_dmamap)) != 0) {
			aprint_error_dev(sc->sc_dev,
			    "unable to create rx DMA map %d, error = %d\n",
			    i, error);
			goto fail_5;
		}
		sc->sc_rxsoft[i].ds_mbuf = NULL;
	}

	/*
	 * create and map the pad buffer
	 */
	if ((error = bus_dmamap_create(sc->sc_dmat, ETHER_PAD_LEN, 1,
	    ETHER_PAD_LEN, 0, BUS_DMA_NOWAIT, &sc->sc_nulldmamap)) != 0) {
		aprint_error_dev(sc->sc_dev,
		    "unable to create pad buffer DMA map, error = %d\n", error);
		goto fail_5;
	}

	if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_nulldmamap,
	    nullbuf, ETHER_PAD_LEN, NULL, BUS_DMA_NOWAIT)) != 0) {
		aprint_error_dev(sc->sc_dev,
		    "unable to load pad buffer DMA map, error = %d\n", error);
		goto fail_6;
	}
	bus_dmamap_sync(sc->sc_dmat, sc->sc_nulldmamap, 0, ETHER_PAD_LEN,
	    BUS_DMASYNC_PREWRITE);

	/*
	 * Reset the chip to a known state.
	 */
	sonic_reset(sc);

	aprint_normal_dev(sc->sc_dev, "Ethernet address %s\n",
	    ether_sprintf(enaddr));

	strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_ioctl = sonic_ioctl;
	ifp->if_start = sonic_start;
	ifp->if_watchdog = sonic_watchdog;
	ifp->if_init = sonic_init;
	ifp->if_stop = sonic_stop;
	IFQ_SET_READY(&ifp->if_snd);

	/*
	 * We can support 802.1Q VLAN-sized frames.
	 */
	sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;

	/*
	 * Attach the interface.
	 */
	if_attach(ifp);
	ether_ifattach(ifp, enaddr);

	/*
	 * Make sure the interface is shutdown during reboot.
	 */
	sc->sc_sdhook = shutdownhook_establish(sonic_shutdown, sc);
	if (sc->sc_sdhook == NULL)
		aprint_error_dev(sc->sc_dev,
		    "WARNING: unable to establish shutdown hook\n");
	return;

	/*
	 * Free any resources we've allocated during the failed attach
	 * attempt.  Do this in reverse order and fall through.
	 */
 fail_6:
	bus_dmamap_destroy(sc->sc_dmat, sc->sc_nulldmamap);
 fail_5:
	for (i = 0; i < SONIC_NRXDESC; i++) {
		if (sc->sc_rxsoft[i].ds_dmamap != NULL)
			bus_dmamap_destroy(sc->sc_dmat,
			    sc->sc_rxsoft[i].ds_dmamap);
	}
 fail_4:
	for (i = 0; i < SONIC_NTXDESC; i++) {
		if (sc->sc_txsoft[i].ds_dmamap != NULL)
			bus_dmamap_destroy(sc->sc_dmat,
			    sc->sc_txsoft[i].ds_dmamap);
	}
	bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
 fail_3:
	bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
 fail_2:
	bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_cdata16, cdatasize);
 fail_1:
	bus_dmamem_free(sc->sc_dmat, &seg, rseg);
 fail_0:
	return;
}
コード例 #17
0
ファイル: if_de.c プロジェクト: avsm/openbsd-xen-sys
/*
 * Interface exists: make available by filling in network interface
 * record.  System will initialize the interface when it is ready
 * to accept packets.  We get the ethernet address here.
 */
void
deattach(struct device *parent, struct device *self, void *aux)
{
	struct uba_attach_args *ua = aux;
	struct de_softc *sc = (struct de_softc *)self;
	struct ifnet *ifp = &sc->sc_if;
	u_int8_t myaddr[ETHER_ADDR_LEN];
	int csr1, error;
	char *c;

	sc->sc_iot = ua->ua_iot;
	sc->sc_ioh = ua->ua_ioh;
	sc->sc_dmat = ua->ua_dmat;

	/*
	 * What kind of a board is this?
	 * The error bits 4-6 in pcsr1 are a device id as long as
	 * the high byte is zero.
	 */
	csr1 = DE_RCSR(DE_PCSR1);
	if (csr1 & 0xff60)
		c = "broken";
	else if (csr1 & 0x10)
		c = "delua";
	else
		c = "deuna";

	/*
	 * Reset the board and temporarily map
	 * the pcbb buffer onto the Unibus.
	 */
	DE_WCSR(DE_PCSR0, 0);		/* reset INTE */
	DELAY(100);
	DE_WCSR(DE_PCSR0, PCSR0_RSET);
	dewait(sc, "reset");

	sc->sc_ui.ui_size = sizeof(struct de_cdata);
	if ((error = ubmemalloc((struct uba_softc *)parent, &sc->sc_ui, 0)))
		return printf(": failed ubmemalloc(), error = %d\n", error);
	sc->sc_dedata = (struct de_cdata *)sc->sc_ui.ui_vaddr;

	/*
	 * Tell the DEUNA about our PCB
	 */
	DE_WCSR(DE_PCSR2, LOWORD(sc->sc_ui.ui_baddr));
	DE_WCSR(DE_PCSR3, HIWORD(sc->sc_ui.ui_baddr));
	DE_WLOW(CMD_GETPCBB);
	dewait(sc, "pcbb");

	sc->sc_dedata->dc_pcbb.pcbb0 = FC_RDPHYAD;
	DE_WLOW(CMD_GETCMD);
	dewait(sc, "read addr ");

	bcopy((caddr_t)&sc->sc_dedata->dc_pcbb.pcbb2, myaddr, sizeof (myaddr));
	printf(": %s, address %s\n", c, ether_sprintf(myaddr));

	uba_intr_establish(ua->ua_icookie, ua->ua_cvec, deintr, sc, 
	    &sc->sc_intrcnt);
	uba_reset_establish(dereset, &sc->sc_dev);
	evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, ua->ua_evcnt,
	    sc->sc_dev.dv_xname, "intr");

	strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, sizeof ifp->if_xname);
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI;
	ifp->if_ioctl = deioctl;
	ifp->if_start = destart;
	ifp->if_init = deinit;
	ifp->if_stop = destop;
	IFQ_SET_READY(&ifp->if_snd);

	if_attach(ifp);
	ether_ifattach(ifp, myaddr);
	ubmemfree((struct uba_softc *)parent, &sc->sc_ui);

	sc->sc_sh = shutdownhook_establish(deshutdown, sc);
}
コード例 #18
0
static void
ste_attach(device_t parent, device_t self, void *aux)
{
	struct ste_softc *sc = device_private(self);
	struct pci_attach_args *pa = aux;
	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
	pci_chipset_tag_t pc = pa->pa_pc;
	pci_intr_handle_t ih;
	const char *intrstr = NULL;
	bus_space_tag_t iot, memt;
	bus_space_handle_t ioh, memh;
	bus_dma_segment_t seg;
	int ioh_valid, memh_valid;
	int i, rseg, error;
	const struct ste_product *sp;
	uint8_t enaddr[ETHER_ADDR_LEN];
	uint16_t myea[ETHER_ADDR_LEN / 2];

	callout_init(&sc->sc_tick_ch, 0);

	sp = ste_lookup(pa);
	if (sp == NULL) {
		printf("\n");
		panic("ste_attach: impossible");
	}

	printf(": %s\n", sp->ste_name);

	/*
	 * Map the device.
	 */
	ioh_valid = (pci_mapreg_map(pa, STE_PCI_IOBA,
	    PCI_MAPREG_TYPE_IO, 0,
	    &iot, &ioh, NULL, NULL) == 0);
	memh_valid = (pci_mapreg_map(pa, STE_PCI_MMBA,
	    PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
	    &memt, &memh, NULL, NULL) == 0);

	if (memh_valid) {
		sc->sc_st = memt;
		sc->sc_sh = memh;
	} else if (ioh_valid) {
		sc->sc_st = iot;
		sc->sc_sh = ioh;
	} else {
		aprint_error_dev(&sc->sc_dev, "unable to map device registers\n");
		return;
	}

	sc->sc_dmat = pa->pa_dmat;

	/* Enable bus mastering. */
	pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
	    pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) |
	    PCI_COMMAND_MASTER_ENABLE);

	/* power up chip */
	if ((error = pci_activate(pa->pa_pc, pa->pa_tag, self,
	    NULL)) && error != EOPNOTSUPP) {
		aprint_error_dev(&sc->sc_dev, "cannot activate %d\n",
		    error);
		return;
	}

	/*
	 * Map and establish our interrupt.
	 */
	if (pci_intr_map(pa, &ih)) {
		aprint_error_dev(&sc->sc_dev, "unable to map interrupt\n");
		return;
	}
	intrstr = pci_intr_string(pc, ih);
	sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, ste_intr, sc);
	if (sc->sc_ih == NULL) {
		aprint_error_dev(&sc->sc_dev, "unable to establish interrupt");
		if (intrstr != NULL)
			printf(" at %s", intrstr);
		printf("\n");
		return;
	}
	printf("%s: interrupting at %s\n", device_xname(&sc->sc_dev), intrstr);

	/*
	 * Allocate the control data structures, and create and load the
	 * DMA map for it.
	 */
	if ((error = bus_dmamem_alloc(sc->sc_dmat,
	    sizeof(struct ste_control_data), PAGE_SIZE, 0, &seg, 1, &rseg,
	    0)) != 0) {
		aprint_error_dev(&sc->sc_dev, "unable to allocate control data, error = %d\n",
		    error);
		goto fail_0;
	}

	if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
	    sizeof(struct ste_control_data), (void **)&sc->sc_control_data,
	    BUS_DMA_COHERENT)) != 0) {
		aprint_error_dev(&sc->sc_dev, "unable to map control data, error = %d\n",
		    error);
		goto fail_1;
	}

	if ((error = bus_dmamap_create(sc->sc_dmat,
	    sizeof(struct ste_control_data), 1,
	    sizeof(struct ste_control_data), 0, 0, &sc->sc_cddmamap)) != 0) {
		aprint_error_dev(&sc->sc_dev, "unable to create control data DMA map, "
		    "error = %d\n", error);
		goto fail_2;
	}

	if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap,
	    sc->sc_control_data, sizeof(struct ste_control_data), NULL,
	    0)) != 0) {
		aprint_error_dev(&sc->sc_dev, "unable to load control data DMA map, error = %d\n",
		    error);
		goto fail_3;
	}

	/*
	 * Create the transmit buffer DMA maps.
	 */
	for (i = 0; i < STE_NTXDESC; i++) {
		if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
		    STE_NTXFRAGS, MCLBYTES, 0, 0,
		    &sc->sc_txsoft[i].ds_dmamap)) != 0) {
			aprint_error_dev(&sc->sc_dev, "unable to create tx DMA map %d, "
			    "error = %d\n", i, error);
			goto fail_4;
		}
	}

	/*
	 * Create the receive buffer DMA maps.
	 */
	for (i = 0; i < STE_NRXDESC; i++) {
		if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
		    MCLBYTES, 0, 0, &sc->sc_rxsoft[i].ds_dmamap)) != 0) {
			aprint_error_dev(&sc->sc_dev, "unable to create rx DMA map %d, "
			    "error = %d\n", i, error);
			goto fail_5;
		}
		sc->sc_rxsoft[i].ds_mbuf = NULL;
	}

	/*
	 * Reset the chip to a known state.
	 */
	ste_reset(sc, AC_GlobalReset | AC_RxReset | AC_TxReset | AC_DMA |
	    AC_FIFO | AC_Network | AC_Host | AC_AutoInit | AC_RstOut);

	/*
	 * Read the Ethernet address from the EEPROM.
	 */
	for (i = 0; i < 3; i++) {
		ste_read_eeprom(sc, STE_EEPROM_StationAddress0 + i, &myea[i]);
		myea[i] = le16toh(myea[i]);
	}
	memcpy(enaddr, myea, sizeof(enaddr));

	printf("%s: Ethernet address %s\n", device_xname(&sc->sc_dev),
	    ether_sprintf(enaddr));

	/*
	 * Initialize our media structures and probe the MII.
	 */
	sc->sc_mii.mii_ifp = ifp;
	sc->sc_mii.mii_readreg = ste_mii_readreg;
	sc->sc_mii.mii_writereg = ste_mii_writereg;
	sc->sc_mii.mii_statchg = ste_mii_statchg;
	sc->sc_ethercom.ec_mii = &sc->sc_mii;
	ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, ether_mediachange,
	    ether_mediastatus);
	mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
	    MII_OFFSET_ANY, 0);
	if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
		ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
	} else
		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);

	ifp = &sc->sc_ethercom.ec_if;
	strlcpy(ifp->if_xname, device_xname(&sc->sc_dev), IFNAMSIZ);
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_ioctl = ste_ioctl;
	ifp->if_start = ste_start;
	ifp->if_watchdog = ste_watchdog;
	ifp->if_init = ste_init;
	ifp->if_stop = ste_stop;
	IFQ_SET_READY(&ifp->if_snd);

	/*
	 * Default the transmit threshold to 128 bytes.
	 */
	sc->sc_txthresh = 128;

	/*
	 * Disable MWI if the PCI layer tells us to.
	 */
	sc->sc_DMACtrl = 0;
	if ((pa->pa_flags & PCI_FLAGS_MWI_OKAY) == 0)
		sc->sc_DMACtrl |= DC_MWIDisable;

	/*
	 * We can support 802.1Q VLAN-sized frames.
	 */
	sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;

	/*
	 * Attach the interface.
	 */
	if_attach(ifp);
	ether_ifattach(ifp, enaddr);

	/*
	 * Make sure the interface is shutdown during reboot.
	 */
	sc->sc_sdhook = shutdownhook_establish(ste_shutdown, sc);
	if (sc->sc_sdhook == NULL)
		printf("%s: WARNING: unable to establish shutdown hook\n",
		    device_xname(&sc->sc_dev));
	return;

	/*
	 * Free any resources we've allocated during the failed attach
	 * attempt.  Do this in reverse order and fall through.
	 */
 fail_5:
	for (i = 0; i < STE_NRXDESC; i++) {
		if (sc->sc_rxsoft[i].ds_dmamap != NULL)
			bus_dmamap_destroy(sc->sc_dmat,
			    sc->sc_rxsoft[i].ds_dmamap);
	}
 fail_4:
	for (i = 0; i < STE_NTXDESC; i++) {
		if (sc->sc_txsoft[i].ds_dmamap != NULL)
			bus_dmamap_destroy(sc->sc_dmat,
			    sc->sc_txsoft[i].ds_dmamap);
	}
	bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
 fail_3:
	bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
 fail_2:
	bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_control_data,
	    sizeof(struct ste_control_data));
 fail_1:
	bus_dmamem_free(sc->sc_dmat, &seg, rseg);
 fail_0:
	return;
}
コード例 #19
0
/*
 * Interface exists: make available by filling in network interface
 * record.  System will initialize the interface when it is ready
 * to accept packets.
 */
static void
niattach(device_t parent, device_t self, void *aux)
{
	struct bi_attach_args *ba = aux;
	struct ni_softc *sc = device_private(self);
	struct ifnet *ifp = (struct ifnet *)&sc->sc_if;
	struct ni_msg *msg;
	struct ni_ptdb *ptdb;
	void *va;
	int i, j, s, res;
	u_short type;

	sc->sc_dev = self;

	type = bus_space_read_2(ba->ba_iot, ba->ba_ioh, BIREG_DTYPE);
	printf(": DEBN%c\n", type == BIDT_DEBNA ? 'A' : type == BIDT_DEBNT ?
	    'T' : 'K');
	sc->sc_iot = ba->ba_iot;
	sc->sc_ioh = ba->ba_ioh;
	sc->sc_dmat = ba->ba_dmat;

	bi_intr_establish(ba->ba_icookie, ba->ba_ivec,
		niintr, sc, &sc->sc_intrcnt);
	evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
		device_xname(self), "intr");

	ni_getpgs(sc, sizeof(struct ni_gvppqb), (void **)&sc->sc_gvppqb,
	    (paddr_t *)&sc->sc_pgvppqb);
	ni_getpgs(sc, sizeof(struct ni_fqb), (void **)&sc->sc_fqb, 0);
	ni_getpgs(sc, NBDESCS * sizeof(struct ni_bbd),
	    (void **)&sc->sc_bbd, 0);
	/*
	 * Zero the newly allocated memory.
	 */

	nipqb->np_veclvl = (ba->ba_ivec << 2) + 2;
	nipqb->np_node = ba->ba_intcpu;
	nipqb->np_vpqb = (u_int32_t)gvp;
#ifdef __vax__
	nipqb->np_spt = nipqb->np_gpt = mfpr(PR_SBR);
	nipqb->np_sptlen = nipqb->np_gptlen = mfpr(PR_SLR);
#else
#error Must fix support for non-vax.
#endif
	nipqb->np_bvplvl = 1;
	nipqb->np_vfqb = (u_int32_t)fqb;
	nipqb->np_vbdt = (u_int32_t)bbd;
	nipqb->np_nbdr = NBDESCS;

	/* Free queue block */
	nipqb->np_freeq = NQUEUES;
	fqb->nf_mlen = PKTHDR+MSGADD;
	fqb->nf_dlen = PKTHDR+TXADD;
	fqb->nf_rlen = PKTHDR+RXADD;

	strlcpy(ifp->if_xname, device_xname(self), IFNAMSIZ);
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	ifp->if_start = nistart;
	ifp->if_ioctl = niioctl;
	ifp->if_watchdog = nitimeout;
	IFQ_SET_READY(&ifp->if_snd);

	/*
	 * Start init sequence.
	 */

	/* Reset the node */
	NI_WREG(BIREG_VAXBICSR, NI_RREG(BIREG_VAXBICSR) | BICSR_NRST);
	DELAY(500000);
	i = 20;
	while ((NI_RREG(BIREG_VAXBICSR) & BICSR_BROKE) && --i)
		DELAY(500000);
	if (i == 0) {
		printf("%s: BROKE bit set after reset\n", device_xname(self));
		return;
	}

	/* Check state */
	if (failtest(sc, NI_PSR, PSR_STATE, PSR_UNDEF, "not undefined state"))
		return;

	/* Clear owner bits */
	NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN);
	NI_WREG(NI_PCR, NI_RREG(NI_PCR) & ~PCR_OWN);

	/* kick off init */
	NI_WREG(NI_PCR, (u_int32_t)sc->sc_pgvppqb | PCR_INIT | PCR_OWN);
	while (NI_RREG(NI_PCR) & PCR_OWN)
		DELAY(100000);

	/* Check state */
	if (failtest(sc, NI_PSR, PSR_INITED, PSR_INITED, "failed initialize"))
		return;

	NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN);

	WAITREG(NI_PCR, PCR_OWN);
	NI_WREG(NI_PCR, PCR_OWN|PCR_ENABLE);
	WAITREG(NI_PCR, PCR_OWN);
	WAITREG(NI_PSR, PSR_OWN);

	/* Check state */
	if (failtest(sc, NI_PSR, PSR_STATE, PSR_ENABLED, "failed enable"))
		return;

	NI_WREG(NI_PSR, NI_RREG(NI_PSR) & ~PSR_OWN);

	/*
	 * The message queue packets must be located on the beginning
	 * of a page. A VAX page is 512 bytes, but it clusters 8 pages.
	 * This knowledge is used here when allocating pages.
	 * !!! How should this be done on MIPS and Alpha??? !!!
	 */
#if NBPG < 4096
#error pagesize too small
#endif
	s = splvm();
	/* Set up message free queue */
	ni_getpgs(sc, NMSGBUF * 512, &va, 0);
	for (i = 0; i < NMSGBUF; i++) {
		msg = (void *)((char *)va + i * 512);
		res = INSQTI(msg, &fqb->nf_mforw);
	}
	WAITREG(NI_PCR, PCR_OWN);
	NI_WREG(NI_PCR, PCR_FREEQNE|PCR_MFREEQ|PCR_OWN);
	WAITREG(NI_PCR, PCR_OWN);

	/* Set up xmit queue */
	ni_getpgs(sc, NTXBUF * 512, &va, 0);
	for (i = 0; i < NTXBUF; i++) {
		struct ni_dg *data;

		data = (void *)((char *)va + i * 512);
		data->nd_status = 0;
		data->nd_len = TXADD;
		data->nd_ptdbidx = 1;
		data->nd_opcode = BVP_DGRAM;
		for (j = 0; j < NTXFRAGS; j++) {
			data->bufs[j]._offset = 0;
			data->bufs[j]._key = 1;
			bbd[i * NTXFRAGS + j].nb_key = 1;
			bbd[i * NTXFRAGS + j].nb_status = 0;
			data->bufs[j]._index = i * NTXFRAGS + j;
		}
		res = INSQTI(data, &fqb->nf_dforw);
	}
	WAITREG(NI_PCR, PCR_OWN);
	NI_WREG(NI_PCR, PCR_FREEQNE|PCR_DFREEQ|PCR_OWN);
	WAITREG(NI_PCR, PCR_OWN);

	/* recv buffers */
	ni_getpgs(sc, NRXBUF * 512, &va, 0);
	for (i = 0; i < NRXBUF; i++) {
		struct ni_dg *data;
		int idx;

		data = (void *)((char *)va + i * 512);
		data->nd_len = RXADD;
		data->nd_opcode = BVP_DGRAMRX;
		data->nd_ptdbidx = 2;
		data->bufs[0]._key = 1;

		idx = NTXBUF * NTXFRAGS + i;
		if (ni_add_rxbuf(sc, data, idx))
			panic("niattach: ni_add_rxbuf: out of mbufs");

		res = INSQTI(data, &fqb->nf_rforw);
	}
	WAITREG(NI_PCR, PCR_OWN);
	NI_WREG(NI_PCR, PCR_FREEQNE|PCR_RFREEQ|PCR_OWN);
	WAITREG(NI_PCR, PCR_OWN);

	splx(s);

	/* Set initial parameters */
	msg = REMQHI(&fqb->nf_mforw);

	msg->nm_opcode = BVP_MSG;
	msg->nm_status = 0;
	msg->nm_len = sizeof(struct ni_param) + 6;
	msg->nm_opcode2 = NI_WPARAM;
	((struct ni_param *)&msg->nm_text[0])->np_flags = NP_PAD;

	endwait = retry = 0;
	res = INSQTI(msg, &gvp->nc_forw0);

retry:	WAITREG(NI_PCR, PCR_OWN);
	NI_WREG(NI_PCR, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
	WAITREG(NI_PCR, PCR_OWN);
	i = 1000;
	while (endwait == 0 && --i)
		DELAY(10000);

	if (endwait == 0) {
		if (++retry < 3)
			goto retry;
		printf("%s: no response to set params\n", device_xname(self));
		return;
	}

	/* Clear counters */
	msg = REMQHI(&fqb->nf_mforw);
	msg->nm_opcode = BVP_MSG;
	msg->nm_status = 0;
	msg->nm_len = sizeof(struct ni_param) + 6;
	msg->nm_opcode2 = NI_RCCNTR;

	res = INSQTI(msg, &gvp->nc_forw0);

	WAITREG(NI_PCR, PCR_OWN);
	NI_WREG(NI_PCR, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
	WAITREG(NI_PCR, PCR_OWN);

	/* Enable transmit logic */
	msg = REMQHI(&fqb->nf_mforw);

	msg->nm_opcode = BVP_MSG;
	msg->nm_status = 0;
	msg->nm_len = 18;
	msg->nm_opcode2 = NI_STPTDB;
	ptdb = (struct ni_ptdb *)&msg->nm_text[0];
	memset(ptdb, 0, sizeof(struct ni_ptdb));
	ptdb->np_index = 1;
	ptdb->np_fque = 1;

	res = INSQTI(msg, &gvp->nc_forw0);

	WAITREG(NI_PCR, PCR_OWN);
	NI_WREG(NI_PCR, PCR_CMDQNE|PCR_CMDQ0|PCR_OWN);
	WAITREG(NI_PCR, PCR_OWN);

	/* Wait for everything to finish */
	WAITREG(NI_PSR, PSR_OWN);

	printf("%s: hardware address %s\n", device_xname(self),
	    ether_sprintf(sc->sc_enaddr));

	/*
	 * Attach the interface.
	 */
	if_attach(ifp);
	ether_ifattach(ifp, sc->sc_enaddr);
	if (shutdownhook_establish(ni_shutdown, sc) == 0)
		aprint_error_dev(self, "WARNING: unable to establish shutdown hook\n");
}
コード例 #20
0
ファイル: sab.c プロジェクト: lacombar/netbsd-alc
void
sabtty_attach(struct device *parent, struct device *self, void *aux)
{
	struct sabtty_softc *sc = (struct sabtty_softc *)self;
	struct sabtty_attach_args *sa = aux;
	int r;
	int maj;
	int is_kgdb = 0;

#ifdef KGDB
	is_kgdb = sab_kgdb_check(sc);
#endif

	if (!is_kgdb) {
		sc->sc_tty = ttymalloc();
		if (sc->sc_tty == NULL) {
			aprint_normal(": failed to allocate tty\n");
			return;
		}
		tty_attach(sc->sc_tty);
		sc->sc_tty->t_oproc = sabtty_start;
		sc->sc_tty->t_param = sabtty_param;
	}

	sc->sc_parent = (struct sab_softc *)parent;
	sc->sc_bt = sc->sc_parent->sc_bt;
	sc->sc_portno = sa->sbt_portno;
	sc->sc_rend = sc->sc_rbuf + SABTTY_RBUF_SIZE;

	switch (sa->sbt_portno) {
	case 0:	/* port A */
		sc->sc_pvr_dtr = SAB_PVR_DTR_A;
		sc->sc_pvr_dsr = SAB_PVR_DSR_A;
		r = bus_space_subregion(sc->sc_bt, sc->sc_parent->sc_bh,
		    SAB_CHAN_A, SAB_CHANLEN, &sc->sc_bh);
		break;
	case 1:	/* port B */
		sc->sc_pvr_dtr = SAB_PVR_DTR_B;
		sc->sc_pvr_dsr = SAB_PVR_DSR_B;
		r = bus_space_subregion(sc->sc_bt, sc->sc_parent->sc_bh,
		    SAB_CHAN_B, SAB_CHANLEN, &sc->sc_bh);
		break;
	default:
		aprint_normal(": invalid channel: %u\n", sa->sbt_portno);
		return;
	}
	if (r != 0) {
		aprint_normal(": failed to allocate register subregion\n");
		return;
	}

	sabtty_console_flags(sc);

	if (sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) {
		struct termios t;
		const char *acc;

		/* Let residual prom output drain */
		DELAY(100000);

		switch (sc->sc_flags & (SABTTYF_CONS_IN | SABTTYF_CONS_OUT)) {
		case SABTTYF_CONS_IN:
			acc = "input";
			break;
		case SABTTYF_CONS_OUT:
			acc = "output";
			break;
		case SABTTYF_CONS_IN|SABTTYF_CONS_OUT:
		default:
			acc = "i/o";
			break;
		}

		t.c_ispeed= 0;
		t.c_ospeed = 9600;
		t.c_cflag = CREAD | CS8 | HUPCL;
		sc->sc_tty->t_ospeed = 0;
		sabttyparam(sc, sc->sc_tty, &t);

		if (sc->sc_flags & SABTTYF_CONS_IN) {
			sabtty_cons_input = sc;
			cn_tab->cn_pollc = sab_cnpollc;
			cn_tab->cn_getc = sab_cngetc;
			maj = cdevsw_lookup_major(&sabtty_cdevsw);
			cn_tab->cn_dev = makedev(maj, device_unit(self));
			shutdownhook_establish(sabtty_shutdown, sc);
			cn_init_magic(&sabtty_cnm_state);
			cn_set_magic("\047\001"); /* default magic is BREAK */
		}

		if (sc->sc_flags & SABTTYF_CONS_OUT) {
			sabtty_tec_wait(sc);
			sabtty_cons_output = sc;
			cn_tab->cn_putc = sab_cnputc;
			maj = cdevsw_lookup_major(&sabtty_cdevsw);
			cn_tab->cn_dev = makedev(maj, device_unit(self));
		}
		aprint_normal(": console %s", acc);
	} else {
		/* Not a console... */
		sabtty_reset(sc);

#ifdef KGDB
		if (is_kgdb) {
			sab_kgdb_init(sc);
			aprint_normal(": kgdb");
		}
#endif
	}

	aprint_normal("\n");
}
コード例 #21
0
ファイル: gtmpsc.c プロジェクト: ryo/netbsd-src
/* ARGSUSED */
STATIC void
gtmpscattach(device_t parent, device_t self, void *aux)
{
	struct gtmpsc_softc *sc = device_private(self);
	struct marvell_attach_args *mva = aux;
	bus_dma_segment_t segs;
	struct tty *tp;
	int rsegs, err, unit;
	void *kva;

	aprint_naive("\n");
	aprint_normal(": Multi-Protocol Serial Controller\n");

	if (mva->mva_unit != MVA_UNIT_DEFAULT)
		unit = mva->mva_unit;
	else
		unit = (mva->mva_offset == GTMPSC_BASE(0)) ? 0 : 1;

#ifdef MPSC_CONSOLE
	if (cn_tab == &gtmpsc_consdev &&
	    cn_tab->cn_dev == makedev(0, unit)) {
		gtmpsc_cn_softc.sc_dev = self;
		memcpy(sc, &gtmpsc_cn_softc, sizeof(struct gtmpsc_softc));
		sc->sc_flags = GTMPSC_CONSOLE;
	} else
#endif
	{
		if (bus_space_subregion(mva->mva_iot, mva->mva_ioh,
		    mva->mva_offset, mva->mva_size, &sc->sc_mpsch)) {
			aprint_error_dev(self, "Cannot map MPSC registers\n");
			return;
		}
		if (bus_space_subregion(mva->mva_iot, mva->mva_ioh,
		    GTSDMA_BASE(unit), GTSDMA_SIZE, &sc->sc_sdmah)) {
			aprint_error_dev(self, "Cannot map SDMA registers\n");
			return;
		}
		sc->sc_dev = self;
		sc->sc_unit = unit;
		sc->sc_iot = mva->mva_iot;
		sc->sc_dmat = mva->mva_dmat;

		err = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE, 0,
		    &segs, 1, &rsegs, BUS_DMA_NOWAIT);
		if (err) {
			aprint_error_dev(sc->sc_dev,
			    "bus_dmamem_alloc error 0x%x\n", err);
			goto fail0;
		}
		err = bus_dmamem_map(sc->sc_dmat, &segs, 1, PAGE_SIZE, &kva,
		    BUS_DMA_NOWAIT);
		if (err) {
			aprint_error_dev(sc->sc_dev,
			    "bus_dmamem_map error 0x%x\n", err);
			goto fail1;
		}
		memset(kva, 0, PAGE_SIZE);	/* paranoid/superfluous */
		sc->sc_poll_sdmapage = kva;

		err = bus_dmamap_create(sc->sc_dmat, sizeof(gtmpsc_polltx_t), 1,
		   sizeof(gtmpsc_polltx_t), 0, BUS_DMA_NOWAIT,
		   &sc->sc_txdma_map);
		if (err != 0) {
			aprint_error_dev(sc->sc_dev,
			    "bus_dmamap_create error 0x%x\n", err);
			goto fail2;
		}
		err = bus_dmamap_load(sc->sc_dmat, sc->sc_txdma_map,
		    sc->sc_poll_sdmapage->tx, sizeof(gtmpsc_polltx_t),
		    NULL, BUS_DMA_NOWAIT | BUS_DMA_READ | BUS_DMA_WRITE);
		if (err != 0) {
			aprint_error_dev(sc->sc_dev,
			    "bus_dmamap_load tx error 0x%x\n", err);
			goto fail3;
		}
		err = bus_dmamap_create(sc->sc_dmat, sizeof(gtmpsc_pollrx_t), 1,
		   sizeof(gtmpsc_pollrx_t), 0, BUS_DMA_NOWAIT,
		   &sc->sc_rxdma_map);
		if (err != 0) {
			aprint_error_dev(sc->sc_dev,
			    "bus_dmamap_create rx error 0x%x\n", err);
			goto fail4;
		}
		err = bus_dmamap_load(sc->sc_dmat, sc->sc_rxdma_map,
		    sc->sc_poll_sdmapage->rx, sizeof(gtmpsc_pollrx_t),
		    NULL, BUS_DMA_NOWAIT | BUS_DMA_READ | BUS_DMA_WRITE);
		if (err != 0) {
			aprint_error_dev(sc->sc_dev,
			    "bus_dmamap_load rx error 0x%x\n", err);
			goto fail5;
		}

		sc->sc_brg = unit;		/* XXXXX */
		sc->sc_baudrate = GT_MPSC_DEFAULT_BAUD_RATE;
	}
	aprint_normal_dev(self, "with SDMA offset 0x%04x-0x%04x\n",
	    GTSDMA_BASE(unit), GTSDMA_BASE(unit) + GTSDMA_SIZE - 1);

	sc->sc_rx_ready = 0;
	sc->sc_tx_busy = 0;
	sc->sc_tx_done = 0;
	sc->sc_tx_stopped = 0;
	sc->sc_heldchange = 0;

	gtmpsc_txdesc_init(sc);
	gtmpsc_rxdesc_init(sc);

	sc->sc_tty = tp = tty_alloc();
	tp->t_oproc = gtmpscstart;
	tp->t_param = gtmpscparam;
	tty_attach(tp);

	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_HIGH);

	/*
	 * clear any pending SDMA interrupts for this unit
	 */
	(void) gt_sdma_icause(device_parent(sc->sc_dev),
	    SDMA_INTR_RXBUF(sc->sc_unit) |
	    SDMA_INTR_RXERR(sc->sc_unit) |
	    SDMA_INTR_TXBUF(sc->sc_unit) |
	    SDMA_INTR_TXEND(sc->sc_unit));

	sc->sc_si = softint_establish(SOFTINT_SERIAL, gtmpsc_softintr, sc);
	if (sc->sc_si == NULL)
		panic("mpscattach: cannot softint_establish IPL_SOFTSERIAL");

	shutdownhook_establish(gtmpsc_shutdownhook, sc);

	gtmpscinit_stop(sc);
	gtmpscinit_start(sc);

	if (sc->sc_flags & GTMPSC_CONSOLE) {
		int maj;

		/* locate the major number */
		maj = cdevsw_lookup_major(&gtmpsc_cdevsw);

		tp->t_dev = cn_tab->cn_dev =
		    makedev(maj, device_unit(sc->sc_dev));

		aprint_normal_dev(self, "console\n");
	}

#ifdef KGDB
	/*
	 * Allow kgdb to "take over" this port.  If this is
	 * the kgdb device, it has exclusive use.
	 */
	if (sc->sc_unit == gtmpsckgdbport) {
#ifdef MPSC_CONSOLE
		if (sc->sc_unit == MPSC_CONSOLE) {
			aprint_error_dev(self,
			    "(kgdb): cannot share with console\n");
			return;
		}
#endif

		sc->sc_flags |= GTMPSC_KGDB;
		aprint_normal_dev(self, "kgdb\n");

		gtmpsc_txflush(sc);

		kgdb_attach(gtmpsc_kgdb_getc, gtmpsc_kgdb_putc, NULL);
		kgdb_dev = 123;	/* unneeded, only to satisfy some tests */
		gtmpsc_kgdb_attached = 1;
		kgdb_connect(1);
	}
#endif /* KGDB */

	return;


fail5:
	bus_dmamap_destroy(sc->sc_dmat, sc->sc_rxdma_map);
fail4:
	bus_dmamap_unload(sc->sc_dmat, sc->sc_txdma_map);
fail3:
	bus_dmamap_destroy(sc->sc_dmat, sc->sc_txdma_map);
fail2:
	bus_dmamem_unmap(sc->sc_dmat, kva, PAGE_SIZE);
fail1:
	bus_dmamem_free(sc->sc_dmat, &segs, 1);
fail0:
	return;
}
コード例 #22
0
ファイル: if_cas.c プロジェクト: repos-holder/openbsd-patches
/*
 * cas_config:
 *
 *	Attach a Cassini interface to the system.
 */
void
cas_config(struct cas_softc *sc)
{
	struct ifnet *ifp = &sc->sc_arpcom.ac_if;
	struct mii_data *mii = &sc->sc_mii;
	struct mii_softc *child;
	int i, error;

	/* Make sure the chip is stopped. */
	ifp->if_softc = sc;
	cas_reset(sc);

	/*
	 * Allocate the control data structures, and create and load the
	 * DMA map for it.
	 */
	if ((error = bus_dmamem_alloc(sc->sc_dmatag,
	    sizeof(struct cas_control_data), CAS_PAGE_SIZE, 0, &sc->sc_cdseg,
	    1, &sc->sc_cdnseg, 0)) != 0) {
		printf("\n%s: unable to allocate control data, error = %d\n",
		    sc->sc_dev.dv_xname, error);
		goto fail_0;
	}

	/* XXX should map this in with correct endianness */
	if ((error = bus_dmamem_map(sc->sc_dmatag, &sc->sc_cdseg, sc->sc_cdnseg,
	    sizeof(struct cas_control_data), (caddr_t *)&sc->sc_control_data,
	    BUS_DMA_COHERENT)) != 0) {
		printf("\n%s: unable to map control data, error = %d\n",
		    sc->sc_dev.dv_xname, error);
		goto fail_1;
	}

	if ((error = bus_dmamap_create(sc->sc_dmatag,
	    sizeof(struct cas_control_data), 1,
	    sizeof(struct cas_control_data), 0, 0, &sc->sc_cddmamap)) != 0) {
		printf("\n%s: unable to create control data DMA map, "
		    "error = %d\n", sc->sc_dev.dv_xname, error);
		goto fail_2;
	}

	if ((error = bus_dmamap_load(sc->sc_dmatag, sc->sc_cddmamap,
	    sc->sc_control_data, sizeof(struct cas_control_data), NULL,
	    0)) != 0) {
		printf("\n%s: unable to load control data DMA map, error = %d\n",
		    sc->sc_dev.dv_xname, error);
		goto fail_3;
	}

	bzero(sc->sc_control_data, sizeof(struct cas_control_data));

	/*
	 * Create the receive buffer DMA maps.
	 */
	for (i = 0; i < CAS_NRXDESC; i++) {
		bus_dma_segment_t seg;
		caddr_t kva;
		int rseg;

		if ((error = bus_dmamem_alloc(sc->sc_dmatag, CAS_PAGE_SIZE,
		    CAS_PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
			printf("\n%s: unable to alloc rx DMA mem %d, "
			    "error = %d\n", sc->sc_dev.dv_xname, i, error);
			goto fail_5;
		}
		sc->sc_rxsoft[i].rxs_dmaseg = seg;

		if ((error = bus_dmamem_map(sc->sc_dmatag, &seg, rseg,
		    CAS_PAGE_SIZE, &kva, BUS_DMA_NOWAIT)) != 0) {
			printf("\n%s: unable to alloc rx DMA mem %d, "
			    "error = %d\n", sc->sc_dev.dv_xname, i, error);
			goto fail_5;
		}
		sc->sc_rxsoft[i].rxs_kva = kva;

		if ((error = bus_dmamap_create(sc->sc_dmatag, CAS_PAGE_SIZE, 1,
		    CAS_PAGE_SIZE, 0, 0, &sc->sc_rxsoft[i].rxs_dmamap)) != 0) {
			printf("\n%s: unable to create rx DMA map %d, "
			    "error = %d\n", sc->sc_dev.dv_xname, i, error);
			goto fail_5;
		}

		if ((error = bus_dmamap_load(sc->sc_dmatag,
		   sc->sc_rxsoft[i].rxs_dmamap, kva, CAS_PAGE_SIZE, NULL,
		   BUS_DMA_NOWAIT)) != 0) {
			printf("\n%s: unable to load rx DMA map %d, "
			    "error = %d\n", sc->sc_dev.dv_xname, i, error);
			goto fail_5;
		}
	}

	/*
	 * Create the transmit buffer DMA maps.
	 */
	for (i = 0; i < CAS_NTXDESC; i++) {
		if ((error = bus_dmamap_create(sc->sc_dmatag, MCLBYTES,
		    CAS_NTXSEGS, MCLBYTES, 0, BUS_DMA_NOWAIT,
		    &sc->sc_txd[i].sd_map)) != 0) {
			printf("\n%s: unable to create tx DMA map %d, "
			    "error = %d\n", sc->sc_dev.dv_xname, i, error);
			goto fail_6;
		}
		sc->sc_txd[i].sd_mbuf = NULL;
	}

	/*
	 * From this point forward, the attachment cannot fail.  A failure
	 * before this point releases all resources that may have been
	 * allocated.
	 */

	/* Announce ourselves. */
	printf(", address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));

	/* Get RX FIFO size */
	sc->sc_rxfifosize = 16 * 1024;

	/* Initialize ifnet structure. */
	strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, sizeof ifp->if_xname);
	ifp->if_softc = sc;
	ifp->if_flags =
	    IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
	ifp->if_start = cas_start;
	ifp->if_ioctl = cas_ioctl;
	ifp->if_watchdog = cas_watchdog;
	IFQ_SET_MAXLEN(&ifp->if_snd, CAS_NTXDESC - 1);
	IFQ_SET_READY(&ifp->if_snd);

	ifp->if_capabilities = IFCAP_VLAN_MTU;

	/* Initialize ifmedia structures and MII info */
	mii->mii_ifp = ifp;
	mii->mii_readreg = cas_mii_readreg;
	mii->mii_writereg = cas_mii_writereg;
	mii->mii_statchg = cas_mii_statchg;

	ifmedia_init(&mii->mii_media, 0, cas_mediachange, cas_mediastatus);

	bus_space_write_4(sc->sc_memt, sc->sc_memh, CAS_MII_DATAPATH_MODE, 0);

	cas_mifinit(sc);

	if (sc->sc_mif_config & CAS_MIF_CONFIG_MDI1) {
		sc->sc_mif_config |= CAS_MIF_CONFIG_PHY_SEL;
		bus_space_write_4(sc->sc_memt, sc->sc_memh,
	            CAS_MIF_CONFIG, sc->sc_mif_config);
	}

	mii_attach(&sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY,
	    MII_OFFSET_ANY, 0);

	child = LIST_FIRST(&mii->mii_phys);
	if (child == NULL &&
	    sc->sc_mif_config & (CAS_MIF_CONFIG_MDI0|CAS_MIF_CONFIG_MDI1)) {
		/* 
		 * Try the external PCS SERDES if we didn't find any
		 * MII devices.
		 */
		bus_space_write_4(sc->sc_memt, sc->sc_memh,
		    CAS_MII_DATAPATH_MODE, CAS_MII_DATAPATH_SERDES);

		bus_space_write_4(sc->sc_memt, sc->sc_memh,
		     CAS_MII_CONFIG, CAS_MII_CONFIG_ENABLE);

		mii->mii_readreg = cas_pcs_readreg;
		mii->mii_writereg = cas_pcs_writereg;

		mii_attach(&sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY,
		    MII_OFFSET_ANY, MIIF_NOISOLATE);
	}

	child = LIST_FIRST(&mii->mii_phys);
	if (child == NULL) {
		/* No PHY attached */
		ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
		ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
	} else {
		/*
		 * Walk along the list of attached MII devices and
		 * establish an `MII instance' to `phy number'
		 * mapping. We'll use this mapping in media change
		 * requests to determine which phy to use to program
		 * the MIF configuration register.
		 */
		for (; child != NULL; child = LIST_NEXT(child, mii_list)) {
			/*
			 * Note: we support just two PHYs: the built-in
			 * internal device and an external on the MII
			 * connector.
			 */
			if (child->mii_phy > 1 || child->mii_inst > 1) {
				printf("%s: cannot accommodate MII device %s"
				       " at phy %d, instance %d\n",
				       sc->sc_dev.dv_xname,
				       child->mii_dev.dv_xname,
				       child->mii_phy, child->mii_inst);
				continue;
			}

			sc->sc_phys[child->mii_inst] = child->mii_phy;
		}

		/*
		 * XXX - we can really do the following ONLY if the
		 * phy indeed has the auto negotiation capability!!
		 */
		ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_AUTO);
	}

	/* Attach the interface. */
	if_attach(ifp);
	ether_ifattach(ifp);

	sc->sc_sh = shutdownhook_establish(cas_shutdown, sc);
	if (sc->sc_sh == NULL)
		panic("cas_config: can't establish shutdownhook");

	timeout_set(&sc->sc_tick_ch, cas_tick, sc);
	return;

	/*
	 * Free any resources we've allocated during the failed attach
	 * attempt.  Do this in reverse order and fall through.
	 */
 fail_6:
	for (i = 0; i < CAS_NTXDESC; i++) {
		if (sc->sc_txd[i].sd_map != NULL)
			bus_dmamap_destroy(sc->sc_dmatag,
			    sc->sc_txd[i].sd_map);
	}
 fail_5:
	for (i = 0; i < CAS_NRXDESC; i++) {
		if (sc->sc_rxsoft[i].rxs_dmamap != NULL)
			bus_dmamap_destroy(sc->sc_dmatag,
			    sc->sc_rxsoft[i].rxs_dmamap);
	}
	bus_dmamap_unload(sc->sc_dmatag, sc->sc_cddmamap);
 fail_3:
	bus_dmamap_destroy(sc->sc_dmatag, sc->sc_cddmamap);
 fail_2:
	bus_dmamem_unmap(sc->sc_dmatag, (caddr_t)sc->sc_control_data,
	    sizeof(struct cas_control_data));
 fail_1:
	bus_dmamem_free(sc->sc_dmatag, &sc->sc_cdseg, sc->sc_cdnseg);
 fail_0:
	return;
}
コード例 #23
0
ファイル: cgtwelve.c プロジェクト: avsm/openbsd-xen-sys
void
cgtwelveattach(struct device *parent, struct device *self, void *args)
{
	struct cgtwelve_softc *sc = (struct cgtwelve_softc *)self;
	struct confargs *ca = args;
	int node;
	int isconsole = 0;
	char *ps;

	node = ca->ca_ra.ra_node;

	printf(": %s", getpropstring(node, "model"));
	ps = getpropstring(node, "dev_id");
	if (*ps != '\0')
		printf(" (%s)", ps);
	printf("\n");

	isconsole = node == fbnode;

	sc->sc_phys = ca->ca_ra.ra_reg[0];

	/*
	 * Map registers
	 */
	sc->sc_dpu = (struct cgtwelve_dpu *)mapiodev(ca->ca_ra.ra_reg,
	    CG12_OFF_DPU, sizeof(struct cgtwelve_dpu));
	sc->sc_apu = (struct cgtwelve_apu *)mapiodev(ca->ca_ra.ra_reg,
	    CG12_OFF_APU, sizeof(struct cgtwelve_apu));
	sc->sc_ramdac = (struct cgtwelve_dac *)mapiodev(ca->ca_ra.ra_reg,
	    CG12_OFF_DAC, sizeof(struct cgtwelve_dac));

	/*
	 * The console is using the 1-bit overlay plane, while the prom
	 * will correctly report 32 bit depth.
	 */
	fb_setsize(&sc->sc_sunfb, 1, CG12_WIDTH, CG12_HEIGHT,
	    node, ca->ca_bustype);
	sc->sc_sunfb.sf_depth = 1;
	sc->sc_sunfb.sf_linebytes = sc->sc_sunfb.sf_width / 8;
	sc->sc_sunfb.sf_fbsize = sc->sc_sunfb.sf_height *
	    sc->sc_sunfb.sf_linebytes;

	sc->sc_highres = sc->sc_sunfb.sf_width == CG12_WIDTH_HR;

	/*
	 * Map planes
	 */
	sc->sc_overlay = mapiodev(ca->ca_ra.ra_reg,
	    sc->sc_highres ? CG12_OFF_OVERLAY0_HR : CG12_OFF_OVERLAY0,
	    round_page(sc->sc_highres ? CG12_SIZE_OVERLAY_HR :
	        CG12_SIZE_OVERLAY));
	sc->sc_inten = mapiodev(ca->ca_ra.ra_reg,
	    sc->sc_highres ? CG12_OFF_INTEN_HR : CG12_OFF_INTEN,
	    round_page(sc->sc_highres ? CG12_SIZE_COLOR24_HR :
	        CG12_SIZE_COLOR24));

	/* reset cursor & frame buffer controls */
	sc->sc_sunfb.sf_depth = 0;	/* force action */
	cgtwelve_reset(sc, 1);

	sc->sc_sunfb.sf_ro.ri_bits = (void *)sc->sc_overlay;
	sc->sc_sunfb.sf_ro.ri_hw = sc;
	fbwscons_init(&sc->sc_sunfb, isconsole ? 0 : RI_CLEAR);

	if (isconsole) {
		fbwscons_console_init(&sc->sc_sunfb, -1);
		shutdownhook_establish(cgtwelve_prom, sc);
	}

	printf("%s: %dx%d", self->dv_xname,
	    sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);
	ps = getpropstring(node, "ucoderev");
	if (*ps != '\0')
		printf(", microcode rev. %s", ps);
	printf("\n");

	fbwscons_attach(&sc->sc_sunfb, &cgtwelve_accessops, isconsole);
}
コード例 #24
0
static void
lmc_pci_attach(struct device * const parent,
		struct device * const self, void * const aux)
{
	u_int32_t revinfo, cfdainfo, id, ssid;
	pci_intr_handle_t intrhandle;
	const char *intrstr;
	unsigned csroffset = LMC_PCI_CSROFFSET;
	unsigned csrsize = LMC_PCI_CSRSIZE;
	lmc_csrptr_t csr_base;
	lmc_spl_t s;
	lmc_intrfunc_t (*intr_rtn)(void *) = lmc_intr_normal;
	lmc_softc_t * const sc = (lmc_softc_t *) self;
	struct pci_attach_args * const pa = (struct pci_attach_args *) aux;
	extern lmc_media_t lmc_hssi_media;
	extern lmc_media_t lmc_ds3_media;
	extern lmc_media_t lmc_t1_media;
	extern lmc_media_t lmc_ssi_media;

	revinfo  = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CFRV) & 0xFF;
	id       = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CFID);
	cfdainfo = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CFDA);
	ssid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SSID);

	switch (PCI_CHIPID(ssid)) {
	case PCI_PRODUCT_LMC_HSSI:
		printf(": HSSI\n");
		sc->lmc_media = &lmc_hssi_media;
		break;
	case PCI_PRODUCT_LMC_HSSIC:
		printf(": HSSIc\n");
		sc->lmc_media = &lmc_hssi_media;
		break;
	case PCI_PRODUCT_LMC_DS3:
		printf(": DS3\n");
		sc->lmc_media = &lmc_ds3_media;
		break;
	case PCI_PRODUCT_LMC_SSI:
		printf(": SSI\n");
		sc->lmc_media = &lmc_ssi_media;
		break;
	case PCI_PRODUCT_LMC_DS1:
		printf(": T1\n");
		sc->lmc_media = &lmc_t1_media;
		break;
	}

        sc->lmc_pci_busno = parent;
        sc->lmc_pci_devno = pa->pa_device;

	sc->lmc_chipid = LMC_21140A;
	sc->lmc_features |= LMC_HAVE_STOREFWD;
	if (sc->lmc_chipid == LMC_21140A && revinfo <= 0x22)
		sc->lmc_features |= LMC_HAVE_RXBADOVRFLW;

	if (cfdainfo & (TULIP_CFDA_SLEEP | TULIP_CFDA_SNOOZE)) {
		cfdainfo &= ~(TULIP_CFDA_SLEEP | TULIP_CFDA_SNOOZE);
		pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_CFDA, cfdainfo);
		DELAY(11 * 1000);
	}

	bcopy(self->dv_xname, sc->lmc_if.if_xname, IFNAMSIZ);
	sc->lmc_if.if_softc = sc;
	sc->lmc_pc = pa->pa_pc;

	sc->lmc_revinfo = revinfo;
	sc->lmc_if.if_softc = sc;

	csr_base = 0;
	{
		bus_space_tag_t iot, memt;
		bus_space_handle_t ioh, memh;
		int ioh_valid, memh_valid;

		ioh_valid = (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO,
		    0, &iot, &ioh, NULL, NULL, 0) == 0);
		memh_valid = (pci_mapreg_map(pa, PCI_CBMA,
		    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &memt,
		    &memh, NULL, NULL, 0) == 0);

		if (memh_valid) {
			sc->lmc_bustag = memt;
			sc->lmc_bushandle = memh;
		} else if (ioh_valid) {
			sc->lmc_bustag = iot;
			sc->lmc_bushandle = ioh;
		} else {
			printf("%s: unable to map device registers\n",
			       sc->lmc_dev.dv_xname);
			return;
		}
	}

	sc->lmc_dmatag = pa->pa_dmat;
	if ((lmc_busdma_init(sc)) != 0) {
		printf("error initing bus_dma\n");
		return;
	}

	lmc_initcsrs(sc, csr_base + csroffset, csrsize);
	lmc_initring(sc, &sc->lmc_rxinfo, sc->lmc_rxdescs,
		       LMC_RXDESCS);
	lmc_initring(sc, &sc->lmc_txinfo, sc->lmc_txdescs,
		       LMC_TXDESCS);

	lmc_gpio_mkinput(sc, 0xff);
	sc->lmc_gpio = 0;  /* drive no signals yet */

	sc->lmc_media->defaults(sc);

	sc->lmc_media->set_link_status(sc, LMC_LINK_DOWN); /* down */

	/*
	 * Make sure there won't be any interrupts or such...
	 */
	LMC_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);

	/*
	 * Wait 10 microseconds (actually 50 PCI cycles but at 
	 * 33MHz that comes to two microseconds but wait a
	 * bit longer anyways)
	 */
	DELAY(100);

	lmc_read_macaddr(sc);

        if (pci_intr_map(pa, &intrhandle)) {
		 printf("%s: couldn't map interrupt\n",
			sc->lmc_dev.dv_xname);
		return;
	}
	intrstr = pci_intr_string(pa->pa_pc, intrhandle);

	sc->lmc_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_NET,
						intr_rtn, sc, self->dv_xname);

	if (sc->lmc_ih == NULL) {
		printf("%s: couldn't establish interrupt",
		       sc->lmc_dev.dv_xname);
		if (intrstr != NULL)
			printf(" at %s", intrstr);
		printf("\n");
		return;
	}

        printf("%s: pass %d.%d, serial " LMC_EADDR_FMT ", %s\n",
               sc->lmc_dev.dv_xname,
               (sc->lmc_revinfo & 0xF0) >> 4, sc->lmc_revinfo & 0x0F,
               LMC_EADDR_ARGS(sc->lmc_enaddr), intrstr);

        sc->lmc_ats = shutdownhook_establish(lmc_shutdown, sc);
        if (sc->lmc_ats == NULL)
		printf("%s: warning: couldn't establish shutdown hook\n",
		       sc->lmc_xname);

	s = LMC_RAISESPL();
	lmc_dec_reset(sc);
	lmc_reset(sc);
	lmc_attach(sc);
	LMC_RESTORESPL(s);
}
コード例 #25
0
ファイル: esp.c プロジェクト: lacombar/netbsd-alc
/*
 * Attach this instance, and then all the sub-devices
 */
void
espattach(device_t parent, device_t self, void *aux)
{
	struct esp_softc *esc = device_private(self);
	struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
	struct confargs *ca = aux;
	u_int *reg;
	int sz;

	/*
	 * Set up glue for MI code early; we use some of it here.
	 */
	sc->sc_dev = self;
	sc->sc_glue = &esp_glue;

	esc->sc_node = ca->ca_node;
	esc->sc_pri = ca->ca_intr[0];
	aprint_normal(" irq %d", esc->sc_pri);

	/*
	 * Map my registers in.
	 */
	reg = ca->ca_reg;
	esc->sc_reg =    mapiodev(ca->ca_baseaddr + reg[0], reg[1]);
	esc->sc_dmareg = mapiodev(ca->ca_baseaddr + reg[2], reg[3]);

	/* Allocate 16-byte aligned DMA command space */
	esc->sc_dmacmd = dbdma_alloc(sizeof(dbdma_command_t) * 20);

	/* Other settings */
	sc->sc_id = 7;
	sz = OF_getprop(ca->ca_node, "clock-frequency",
	    &sc->sc_freq, sizeof(int));
	if (sz != sizeof(int))
		sc->sc_freq = 25000000;

	/* gimme MHz */
	sc->sc_freq /= 1000000;

	/* esc->sc_dma->sc_esp = esc;*/

	/*
	 * 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.
	 */
	sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
	sc->sc_cfg2 = NCRCFG2_SCSI2; /* | NCRCFG2_FE */
	sc->sc_cfg3 = NCRCFG3_CDB;
	sc->sc_rev = NCR_VARIANT_NCR53C94;

	/*
	 * 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_maxxfer = 64 * 1024;

	/* and the interuppts */
	intr_establish(esc->sc_pri, IST_EDGE, IPL_BIO, ncr53c9x_intr, sc);

	/* Reset SCSI bus when halt. */
	shutdownhook_establish(esp_shutdownhook, sc);

	/* Do the common parts of attachment. */
	sc->sc_adapter.adapt_minphys = minphys;
	sc->sc_adapter.adapt_request = ncr53c9x_scsipi_request;
	ncr53c9x_attach(sc);

	/* Turn on target selection using the `DMA' method */
	sc->sc_features |= NCR_F_DMASELECT;
}
コード例 #26
0
ファイル: if_ae.c プロジェクト: yazshel/netbsd-kernel
/*
 * ae_attach:
 *
 *	Attach an ae interface to the system.
 */
void
ae_attach(device_t parent, device_t self, void *aux)
{
	const uint8_t *enaddr;
	prop_data_t ea;
	struct ae_softc *sc = device_private(self);
	struct arbus_attach_args *aa = aux;
	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
	int i, error;

	sc->sc_dev = self;

	callout_init(&sc->sc_tick_callout, 0);

	printf(": Atheros AR531X 10/100 Ethernet\n");

	/*
	 * Try to get MAC address.
	 */
	ea = prop_dictionary_get(device_properties(sc->sc_dev), "mac-address");
	if (ea == NULL) {
		printf("%s: unable to get mac-addr property\n",
		    device_xname(sc->sc_dev));
		return;
	}
	KASSERT(prop_object_type(ea) == PROP_TYPE_DATA);
	KASSERT(prop_data_size(ea) == ETHER_ADDR_LEN);
	enaddr = prop_data_data_nocopy(ea);

	/* Announce ourselves. */
	printf("%s: Ethernet address %s\n", device_xname(sc->sc_dev),
	    ether_sprintf(enaddr));

	sc->sc_cirq = aa->aa_cirq;
	sc->sc_mirq = aa->aa_mirq;
	sc->sc_st = aa->aa_bst;
	sc->sc_dmat = aa->aa_dmat;

	SIMPLEQ_INIT(&sc->sc_txfreeq);
	SIMPLEQ_INIT(&sc->sc_txdirtyq);

	/*
	 * Map registers.
	 */
	sc->sc_size = aa->aa_size;
	if ((error = bus_space_map(sc->sc_st, aa->aa_addr, sc->sc_size, 0,
	    &sc->sc_sh)) != 0) {
		printf("%s: unable to map registers, error = %d\n",
		    device_xname(sc->sc_dev), error);
		goto fail_0;
	}

	/*
	 * Allocate the control data structures, and create and load the
	 * DMA map for it.
	 */
	if ((error = bus_dmamem_alloc(sc->sc_dmat,
	    sizeof(struct ae_control_data), PAGE_SIZE, 0, &sc->sc_cdseg,
	    1, &sc->sc_cdnseg, 0)) != 0) {
		printf("%s: unable to allocate control data, error = %d\n",
		    device_xname(sc->sc_dev), error);
		goto fail_1;
	}

	if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg,
	    sizeof(struct ae_control_data), (void **)&sc->sc_control_data,
	    BUS_DMA_COHERENT)) != 0) {
		printf("%s: unable to map control data, error = %d\n",
		    device_xname(sc->sc_dev), error);
		goto fail_2;
	}

	if ((error = bus_dmamap_create(sc->sc_dmat,
	    sizeof(struct ae_control_data), 1,
	    sizeof(struct ae_control_data), 0, 0, &sc->sc_cddmamap)) != 0) {
		printf("%s: unable to create control data DMA map, "
		    "error = %d\n", device_xname(sc->sc_dev), error);
		goto fail_3;
	}

	if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap,
	    sc->sc_control_data, sizeof(struct ae_control_data), NULL,
	    0)) != 0) {
		printf("%s: unable to load control data DMA map, error = %d\n",
		    device_xname(sc->sc_dev), error);
		goto fail_4;
	}

	/*
	 * Create the transmit buffer DMA maps.
	 */
	for (i = 0; i < AE_TXQUEUELEN; i++) {
		if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
		    AE_NTXSEGS, MCLBYTES, 0, 0,
		    &sc->sc_txsoft[i].txs_dmamap)) != 0) {
			printf("%s: unable to create tx DMA map %d, "
			    "error = %d\n", device_xname(sc->sc_dev), i, error);
			goto fail_5;
		}
	}

	/*
	 * Create the receive buffer DMA maps.
	 */
	for (i = 0; i < AE_NRXDESC; i++) {
		if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
		    MCLBYTES, 0, 0, &sc->sc_rxsoft[i].rxs_dmamap)) != 0) {
			printf("%s: unable to create rx DMA map %d, "
			    "error = %d\n", device_xname(sc->sc_dev), i, error);
			goto fail_6;
		}
		sc->sc_rxsoft[i].rxs_mbuf = NULL;
	}

	/*
	 * Reset the chip to a known state.
	 */
	ae_reset(sc);

	/*
	 * From this point forward, the attachment cannot fail.  A failure
	 * before this point releases all resources that may have been
	 * allocated.
	 */
	sc->sc_flags |= AE_ATTACHED;

	/*
	 * Initialize our media structures.  This may probe the MII, if
	 * present.
	 */
	sc->sc_mii.mii_ifp = ifp;
	sc->sc_mii.mii_readreg = ae_mii_readreg;
	sc->sc_mii.mii_writereg = ae_mii_writereg;
	sc->sc_mii.mii_statchg = ae_mii_statchg;
	sc->sc_ethercom.ec_mii = &sc->sc_mii;
	ifmedia_init(&sc->sc_mii.mii_media, 0, ether_mediachange,
	    ether_mediastatus);
	mii_attach(sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
	    MII_OFFSET_ANY, 0);

	if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
		ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
	} else
		ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);

	sc->sc_tick = ae_mii_tick;

	strcpy(ifp->if_xname, device_xname(sc->sc_dev));
	ifp->if_softc = sc;
	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
	sc->sc_if_flags = ifp->if_flags;
	ifp->if_ioctl = ae_ioctl;
	ifp->if_start = ae_start;
	ifp->if_watchdog = ae_watchdog;
	ifp->if_init = ae_init;
	ifp->if_stop = ae_stop;
	IFQ_SET_READY(&ifp->if_snd);

	/*
	 * We can support 802.1Q VLAN-sized frames.
	 */
	sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;

	/*
	 * Attach the interface.
	 */
	if_attach(ifp);
	ether_ifattach(ifp, enaddr);
	ether_set_ifflags_cb(&sc->sc_ethercom, ae_ifflags_cb);

	rnd_attach_source(&sc->sc_rnd_source, device_xname(sc->sc_dev),
	    RND_TYPE_NET, RND_FLAG_DEFAULT);

	/*
	 * Make sure the interface is shutdown during reboot.
	 */
	sc->sc_sdhook = shutdownhook_establish(ae_shutdown, sc);
	if (sc->sc_sdhook == NULL)
		printf("%s: WARNING: unable to establish shutdown hook\n",
		    device_xname(sc->sc_dev));

	/*
	 * Add a suspend hook to make sure we come back up after a
	 * resume.
	 */
	sc->sc_powerhook = powerhook_establish(device_xname(sc->sc_dev),
	    ae_power, sc);
	if (sc->sc_powerhook == NULL)
		printf("%s: WARNING: unable to establish power hook\n",
		    device_xname(sc->sc_dev));
	return;

	/*
	 * Free any resources we've allocated during the failed attach
	 * attempt.  Do this in reverse order and fall through.
	 */
 fail_6:
	for (i = 0; i < AE_NRXDESC; i++) {
		if (sc->sc_rxsoft[i].rxs_dmamap != NULL)
			bus_dmamap_destroy(sc->sc_dmat,
			    sc->sc_rxsoft[i].rxs_dmamap);
	}
 fail_5:
	for (i = 0; i < AE_TXQUEUELEN; i++) {
		if (sc->sc_txsoft[i].txs_dmamap != NULL)
			bus_dmamap_destroy(sc->sc_dmat,
			    sc->sc_txsoft[i].txs_dmamap);
	}
	bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
 fail_4:
	bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
 fail_3:
	bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_control_data,
	    sizeof(struct ae_control_data));
 fail_2:
	bus_dmamem_free(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg);
 fail_1:
	bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_size);
 fail_0:
	return;
}
コード例 #27
0
/*
 * The routine called by the low level scsi routine when it discovers
 * a device suitable for this driver.
 */
void
sdattach(struct device *parent, struct device *self, void *aux)
{
	struct sd_softc *sc = (struct sd_softc *)self;
	struct scsi_attach_args *sa = aux;
	struct disk_parms *dp = &sc->params;
	struct scsi_link *sc_link = sa->sa_sc_link;
	int sd_autoconf = scsi_autoconf | SCSI_SILENT |
	    SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE;
	struct dk_cache dkc;
	int error, result;

	SC_DEBUG(sc_link, SDEV_DB2, ("sdattach:\n"));

	/*
	 * Store information needed to contact our base driver
	 */
	sc->sc_link = sc_link;
	sc_link->interpret_sense = sd_interpret_sense;
	sc_link->device_softc = sc;

	if ((sc_link->flags & SDEV_ATAPI) && (sc_link->flags & SDEV_REMOVABLE))
		sc_link->quirks |= SDEV_NOSYNCCACHE;

	if (!(sc_link->inqdata.flags & SID_RelAdr))
		sc_link->quirks |= SDEV_ONLYBIG;

	/*
	 * Note if this device is ancient.  This is used in sdminphys().
	 */
	if (!(sc_link->flags & SDEV_ATAPI) &&
	    SCSISPC(sa->sa_inqbuf->version) == 0)
		sc->flags |= SDF_ANCIENT;

	/*
	 * Use the subdriver to request information regarding
	 * the drive. We cannot use interrupts yet, so the
	 * request must specify this.
	 */
	printf("\n");

	scsi_xsh_set(&sc->sc_xsh, sc_link, sdstart);
	timeout_set(&sc->sc_timeout, (void (*)(void *))scsi_xsh_add,
	    &sc->sc_xsh);

	/* Spin up non-UMASS devices ready or not. */
	if ((sc->sc_link->flags & SDEV_UMASS) == 0)
		scsi_start(sc_link, SSS_START, sd_autoconf);

	/*
	 * Some devices (e.g. Blackberry Pearl) won't admit they have
	 * media loaded unless its been locked in.
	 */
	if ((sc_link->flags & SDEV_REMOVABLE) != 0)
		scsi_prevent(sc_link, PR_PREVENT, sd_autoconf);

	/* Check that it is still responding and ok. */
	error = scsi_test_unit_ready(sc->sc_link, TEST_READY_RETRIES * 3,
	    sd_autoconf);

	if (error)
		result = SDGP_RESULT_OFFLINE;
	else
		result = sd_get_parms(sc, &sc->params, sd_autoconf);

	if ((sc_link->flags & SDEV_REMOVABLE) != 0)
		scsi_prevent(sc_link, PR_ALLOW, sd_autoconf);

	switch (result) {
	case SDGP_RESULT_OK:
		printf("%s: %lluMB, %lu bytes/sector, %llu sectors",
		    sc->sc_dev.dv_xname,
		    dp->disksize / (1048576 / dp->secsize), dp->secsize,
		    dp->disksize);
		printf("\n");
		break;

	case SDGP_RESULT_OFFLINE:
		break;

#ifdef DIAGNOSTIC
	default:
		panic("sdattach: unknown result (%#x) from get_parms", result);
		break;
#endif
	}

	/*
	 * Initialize disk structures.
	 */
	sc->sc_dk.dk_name = sc->sc_dev.dv_xname;
	bufq_init(&sc->sc_bufq, BUFQ_FIFO);

	/*
	 * Enable write cache by default.
	 */
	memset(&dkc, 0, sizeof(dkc));
	if (sd_ioctl_cache(sc, DIOCGCACHE, &dkc) == 0 && dkc.wrcache == 0) {
		dkc.wrcache = 1;
		sd_ioctl_cache(sc, DIOCSCACHE, &dkc);
	}

	/*
	 * Establish a shutdown hook so that we can ensure that
	 * our data has actually made it onto the platter at
	 * shutdown time.  Note that this relies on the fact
	 * that the shutdown hook code puts us at the head of
	 * the list (thus guaranteeing that our hook runs before
	 * our ancestors').
	 */
	if ((sc->sc_sdhook =
	    shutdownhook_establish(sd_shutdown, sc)) == NULL)
		printf("%s: WARNING: unable to establish shutdown hook\n",
		    sc->sc_dev.dv_xname);

	/* Attach disk. */
	disk_attach(&sc->sc_dev, &sc->sc_dk);
}
コード例 #28
0
ファイル: cac.c プロジェクト: ryo/netbsd-src
/*
 * Initialise our interface to the controller.
 */
int
cac_init(struct cac_softc *sc, const char *intrstr, int startfw)
{
	struct cac_controller_info cinfo;
	int error, rseg, size, i;
	bus_dma_segment_t seg;
	struct cac_ccb *ccb;
	char firm[8];

	if (intrstr != NULL)
		aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr);

	SIMPLEQ_INIT(&sc->sc_ccb_free);
	SIMPLEQ_INIT(&sc->sc_ccb_queue);
	mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_VM);
	cv_init(&sc->sc_ccb_cv, "cacccb");

        size = sizeof(struct cac_ccb) * CAC_MAX_CCBS;

	if ((error = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &seg, 1,
	    &rseg, BUS_DMA_NOWAIT)) != 0) {
		aprint_error_dev(sc->sc_dev, "unable to allocate CCBs, error = %d\n",
		    error);
		return (-1);
	}

	if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, size,
	    (void **)&sc->sc_ccbs,
	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
		aprint_error_dev(sc->sc_dev, "unable to map CCBs, error = %d\n",
		    error);
		return (-1);
	}

	if ((error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
	    BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) {
		aprint_error_dev(sc->sc_dev, "unable to create CCB DMA map, error = %d\n",
		    error);
		return (-1);
	}

	if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_ccbs,
	    size, NULL, BUS_DMA_NOWAIT)) != 0) {
		aprint_error_dev(sc->sc_dev, "unable to load CCB DMA map, error = %d\n",
		    error);
		return (-1);
	}

	sc->sc_ccbs_paddr = sc->sc_dmamap->dm_segs[0].ds_addr;
	memset(sc->sc_ccbs, 0, size);
	ccb = (struct cac_ccb *)sc->sc_ccbs;

	for (i = 0; i < CAC_MAX_CCBS; i++, ccb++) {
		/* Create the DMA map for this CCB's data */
		error = bus_dmamap_create(sc->sc_dmat, CAC_MAX_XFER,
		    CAC_SG_SIZE, CAC_MAX_XFER, 0,
		    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
		    &ccb->ccb_dmamap_xfer);

		if (error) {
			aprint_error_dev(sc->sc_dev, "can't create ccb dmamap (%d)\n",
			    error);
			break;
		}

		ccb->ccb_flags = 0;
		ccb->ccb_paddr = sc->sc_ccbs_paddr + i * sizeof(struct cac_ccb);
		SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_free, ccb, ccb_chain);
	}

	/* Start firmware background tasks, if needed. */
	if (startfw) {
		if (cac_cmd(sc, CAC_CMD_START_FIRMWARE, &cinfo, sizeof(cinfo),
		    0, 0, CAC_CCB_DATA_IN, NULL)) {
			aprint_error_dev(sc->sc_dev, "CAC_CMD_START_FIRMWARE failed\n");
			return (-1);
		}
	}

	if (cac_cmd(sc, CAC_CMD_GET_CTRL_INFO, &cinfo, sizeof(cinfo), 0, 0,
	    CAC_CCB_DATA_IN, NULL)) {
		aprint_error_dev(sc->sc_dev, "CAC_CMD_GET_CTRL_INFO failed\n");
		return (-1);
	}

	strlcpy(firm, cinfo.firm_rev, 4+1);
	printf("%s: %d channels, firmware <%s>\n", device_xname(sc->sc_dev),
	    cinfo.scsi_chips, firm);

	/* Limit number of units to size of our sc_unitmask */
	sc->sc_nunits = cinfo.num_drvs;
	if (sc->sc_nunits > sizeof(sc->sc_unitmask) * NBBY)
		sc->sc_nunits = sizeof(sc->sc_unitmask) * NBBY;

	/* Attach our units */
	sc->sc_unitmask = 0;
	cac_rescan(sc->sc_dev, "cac", 0);

	/* Set our `shutdownhook' before we start any device activity. */
	if (cac_sdh == NULL)
		cac_sdh = shutdownhook_establish(cac_shutdown, NULL);

	mutex_enter(&sc->sc_mutex);
	(*sc->sc_cl.cl_intr_enable)(sc, CAC_INTR_ENABLE);
	mutex_exit(&sc->sc_mutex);

#if NBIO > 0
	if (bio_register(sc->sc_dev, cac_ioctl) != 0)
		aprint_error_dev(sc->sc_dev, "controller registration failed");
	else
		sc->sc_ioctl = cac_ioctl;
	if (cac_create_sensors(sc) != 0)
		aprint_error_dev(sc->sc_dev, "unable to create sensors\n");
#endif

	return (0);
}
コード例 #29
0
ファイル: cgtwelve.c プロジェクト: sofuture/bitrig
/*
 * Attach and initialize a cgtwelve.
 */
void
cgtwelveattach(struct device *parent, struct device *self, void *args)
{
	struct cgtwelve_softc *sc = (struct cgtwelve_softc *)self;
	struct sbus_attach_args *sa = args;
	bus_space_tag_t bt;
	bus_space_handle_t bh;
	int node, isconsole = 0;
	char *ps;

	bt = sa->sa_bustag;
	node = sa->sa_node;

	printf(": %s", getpropstring(node, "model"));
	ps = getpropstring(node, "dev_id");
	if (*ps != '\0')
		printf(" (%s)", ps);
	printf("\n");

	isconsole = node == fbnode;

	if (sa->sa_nreg == 0) {
		printf("%s: no SBus registers!\n", self->dv_xname);
		return;
	}

	sc->sc_bustag = bt;

	/*
	 * Map registers
	 */
	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset +
	    CG12_OFF_DPU, sizeof(struct cgtwelve_dpu),
	    BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
		printf("%s: can't map DPU registers\n", self->dv_xname);
		return;
	}
	sc->sc_dpu = bus_space_vaddr(bt, bh);
	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset +
	    CG12_OFF_APU, sizeof(struct cgtwelve_apu),
	    BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
		printf("%s: can't map APU registers\n", self->dv_xname);
		return;
	}
	sc->sc_apu = bus_space_vaddr(bt, bh);
	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset +
	    CG12_OFF_DAC, sizeof(struct cgtwelve_dac),
	    BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
		printf("%s: can't map RAMDAC registers\n", self->dv_xname);
		return;
	}
	sc->sc_ramdac = bus_space_vaddr(bt, bh);

	/*
	 * The console is using the 1-bit overlay plane, while the prom
	 * will correctly report 32 bit depth.
	 */
	fb_setsize(&sc->sc_sunfb, 1, CG12_WIDTH, CG12_HEIGHT,
	    node, 0);
	sc->sc_sunfb.sf_depth = 1;
	sc->sc_sunfb.sf_linebytes = sc->sc_sunfb.sf_width / 8;
	sc->sc_sunfb.sf_fbsize = sc->sc_sunfb.sf_height *
	    sc->sc_sunfb.sf_linebytes;

	sc->sc_highres = sc->sc_sunfb.sf_width == CG12_WIDTH_HR;

	/*
	 * Map planes
	 */
	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset +
	    (sc->sc_highres ? CG12_OFF_OVERLAY0_HR : CG12_OFF_OVERLAY0),
	    round_page(sc->sc_highres ? CG12_SIZE_OVERLAY_HR :
	        CG12_SIZE_OVERLAY), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
		printf("%s: can't map overlay plane\n", self->dv_xname);
		return;
	}
	sc->sc_overlay = bus_space_vaddr(bt, bh);
	if (sbus_bus_map(bt, sa->sa_slot, sa->sa_offset +
	    (sc->sc_highres ? CG12_OFF_INTEN_HR : CG12_OFF_INTEN),
	    round_page(sc->sc_highres ? CG12_SIZE_COLOR24_HR :
	        CG12_SIZE_COLOR24), BUS_SPACE_MAP_LINEAR, 0, &bh) != 0) {
		printf("%s: can't map color plane\n", self->dv_xname);
		return;
	}
	sc->sc_inten = bus_space_vaddr(bt, bh);
	sc->sc_paddr = sbus_bus_addr(bt, sa->sa_slot, sa->sa_offset +
	    (sc->sc_highres ? CG12_OFF_INTEN_HR : CG12_OFF_INTEN));

	/* reset cursor & frame buffer controls */
	sc->sc_sunfb.sf_depth = 0;	/* force action */
	cgtwelve_reset(sc, 1);

	sc->sc_sunfb.sf_ro.ri_bits = (void *)sc->sc_overlay;
	sc->sc_sunfb.sf_ro.ri_hw = sc;
	fbwscons_init(&sc->sc_sunfb, 0, isconsole);

	if (isconsole) {
		fbwscons_console_init(&sc->sc_sunfb, -1);
		shutdownhook_establish(cgtwelve_prom, sc);
	}

	printf("%s: %dx%d", self->dv_xname,
	    sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);
	ps = getpropstring(node, "ucoderev");
	if (*ps != '\0')
		printf(", microcode rev. %s", ps);
	printf("\n");

	fbwscons_attach(&sc->sc_sunfb, &cgtwelve_accessops, isconsole);
}
コード例 #30
0
ファイル: tcx.c プロジェクト: alenichev/openbsd-kernel
void
tcxattach(struct device *parent, struct device *self, void *args)
{
	struct tcx_softc *sc = (struct tcx_softc *)self;
	struct confargs *ca = args;
	int node, pri;
	int isconsole = 0;
	char *nam = NULL;
	vaddr_t thc_offset;

	pri = ca->ca_ra.ra_intr[0].int_pri;
	printf(" pri %d: ", pri);

	node = ca->ca_ra.ra_node;
	isconsole = node == fbnode;

	if (ca->ca_ra.ra_nreg < TCX_NREG) {
		printf("expected %d registers, got %d\n",
		    TCX_NREG, ca->ca_ra.ra_nreg);
		return;
	}

	nam = getpropstring(node, "model");
	if (*nam != '\0')
		printf("%s, ", nam);

	/*
	 * Copy the register address spaces needed for mmap operation.
	 */
	sc->sc_phys[0] = ca->ca_ra.ra_reg[TCX_REG_DFB8];
	sc->sc_phys[1] = ca->ca_ra.ra_reg[TCX_REG_DFB24];

	/*
	 * Can't trust the PROM range len here, it is only 4 bytes on the
	 * 8-bit model. Not that it matters much anyway since we map in
	 * pages.
	 */
	sc->sc_bt = (volatile struct bt_regs *)
	    mapiodev(&ca->ca_ra.ra_reg[TCX_REG_CMAP], 0, sizeof *sc->sc_bt);

	/*
	 * For some reason S24 PROM sets up TEC and THC ranges at the
	 * right addresses (701000 and 301000), while 8 bit TCX doesn't
	 * (and uses 70000 and 30000) - be sure to only compensate on 8 bit
	 * models.
	 */
	if (((vaddr_t)ca->ca_ra.ra_reg[TCX_REG_THC].rr_paddr & 0x1000) != 0)
		thc_offset = 0;
	else
		thc_offset = 0x1000;
	sc->sc_thc = (volatile struct tcx_thc *)
	    mapiodev(&ca->ca_ra.ra_reg[TCX_REG_THC],
	        thc_offset, sizeof *sc->sc_thc);

	/*
	 * Find out frame buffer geometry, so that we know how much
	 * memory to map.
	 */
	fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, ca->ca_bustype);

	sc->sc_dfb8 = mapiodev(&ca->ca_ra.ra_reg[TCX_REG_DFB8], 0,
	    round_page(sc->sc_sunfb.sf_fbsize));

	/*
	 * If the frame buffer advertizes itself as the 8 bit model, or
	 * if the PROM ranges are too small, limit ourselves to 8 bit
	 * operations.
	 *
	 * Further code needing to know which capabilities the frame buffer
	 * has will rely on sc_cplane being non-zero if 24 bit operation
	 * is possible.
	 */
	if (!node_has_property(node, "tcx-8-bit") &&
	    ca->ca_ra.ra_reg[TCX_REG_RDFB32].rr_len >=
	      sc->sc_sunfb.sf_fbsize * 4) {
		sc->sc_cplane =
		    (paddr_t)ca->ca_ra.ra_reg[TCX_REG_RDFB32].rr_paddr;
	}

	printf("%dx%dx%d\n",
	    sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height,
	    sc->sc_cplane == 0 ? 8 : 24);

	/*
	 * Set up mappings for the acceleration code. This may fail.
	 */
	tcx_accel_init(sc, ca);

	/* reset cursor & frame buffer controls */
	tcx_reset(sc, 8);

	/* enable video */
	tcx_burner(sc, 1, 0);

	sc->sc_sunfb.sf_ro.ri_hw = sc;
	sc->sc_sunfb.sf_ro.ri_bits = (void *)sc->sc_dfb8;

	fbwscons_init(&sc->sc_sunfb, isconsole);
	fbwscons_setcolormap(&sc->sc_sunfb, tcx_setcolor);

	/*
	 * Now plug accelerated console routines, if possible.
	 */
	tcx_accel_plug(sc, ca);

	sc->sc_ih.ih_fun = tcx_intr;
	sc->sc_ih.ih_arg = sc;
	intr_establish(pri, &sc->sc_ih, IPL_FB, self->dv_xname);

	if (isconsole) {
		fbwscons_console_init(&sc->sc_sunfb, -1);
		shutdownhook_establish(tcx_prom, sc);
	}

	fbwscons_attach(&sc->sc_sunfb, &tcx_accessops, isconsole);
}