Beispiel #1
0
/*
 * Interrupt handler
 */
static int
icap_ebus_intr(void *cookie, void *f)
{
	struct icap_softc *sc = cookie;
    struct buf *bp = sc->sc_bp;
	u_int32_t isr, saf = 0, hi, lo;

	isr = sc->sc_dp->Control;

	DEBUG_PRINT(("i %x\n",isr), DEBUG_INTR);

    /* Make sure there is an interrupt and that we should take it
     */
	if ((isr & (ICAPC_INTEN|ICAPC_DONE)) != (ICAPC_INTEN|ICAPC_DONE))
		return (0);

    /* Pull out all completed buffers
     */
    while ((isr & ICAPC_OF_EMPTY) == 0) {

        if (isr & ICAPC_ERROR) {
            printf("%s: internal error (%x)\n", device_xname(sc->sc_dev),isr);
            icap_reset(sc);
            if (bp) {
                bp->b_error = EIO;
                icapstart(sc);
            }
            return (1);
        }

        /* Beware, order matters */
        saf = sc->sc_dp->SizeAndFlags;
        hi  = sc->sc_dp->BufferAddressHi32; /* BUGBUG 64bit */
        lo  = sc->sc_dp->BufferAddressLo32; /* this pops the fifo */
	__USE(hi);
	__USE(lo);

        /* Say its done that much (and sanity)
         */
        if (bp) {
            size_t count = saf & ICAPS_S_MASK;
            /* more sanity */
            if (count > bp->b_resid)
                count = bp->b_resid;
            bp->b_resid -= count;
        }

        /* More? */
        isr = sc->sc_dp->Control;
    }

    /* Did we pop at least one */
    if (saf)
        icapstart(sc);

	return (1);
}
Beispiel #2
0
/*
 * Receive a packet.
 */
static int
kgdb_recv(u_char *bp, int maxlen)
{
	u_char *p;
	int c, csum, tmpcsum;
	int len;

	DPRINTF(("kgdb_recv:  "));
	do {
		p = bp;
		csum = len = 0;
		while ((c = GETC()) != KGDB_START)
			DPRINTF(("%c",c));
		DPRINTF(("%c Start ",c));

		while ((c = GETC()) != KGDB_END && len < maxlen) {
			DPRINTF(("%c",c));
			c &= 0x7f;
			csum += c;
			*p++ = c;
			len++;
		}
		csum &= 0xff;
		*p = '\0';
		DPRINTF(("%c End ", c));

		if (len >= maxlen) {
			DPRINTF(("Long- "));
			PUTC(KGDB_BADP);
			continue;
		}
		tmpcsum = csum;

		c = GETC();
		DPRINTF(("%c",c));
		csum -= digit2i(c) * 16;
		c = GETC();
		DPRINTF(("%c",c));
		csum -= digit2i(c);

		if (csum == 0) {
			DPRINTF(("Good+ "));
			PUTC(KGDB_GOODP);
			/* Sequence present? */
			if (bp[2] == ':') {
				DPRINTF(("Seq %c%c ", bp[0], bp[1]));
				PUTC(bp[0]);
				PUTC(bp[1]);
				len -= 3;
				kgdb_copy(bp + 3, bp, len);
			}
			break;
		}
		DPRINTF((" Bad(wanted %x, off by %d)- ", tmpcsum, csum));
		__USE(tmpcsum);
		PUTC(KGDB_BADP);
	} while (1);
	DPRINTF(("kgdb_recv: %s\n", bp));
	return (len);
}
Beispiel #3
0
static int 
addstr4(SCR *sp, const void *str, size_t len, int wide)
{
	WINDOW *win;
	size_t y, x;
	int iv;

	win = CLSP(sp) ? CLSP(sp) : stdscr;

	/*
	 * If ex isn't in control, it's the last line of the screen and
	 * it's a split screen, use inverse video.
	 */
	iv = 0;
	getyx(win, y, x);
	__USE(x);
	if (!F_ISSET(sp, SC_SCR_EXWROTE) &&
	    y == RLNO(sp, LASTLINE(sp)) && IS_SPLIT(sp)) {
		iv = 1;
		(void)wstandout(win);
	}

#ifdef USE_WIDECHAR
	if (wide) {
	    if (waddnwstr(win, str, len) == ERR)
		return (1);
	} else 
#endif
	    if (waddnstr(win, str, len) == ERR)
		    return (1);

	if (iv)
		(void)wstandend(win);
	return (0);
}
/* ARGSUSED */
int
hp300_bus_space_probe(bus_space_tag_t t, bus_space_handle_t bsh,
    bus_size_t offset, int sz)
{
	label_t faultbuf;
	int i;

	nofault = (int *)&faultbuf;
	if (setjmp((label_t *)nofault)) {
		nofault = NULL;
		return 0;
	}

	switch (sz) {
	case 1:
		i = bus_space_read_1(t, bsh, offset);
		break;

	case 2:
		i = bus_space_read_2(t, bsh, offset);
		break;

	case 4:
		i = bus_space_read_4(t, bsh, offset);
		break;

	default:
		panic("%s: unupported data size %d", __func__, sz);
		/* NOTREACHED */
	}
	__USE(i);
	nofault = NULL;
	return 1;
}
int
empsc_intr(void *arg)
{
	struct sci_softc *dev = arg;
	u_char stat;

	if ((*dev->sci_csr & SCI_CSR_INT) == 0)
		return(0);
	stat = *dev->sci_iack;
	__USE(stat);
	/* XXXX is: something is missing here, at least a: */
	return(1);
}
Beispiel #6
0
/*
 * mutex_vector_exit:
 *
 *	Support routine for mutex_exit() that handles all cases.
 */
void
mutex_vector_exit(kmutex_t *mtx)
{
	turnstile_t *ts;
	uintptr_t curthread;

	if (MUTEX_SPIN_P(mtx)) {
#ifdef FULL
		if (__predict_false(!MUTEX_SPINBIT_LOCKED_P(mtx))) {
			if (panicstr != NULL)
				return;
			MUTEX_ABORT(mtx, "exiting unheld spin mutex");
		}
		MUTEX_UNLOCKED(mtx);
		MUTEX_SPINBIT_LOCK_UNLOCK(mtx);
#endif
		MUTEX_SPIN_SPLRESTORE(mtx);
		return;
	}

	if (__predict_false((uintptr_t)panicstr | cold)) {
		MUTEX_UNLOCKED(mtx);
		MUTEX_RELEASE(mtx);
		return;
	}

	curthread = (uintptr_t)curlwp;
	MUTEX_DASSERT(mtx, curthread != 0);
	MUTEX_ASSERT(mtx, MUTEX_OWNER(mtx->mtx_owner) == curthread);
	MUTEX_UNLOCKED(mtx);
#if !defined(LOCKDEBUG)
	__USE(curthread);
#endif

#ifdef LOCKDEBUG
	/*
	 * Avoid having to take the turnstile chain lock every time
	 * around.  Raise the priority level to splhigh() in order
	 * to disable preemption and so make the following atomic.
	 */
	{
		int s = splhigh();
		if (!MUTEX_HAS_WAITERS(mtx)) {
			MUTEX_RELEASE(mtx);
			splx(s);
			return;
		}
		splx(s);
	}
#endif

	/*
	 * Get this lock's turnstile.  This gets the interlock on
	 * the sleep queue.  Once we have that, we can clear the
	 * lock.  If there was no turnstile for the lock, there
	 * were no waiters remaining.
	 */
	ts = turnstile_lookup(mtx);

	if (ts == NULL) {
		MUTEX_RELEASE(mtx);
		turnstile_exit(mtx);
	} else {
		MUTEX_RELEASE(mtx);
		turnstile_wakeup(ts, TS_WRITER_Q,
		    TS_WAITERS(ts, TS_WRITER_Q), NULL);
	}
}
Beispiel #7
0
static void
apm_event_handle(struct apm_softc *sc, u_int event_code, u_int event_info)
{
	int error;
	const char *code;
	struct apm_power_info pi;

	switch (event_code) {
	case APM_USER_STANDBY_REQ:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: user standby request\n"));
		if (apm_do_standby) {
			if (apm_op_inprog == 0 && apm_record_event(sc, event_code))
				apm_userstandbys++;
			apm_op_inprog++;
			(void)(*sc->sc_ops->aa_set_powstate)(sc->sc_cookie,
			    APM_DEV_ALLDEVS, APM_LASTREQ_INPROG);
		} else {
			(void)(*sc->sc_ops->aa_set_powstate)(sc->sc_cookie,
			    APM_DEV_ALLDEVS, APM_LASTREQ_REJECTED);
			/* in case BIOS hates being spurned */
			(*sc->sc_ops->aa_enable)(sc->sc_cookie, 1);
		}
		break;

	case APM_STANDBY_REQ:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: system standby request\n"));
		if (apm_op_inprog) {
			DPRINTF(APMDEBUG_EVENTS | APMDEBUG_ANOM,
			    ("damn fool BIOS did not wait for answer\n"));
			/* just give up the fight */
			apm_damn_fool_bios = 1;
		}
		if (apm_do_standby) {
			if (apm_op_inprog == 0 &&
			    apm_record_event(sc, event_code))
				apm_standbys++;
			apm_op_inprog++;
			(void)(*sc->sc_ops->aa_set_powstate)(sc->sc_cookie,
			    APM_DEV_ALLDEVS, APM_LASTREQ_INPROG);
		} else {
			(void)(*sc->sc_ops->aa_set_powstate)(sc->sc_cookie,
			    APM_DEV_ALLDEVS, APM_LASTREQ_REJECTED);
			/* in case BIOS hates being spurned */
			(*sc->sc_ops->aa_enable)(sc->sc_cookie, 1);
		}
		break;

	case APM_USER_SUSPEND_REQ:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: user suspend request\n"));
		if (apm_op_inprog == 0 && apm_record_event(sc, event_code))
			apm_suspends++;
		apm_op_inprog++;
		(void)(*sc->sc_ops->aa_set_powstate)(sc->sc_cookie,
		    APM_DEV_ALLDEVS, APM_LASTREQ_INPROG);
		break;

	case APM_SUSPEND_REQ:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: system suspend request\n"));
		if (apm_op_inprog) {
			DPRINTF(APMDEBUG_EVENTS | APMDEBUG_ANOM,
			    ("damn fool BIOS did not wait for answer\n"));
			/* just give up the fight */
			apm_damn_fool_bios = 1;
		}
		if (apm_op_inprog == 0 && apm_record_event(sc, event_code))
			apm_suspends++;
		apm_op_inprog++;
		(void)(*sc->sc_ops->aa_set_powstate)(sc->sc_cookie,
		    APM_DEV_ALLDEVS, APM_LASTREQ_INPROG);
		break;

	case APM_POWER_CHANGE:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: power status change\n"));
		error = (*sc->sc_ops->aa_get_powstat)(sc->sc_cookie, 0, &pi);
#ifdef APM_POWER_PRINT
		/* only print if nobody is catching events. */
		if (error == 0 &&
		    (sc->sc_flags & (SCFLAG_OREAD|SCFLAG_OWRITE)) == 0)
			apm_power_print(sc, &pi);
#else
		__USE(error);
#endif
		apm_record_event(sc, event_code);
		break;

	case APM_NORMAL_RESUME:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: resume system\n"));
		apm_resume(sc, event_code, event_info);
		break;

	case APM_CRIT_RESUME:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: critical resume system"));
		apm_resume(sc, event_code, event_info);
		break;

	case APM_SYS_STANDBY_RESUME:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: system standby resume\n"));
		apm_resume(sc, event_code, event_info);
		break;

	case APM_UPDATE_TIME:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: update time\n"));
		apm_resume(sc, event_code, event_info);
		break;

	case APM_CRIT_SUSPEND_REQ:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: critical system suspend\n"));
		apm_record_event(sc, event_code);
		apm_suspend(sc);
		break;

	case APM_BATTERY_LOW:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: battery low\n"));
		apm_battlow++;
		apm_record_event(sc, event_code);
		break;

	case APM_CAP_CHANGE:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: capability change\n"));
		if (apm_minver < 2) {
			DPRINTF(APMDEBUG_EVENTS, ("apm: unexpected event\n"));
		} else {
			u_int numbatts, capflags;
			(*sc->sc_ops->aa_get_capabilities)(sc->sc_cookie,
			    &numbatts, &capflags);
			(*sc->sc_ops->aa_get_powstat)(sc->sc_cookie, 0, &pi);
		}
		break;

	default:
		switch (event_code >> 8) {
			case 0:
				code = "reserved system";
				break;
			case 1:
				code = "reserved device";
				break;
			case 2:
				code = "OEM defined";
				break;
			default:
				code = "reserved";
				break;
		}
		printf("APM: %s event code %x\n", code, event_code);
	}
}
Beispiel #8
0
static int
yds_allocate_slots(struct yds_softc *sc)
{
	size_t pcs, rcs, ecs, ws, memsize;
	void *mp;
	uint32_t da;		/* DMA address */
	char *va;		/* KVA */
	off_t cb;
	int i;
	struct yds_dma *p;

	/* Alloc DSP Control Data */
	pcs = YREAD4(sc, YDS_PLAY_CTRLSIZE) * sizeof(uint32_t);
	rcs = YREAD4(sc, YDS_REC_CTRLSIZE) * sizeof(uint32_t);
	ecs = YREAD4(sc, YDS_EFFECT_CTRLSIZE) * sizeof(uint32_t);
	ws = WORK_SIZE;
	YWRITE4(sc, YDS_WORK_SIZE, ws / sizeof(uint32_t));

	DPRINTF(("play control size : %d\n", (unsigned int)pcs));
	DPRINTF(("rec control size : %d\n", (unsigned int)rcs));
	DPRINTF(("eff control size : %d\n", (unsigned int)ecs));
#ifndef AUDIO_DEBUG
	__USE(ecs);
#endif
	DPRINTF(("work size : %d\n", (unsigned int)ws));
#ifdef DIAGNOSTIC
	if (pcs != sizeof(struct play_slot_ctrl_bank)) {
		aprint_error_dev(sc->sc_dev, "invalid play slot ctrldata %d != %d\n",
		       (unsigned int)pcs,
		       (unsigned int)sizeof(struct play_slot_ctrl_bank));
	if (rcs != sizeof(struct rec_slot_ctrl_bank))
		aprint_error_dev(sc->sc_dev, "invalid rec slot ctrldata %d != %d\n",
		       (unsigned int)rcs,
		       (unsigned int)sizeof(struct rec_slot_ctrl_bank));
	}
#endif

	memsize = N_PLAY_SLOTS*N_PLAY_SLOT_CTRL_BANK*pcs +
		  N_REC_SLOT_CTRL*N_REC_SLOT_CTRL_BANK*rcs + ws;
	memsize += (N_PLAY_SLOTS+1)*sizeof(uint32_t);

	p = &sc->sc_ctrldata;
	if (KERNADDR(p) == NULL) {
		i = yds_allocmem(sc, memsize, 16, p);
		if (i) {
			aprint_error_dev(sc->sc_dev, "couldn't alloc/map DSP DMA buffer, reason %d\n", i);
			return 1;
		}
	}
	mp = KERNADDR(p);
	da = DMAADDR(p);

	DPRINTF(("mp:%p, DMA addr:%#" PRIxPADDR "\n",
		 mp, sc->sc_ctrldata.map->dm_segs[0].ds_addr));

	memset(mp, 0, memsize);

	/* Work space */
	cb = 0;
	va = (uint8_t *)mp;
	YWRITE4(sc, YDS_WORK_BASE, da + cb);
	cb += ws;

	/* Play control data table */
	sc->ptbl = (uint32_t *)(va + cb);
	sc->ptbloff = cb;
	YWRITE4(sc, YDS_PLAY_CTRLBASE, da + cb);
	cb += (N_PLAY_SLOT_CTRL + 1) * sizeof(uint32_t);

	/* Record slot control data */
	sc->rbank = (struct rec_slot_ctrl_bank *)(va + cb);
	YWRITE4(sc, YDS_REC_CTRLBASE, da + cb);
	sc->rbankoff = cb;
	cb += N_REC_SLOT_CTRL * N_REC_SLOT_CTRL_BANK * rcs;

#if 0
	/* Effect slot control data -- unused */
	YWRITE4(sc, YDS_EFFECT_CTRLBASE, da + cb);
	cb += N_EFFECT_SLOT_CTRL * N_EFFECT_SLOT_CTRL_BANK * ecs;
#endif

	/* Play slot control data */
	sc->pbankoff = cb;
	for (i=0; i < N_PLAY_SLOT_CTRL; i++) {
		sc->pbankp[i*2] = (struct play_slot_ctrl_bank *)(va + cb);
		*(sc->ptbl + i+1) = htole32(da + cb);
		cb += pcs;

		sc->pbankp[i*2+1] = (struct play_slot_ctrl_bank *)(va + cb);
		cb += pcs;
	}
	/* Sync play control data table */
	bus_dmamap_sync(sc->sc_dmatag, p->map,
			sc->ptbloff, (N_PLAY_SLOT_CTRL+1) * sizeof(uint32_t),
			BUS_DMASYNC_PREWRITE);

	return 0;
}
int
mlhsc_dma_xfer_out(struct sci_softc *dev, int len, register u_char *buf,
                   int phase)
{
	int wait = sci_data_wait;
	u_char csr;
	volatile register u_char *sci_dma = dev->sci_data + 16;
	volatile register u_char *sci_csr = dev->sci_csr;

	csr = *dev->sci_bus_csr;
	__USE(csr);

	QPRINTF(("mlhdma_xfer %d, csr=%02x\n", len, csr));

	QPRINTF(("mlhgdma_out {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
  	 len, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
	 buf[6], buf[7], buf[8], buf[9]));

	*dev->sci_tcmd = phase;
	*dev->sci_mode |= SCI_MODE_DMA;
	*dev->sci_icmd = SCI_ICMD_DATA;
	*dev->sci_dma_send = 0;
	while (len > 64) {
		wait = sci_data_wait;
		while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
		  (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
			if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
			  || !(*dev->sci_bus_csr & SCI_BUS_BSY)
			  || --wait < 0) {
#ifdef DEBUG
				if (sci_debug)
					printf("mlhdma_out fail: l%d i%x w%d\n",
					len, csr, wait);
#endif
				*dev->sci_mode &= ~SCI_MODE_DMA;
				return 0;
			}
		}

#define W1	(*sci_dma = *buf++)
		W1; W1; W1; W1; W1; W1; W1; W1;
		W1; W1; W1; W1; W1; W1; W1; W1;
		W1; W1; W1; W1; W1; W1; W1; W1;
		W1; W1; W1; W1; W1; W1; W1; W1;
		W1; W1; W1; W1; W1; W1; W1; W1;
		W1; W1; W1; W1; W1; W1; W1; W1;
		W1; W1; W1; W1; W1; W1; W1; W1;
		W1; W1; W1; W1; W1; W1; W1; W1;
		len -= 64;
	}
	while (len > 0) {
		wait = sci_data_wait;
		while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
		  (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
			if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
			  || !(*dev->sci_bus_csr & SCI_BUS_BSY)
			  || --wait < 0) {
#ifdef DEBUG
				if (sci_debug)
					printf("mlhdma_out fail: l%d i%x w%d\n",
					len, csr, wait);
#endif
				*dev->sci_mode &= ~SCI_MODE_DMA;
				return 0;
			}
		}

		*sci_dma = *buf++;
		len--;
	}

	wait = sci_data_wait;
	while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) ==
	  SCI_CSR_PHASE_MATCH && --wait);

	*dev->sci_mode &= ~SCI_MODE_DMA;
	return 0;
}
int
mlhsc_dma_xfer_in(struct sci_softc *dev, int len, register u_char *buf,
                  int phase)
{
	int wait = sci_data_wait;
	u_char csr;
	volatile register u_char *sci_dma = dev->sci_data + 16;
	volatile register u_char *sci_csr = dev->sci_csr;
#ifdef DEBUG
	u_char *obp = buf;
#endif

	csr = *dev->sci_bus_csr;
	__USE(csr);

	QPRINTF(("mlhdma_in %d, csr=%02x\n", len, csr));

	*dev->sci_tcmd = phase;
	*dev->sci_mode |= SCI_MODE_DMA;
	*dev->sci_icmd = 0;
	*dev->sci_irecv = 0;
	while (len > 128) {
		wait = sci_data_wait;
		while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
		  (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
			if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
			  || !(*dev->sci_bus_csr & SCI_BUS_BSY)
			  || --wait < 0) {
#ifdef DEBUG
				if (sci_debug)
					printf("mlhdma_in fail: l%d i%x w%d\n",
					len, csr, wait);
#endif
				*dev->sci_mode &= ~SCI_MODE_DMA;
				return 0;
			}
		}

#define R1	(*buf++ = *sci_dma)
		R1; R1; R1; R1; R1; R1; R1; R1;
		R1; R1; R1; R1; R1; R1; R1; R1;
		R1; R1; R1; R1; R1; R1; R1; R1;
		R1; R1; R1; R1; R1; R1; R1; R1;
		R1; R1; R1; R1; R1; R1; R1; R1;
		R1; R1; R1; R1; R1; R1; R1; R1;
		R1; R1; R1; R1; R1; R1; R1; R1;
		R1; R1; R1; R1; R1; R1; R1; R1;
		R1; R1; R1; R1; R1; R1; R1; R1;
		R1; R1; R1; R1; R1; R1; R1; R1;
		R1; R1; R1; R1; R1; R1; R1; R1;
		R1; R1; R1; R1; R1; R1; R1; R1;
		R1; R1; R1; R1; R1; R1; R1; R1;
		R1; R1; R1; R1; R1; R1; R1; R1;
		R1; R1; R1; R1; R1; R1; R1; R1;
		R1; R1; R1; R1; R1; R1; R1; R1;
		len -= 128;
	}
	while (len > 0) {
		wait = sci_data_wait;
		while ((*sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) !=
		  (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) {
			if (!(*sci_csr & SCI_CSR_PHASE_MATCH)
			  || !(*dev->sci_bus_csr & SCI_BUS_BSY)
			  || --wait < 0) {
#ifdef DEBUG
				if (sci_debug)
					printf("mlhdma_in fail: l%d i%x w%d\n",
					len, csr, wait);
#endif
				*dev->sci_mode &= ~SCI_MODE_DMA;
				return 0;
			}
		}

		*buf++ = *sci_dma;
		len--;
	}

	QPRINTF(("mlhdma_in {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
	  len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5],
	  obp[6], obp[7], obp[8], obp[9]));

	*dev->sci_mode &= ~SCI_MODE_DMA;
	return 0;
}
Beispiel #11
0
/*
 * Adds the entry into the rpcbind database.
 * If PORTMAP, then for UDP and TCP, it adds the entries for version 2 also
 * Returns 0 if succeeds, else fails
 */
static int
init_transport(struct netconfig *nconf)
{
	int fd;
	struct t_bind taddr;
	struct addrinfo hints, *res = NULL;
	struct __rpc_sockinfo si;
	SVCXPRT	*my_xprt;
	int status;	/* bound checking ? */
	int aicode;
	int addrlen;
	struct sockaddr *sa;
	struct sockaddr_un sun;
	const int one = 1;

	if ((nconf->nc_semantics != NC_TPI_CLTS) &&
		(nconf->nc_semantics != NC_TPI_COTS) &&
		(nconf->nc_semantics != NC_TPI_COTS_ORD))
		return 1;	/* not my type */
#ifdef RPCBIND_DEBUG
	if (debugging) {
		int i;
		char **s;

		(void)fprintf(stderr, "%s: %ld lookup routines :\n",
		    nconf->nc_netid, nconf->nc_nlookups);
		for (i = 0, s = nconf->nc_lookups; i < nconf->nc_nlookups;
		     i++, s++)
			(void)fprintf(stderr, "[%d] - %s\n", i, *s);
	}
#endif

	/*
	 * XXX - using RPC library internal functions.
	 */
	if ((fd = __rpc_nconf2fd(nconf)) < 0) {
		if (errno == EAFNOSUPPORT)
			return 1;
		warn("Cannot create socket for `%s'", nconf->nc_netid);
		return 1;
	}

	if (!__rpc_nconf2sockinfo(nconf, &si)) {
		warnx("Cannot get information for `%s'", nconf->nc_netid);
		return 1;
	}

	if (si.si_af == AF_INET6) {
		/*
		 * We're doing host-based access checks here, so don't allow
		 * v4-in-v6 to confuse things.
		 */
		if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one,
		    sizeof one) < 0) {
			warn("Can't make socket ipv6 only");
			return 1;
		}
	}


	if (!strcmp(nconf->nc_netid, "local")) {
		(void)memset(&sun, 0, sizeof sun);
		sun.sun_family = AF_LOCAL;
#ifdef RPCBIND_RUMP
		(void)rump_sys_unlink(_PATH_RPCBINDSOCK);
#else
		(void)unlink(_PATH_RPCBINDSOCK);
#endif
		(void)strlcpy(sun.sun_path, _PATH_RPCBINDSOCK,
		    sizeof(sun.sun_path));
		sun.sun_len = SUN_LEN(&sun);
		addrlen = sizeof(struct sockaddr_un);
		sa = (struct sockaddr *)&sun;
	} else {
		/* Get rpcbind's address on this transport */

		(void)memset(&hints, 0, sizeof hints);
		hints.ai_flags = AI_PASSIVE;
		hints.ai_family = si.si_af;
		hints.ai_socktype = si.si_socktype;
		hints.ai_protocol = si.si_proto;
		if ((aicode = getaddrinfo(NULL, servname, &hints, &res)) != 0) {
			warnx("Cannot get local address for `%s' (%s)",
			    nconf->nc_netid, gai_strerror(aicode));
			return 1;
		}
		addrlen = res->ai_addrlen;
		sa = (struct sockaddr *)res->ai_addr;
	}

	if (bind(fd, sa, addrlen) < 0) {
		warn("Cannot bind `%s'", nconf->nc_netid);
		if (res != NULL)
			freeaddrinfo(res);
		return 1;
	}
#ifndef RPCBIND_RUMP
	if (sa->sa_family == AF_LOCAL)
		if (chmod(sun.sun_path, S_IRWXU|S_IRWXG|S_IRWXO) == -1)
			warn("Cannot chmod `%s'", sun.sun_path);
#endif

	/* Copy the address */
	taddr.addr.len = taddr.addr.maxlen = addrlen;
	taddr.addr.buf = malloc(addrlen);
	if (taddr.addr.buf == NULL) {
		warn("Cannot allocate memory for `%s' address",
		    nconf->nc_netid);
		if (res != NULL)
			freeaddrinfo(res);
		return 1;
	}
	(void)memcpy(taddr.addr.buf, sa, addrlen);
#ifdef RPCBIND_DEBUG
	if (debugging) {
		/* for debugging print out our universal address */
		char *uaddr;
		struct netbuf nb;

		nb.buf = sa;
		nb.len = nb.maxlen = sa->sa_len;
		uaddr = taddr2uaddr(nconf, &nb);
		(void)fprintf(stderr, "rpcbind: my address is %s fd=%d\n",
		    uaddr, fd);
		(void)free(uaddr);
	}
#endif

	if (res != NULL)
		freeaddrinfo(res);

	if (nconf->nc_semantics != NC_TPI_CLTS)
		listen(fd, SOMAXCONN);
		
	my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr, RPC_MAXDATASIZE,
	    RPC_MAXDATASIZE);
	if (my_xprt == NULL) {
		warnx("Could not create service for `%s'", nconf->nc_netid);
		goto error;
	}

#ifdef PORTMAP
	/*
	 * Register both the versions for tcp/ip, udp/ip and local.
	 */
	if ((strcmp(nconf->nc_protofmly, NC_INET) == 0 &&
		(strcmp(nconf->nc_proto, NC_TCP) == 0 ||
		strcmp(nconf->nc_proto, NC_UDP) == 0)) ||
		strcmp(nconf->nc_netid, "local") == 0) {
		struct pmaplist *pml;

		if (!svc_register(my_xprt, PMAPPROG, PMAPVERS,
			pmap_service, 0)) {
			warn("Could not register on `%s'", nconf->nc_netid);
			goto error;
		}
		pml = malloc(sizeof (struct pmaplist));
		if (pml == NULL) {
			warn("Cannot allocate memory");
			goto error;
		}
		pml->pml_map.pm_prog = PMAPPROG;
		pml->pml_map.pm_vers = PMAPVERS;
		pml->pml_map.pm_port = PMAPPORT;
		if (strcmp(nconf->nc_proto, NC_TCP) == 0) {
			if (tcptrans[0]) {
				warnx(
				    "Cannot have more than one TCP transport");
				free(pml);
				goto error;
			}
			tcptrans = strdup(nconf->nc_netid);
			if (tcptrans == NULL) {
				free(pml);
				warn("Cannot allocate memory");
				goto error;
			}
			pml->pml_map.pm_prot = IPPROTO_TCP;

			/* Let's snarf the universal address */
			/* "h1.h2.h3.h4.p1.p2" */
			tcp_uaddr = taddr2uaddr(nconf, &taddr.addr);
		} else if (strcmp(nconf->nc_proto, NC_UDP) == 0) {
			if (udptrans[0]) {
				free(pml);
				warnx(
				"Cannot have more than one UDP transport");
				goto error;
			}
			udptrans = strdup(nconf->nc_netid);
			if (udptrans == NULL) {
				free(pml);
				warn("Cannot allocate memory");
				goto error;
			}
			pml->pml_map.pm_prot = IPPROTO_UDP;

			/* Let's snarf the universal address */
			/* "h1.h2.h3.h4.p1.p2" */
			udp_uaddr = taddr2uaddr(nconf, &taddr.addr);
		}
		pml->pml_next = list_pml;
		list_pml = pml;

		/* Add version 3 information */
		pml = malloc(sizeof (struct pmaplist));
		if (pml == NULL) {
			warn("Cannot allocate memory");
			goto error;
		}
		pml->pml_map = list_pml->pml_map;
		pml->pml_map.pm_vers = RPCBVERS;
		pml->pml_next = list_pml;
		list_pml = pml;

		/* Add version 4 information */
		pml = malloc(sizeof (struct pmaplist));
		if (pml == NULL) {
			warn("Cannot allocate memory");
			goto error;
		}
		pml->pml_map = list_pml->pml_map;
		pml->pml_map.pm_vers = RPCBVERS4;
		pml->pml_next = list_pml;
		list_pml = pml;

		/* Also add version 2 stuff to rpcbind list */
		rbllist_add(PMAPPROG, PMAPVERS, nconf, &taddr.addr);
	}
#endif

	/* version 3 registration */
	if (!svc_reg(my_xprt, RPCBPROG, RPCBVERS, rpcb_service_3, NULL)) {
		warn("Could not register %s version 3", nconf->nc_netid);
		goto error;
	}
	rbllist_add(RPCBPROG, RPCBVERS, nconf, &taddr.addr);

	/* version 4 registration */
	if (!svc_reg(my_xprt, RPCBPROG, RPCBVERS4, rpcb_service_4, NULL)) {
		warn("Could not register %s version 4", nconf->nc_netid);
		goto error;
	}
	rbllist_add(RPCBPROG, RPCBVERS4, nconf, &taddr.addr);

	/* decide if bound checking works for this transport */
	status = add_bndlist(nconf, &taddr.addr);
#ifdef RPCBIND_DEBUG
	if (debugging) {
		if (status < 0) {
			fprintf(stderr, "Error in finding bind status for %s\n",
				nconf->nc_netid);
		} else if (status == 0) {
			fprintf(stderr, "check binding for %s\n",
				nconf->nc_netid);
		} else if (status > 0) {
			fprintf(stderr, "No check binding for %s\n",
				nconf->nc_netid);
		}
	}
#else
	__USE(status);
#endif
	/*
	 * rmtcall only supported on CLTS transports for now.
	 */
	if (nconf->nc_semantics == NC_TPI_CLTS) {
		status = create_rmtcall_fd(nconf);

#ifdef RPCBIND_DEBUG
		if (debugging) {
			if (status < 0) {
				fprintf(stderr,
				    "Could not create rmtcall fd for %s\n",
					nconf->nc_netid);
			} else {
				fprintf(stderr, "rmtcall fd for %s is %d\n",
					nconf->nc_netid, status);
			}
		}
#endif
	}
	return (0);
error:
#ifdef RPCBIND_RUMP
	(void)rump_sys_close(fd);
#else
	(void)close(fd);
#endif
	return (1);
}
static void
udf_doshedule(struct udf_mount *ump)
{
	struct buf *buf;
	struct timespec now, *last;
	struct strat_private *priv = PRIV(ump);
	void (*b_callback)(struct buf *);
	int new_queue;
	int error;

	buf = bufq_get(priv->queues[priv->cur_queue]);
	if (buf) {
		/* transfer from the current queue to the device queue */
		mutex_exit(&priv->discstrat_mutex);

		/* transform buffer to synchronous; XXX needed? */
		b_callback = buf->b_iodone;
		buf->b_iodone = NULL;
		CLR(buf->b_flags, B_ASYNC);

		/* issue and wait on completion */
		udf_issue_buf(ump, priv->cur_queue, buf);
		biowait(buf);

		mutex_enter(&priv->discstrat_mutex);

		/* if there is an error, repair this error, otherwise propagate */
		if (buf->b_error && ((buf->b_flags & B_READ) == 0)) {
			/* check what we need to do */
			panic("UDF write error, can't handle yet!\n");
		}

		/* propagate result to higher layers */
		if (b_callback) {
			buf->b_iodone = b_callback;
			(*buf->b_iodone)(buf);
		}

		return;
	}

	/* Check if we're idling in this state */
	vfs_timestamp(&now);
	last = &priv->last_queued[priv->cur_queue];
	if (ump->discinfo.mmc_class == MMC_CLASS_CD) {
		/* dont switch too fast for CD media; its expensive in time */
		if (now.tv_sec - last->tv_sec < 3)
			return;
	}

	/* check if we can/should switch */
	new_queue = priv->cur_queue;

	if (bufq_peek(priv->queues[UDF_SHED_READING]))
		new_queue = UDF_SHED_READING;
	if (bufq_peek(priv->queues[UDF_SHED_WRITING]))		/* only for unmount */
		new_queue = UDF_SHED_WRITING;
	if (bufq_peek(priv->queues[UDF_SHED_SEQWRITING]))
		new_queue = UDF_SHED_SEQWRITING;
	if (priv->cur_queue == UDF_SHED_READING) {
		if (new_queue == UDF_SHED_SEQWRITING) {
			/* TODO use flag to signal if this is needed */
			mutex_exit(&priv->discstrat_mutex);

			/* update trackinfo for data and metadata */
			error = udf_update_trackinfo(ump,
					&ump->data_track);
			assert(error == 0);
			error = udf_update_trackinfo(ump,
					&ump->metadata_track);
			assert(error == 0);
			mutex_enter(&priv->discstrat_mutex);
			__USE(error);
		}
	}

	if (new_queue != priv->cur_queue) {
		DPRINTF(SHEDULE, ("switching from %d to %d\n",
			priv->cur_queue, new_queue));
	}

	priv->cur_queue = new_queue;
}
static void
__BS(unmap)(void *v, bus_space_handle_t h, bus_size_t size, int acct)
{
#if !defined(_LP64) || defined(CHIP_EXTENT)
	bus_addr_t addr = 0;	/* initialize to appease gcc */
#endif
#ifndef _LP64
	bool handle_is_km;

	/* determine if h is addr obtained from uvm_km_alloc */
	handle_is_km = !(MIPS_KSEG0_P(h) || MIPS_KSEG1_P(h));
#ifdef __mips_n32
	if (handle_is_km == true)
		handle_is_km = !MIPS_XKPHYS_P(h);
#endif
	if (handle_is_km == true) {
		paddr_t pa;
		vaddr_t va = (vaddr_t)trunc_page(h);
		vsize_t sz = (vsize_t)round_page((h % PAGE_SIZE) + size);
		int s;

		s = splhigh();

		if (pmap_extract(pmap_kernel(), (vaddr_t)h, &pa) == false)
			panic("%s: pmap_extract failed", __func__);
		addr = (bus_addr_t)pa;
#if 0
		printf("%s:%d: addr %#"PRIxBUSADDR", sz %#"PRIxVSIZE"\n",
			__func__, __LINE__, addr, sz);
#endif
		/* sanity check: this is why we couldn't map w/ kseg[0,1] */
		KASSERT (((addr + sz) & ~MIPS_PHYS_MASK) != 0);

		pmap_kremove(va, sz);
		pmap_update(pmap_kernel());
		uvm_km_free(kernel_map, va, sz, UVM_KMF_VAONLY);

		splx(s);
	}
#endif	/* _LP64 */

#ifdef CHIP_EXTENT

	if (acct == 0)
		return;

#ifdef EXTENT_DEBUG
	printf("%s: freeing handle %#"PRIxBSH" for %#"PRIxBUSSIZE"\n",
		__S(__BS(unmap)), h, size);
#endif

#ifdef _LP64
	KASSERT(MIPS_XKPHYS_P(h));
	addr = MIPS_XKPHYS_TO_PHYS(h);
#else
	if (handle_is_km == false) {
		if (MIPS_KSEG0_P(h))
			addr = MIPS_KSEG0_TO_PHYS(h);
#ifdef __mips_n32
		else if (MIPS_XKPHYS_P(h))
			addr = MIPS_XKPHYS_TO_PHYS(h);
#endif
		else
			addr = MIPS_KSEG1_TO_PHYS(h);
	}
#endif

#ifdef CHIP_W1_BUS_START
	if (addr >= CHIP_W1_SYS_START(v) && addr <= CHIP_W1_SYS_END(v)) {
		addr = CHIP_W1_BUS_START(v) + (addr - CHIP_W1_SYS_START(v));
	} else
#endif
#ifdef CHIP_W2_BUS_START
	if (addr >= CHIP_W2_SYS_START(v) && addr <= CHIP_W2_SYS_END(v)) {
		addr = CHIP_W2_BUS_START(v) + (addr - CHIP_W2_SYS_START(v));
	} else
#endif
#ifdef CHIP_W3_BUS_START
	if (addr >= CHIP_W3_SYS_START(v) && addr <= CHIP_W3_SYS_END(v)) {
		addr = CHIP_W3_BUS_START(v) + (addr - CHIP_W3_SYS_START(v));
	} else
#endif
	{
		printf("\n");
#ifdef CHIP_W1_BUS_START
		printf("%s: sys window[1]=0x%lx-0x%lx\n",
		    __S(__BS(unmap)), (u_long)CHIP_W1_SYS_START(v),
		    (u_long)CHIP_W1_SYS_END(v));
#endif
#ifdef CHIP_W2_BUS_START
		printf("%s: sys window[2]=0x%lx-0x%lx\n",
		    __S(__BS(unmap)), (u_long)CHIP_W2_SYS_START(v),
		    (u_long)CHIP_W2_SYS_END(v));
#endif
#ifdef CHIP_W3_BUS_START
		printf("%s: sys window[3]=0x%lx-0x%lx\n",
		    __S(__BS(unmap)), (u_long)CHIP_W3_SYS_START(v),
		    (u_long)CHIP_W3_SYS_END(v));
#endif
		panic("%s: don't know how to unmap %#"PRIxBSH, __S(__BS(unmap)), h);
	}

#ifdef EXTENT_DEBUG
	printf("%s: freeing %#"PRIxBUSADDR" to %#"PRIxBUSADDR"\n",
	    __S(__BS(unmap)), addr, addr + size - 1);
#endif
	int error = extent_free(CHIP_EXTENT(v), addr, size,
	    EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0));
	if (error) {
		printf("%s: WARNING: could not unmap"
		    " %#"PRIxBUSADDR"-%#"PRIxBUSADDR" (error %d)\n",
		    __S(__BS(unmap)), addr, addr + size - 1, error);
#ifdef EXTENT_DEBUG
		extent_print(CHIP_EXTENT(v));
#endif
	}
#endif /* CHIP_EXTENT */
#if !defined(_LP64) || defined(CHIP_EXTENT)
	__USE(addr);
#endif
}