Ejemplo n.º 1
0
/*
 * ppb_1284_get_state()
 *
 * Get IEEE1284 state
 */
int
ppb_1284_get_state(device_t bus)
{
        return (DEVTOSOFTC(bus)->state);
}
Ejemplo n.º 2
0
void
_ppb_assert_locked(device_t bus, const char *file, int line)
{

	mtx_assert_(DEVTOSOFTC(bus)->ppc_lock, MA_OWNED, file, line);
}
Ejemplo n.º 3
0
static int
pcf_ebus_attach(device_t dev)
{
	struct pcf_softc *sc;
	int rv = ENXIO;
	phandle_t node;
	uint64_t own_addr;

	sc = DEVTOSOFTC(dev);
	mtx_init(&sc->pcf_lock, device_get_nameunit(dev), "pcf", MTX_DEF);

	/* get OFW node of the pcf */
	if ((node = ofw_bus_get_node(dev)) == -1) {
		device_printf(dev, "cannot get OFW node\n");
		goto error;
	}

	/* IO port is mandatory */
	sc->res_ioport = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
	    &sc->rid_ioport, RF_ACTIVE);
	if (sc->res_ioport == 0) {
		device_printf(dev, "cannot reserve I/O port range\n");
		goto error;
	}

	sc->pcf_flags = device_get_flags(dev);

	/*
	 * XXX use poll-mode property?
	 */
	if (!(sc->pcf_flags & IIC_POLLED)) {
		sc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
		    &sc->rid_irq, RF_ACTIVE);
		if (sc->res_irq == 0) {
			device_printf(dev, "can't reserve irq, polled mode.\n");
			sc->pcf_flags |= IIC_POLLED;
		}
	}

	/*
	 * XXX on AXmp there's probably a second IRQ which is the fan fail
	 *     interrupt genererated by the PCF8574 at 0x78.
	 */

	/* get address of the pcf */
	if (OF_getprop(node, "own-address", &own_addr, sizeof(own_addr)) ==
	    -1) {
		device_printf(dev, "cannot get own address\n");
		goto error;
	}
	if (bootverbose)
		device_printf(dev, "PCF8584 address: 0x%08llx\n", (unsigned
		    long long)own_addr);

	/* reset the chip */
	pcf_rst_card(dev, IIC_FASTEST, own_addr, NULL);

	if (sc->res_irq) {
		rv = bus_setup_intr(dev, sc->res_irq,
		    INTR_TYPE_NET /* | INTR_ENTROPY */, NULL, pcf_intr, sc,
		    &sc->intr_cookie);
		if (rv) {
			device_printf(dev, "could not setup IRQ\n");
			goto error;
		}
	}

	if ((sc->iicbus = device_add_child(dev, "iicbus", -1)) == NULL)
		device_printf(dev, "could not allocate iicbus instance\n");

	/* probe and attach the iicbus */
	bus_generic_attach(dev);

	return (0);

error:
	if (sc->res_irq != 0) {
		bus_release_resource(dev, SYS_RES_IRQ, sc->rid_irq,
		    sc->res_irq);
	}
	if (sc->res_ioport != 0) {
		bus_release_resource(dev, SYS_RES_MEMORY, sc->rid_ioport,
		    sc->res_ioport);
	}
	mtx_destroy(&sc->pcf_lock);
	return (rv);
}
Ejemplo n.º 4
0
static void
pcfintr(void *arg)
{
	device_t pcfdev = (device_t)arg;
	struct pcf_softc *pcf = DEVTOSOFTC(pcfdev);

	char data, status, addr;
	char error = 0;

	status = PCF_GET_S1(pcf);

	if (status & PIN) {
		device_printf(pcfdev, "spurious interrupt, status=0x%x\n", status & 0xff);

		goto error;
	}

	if (status & LAB)
		device_printf(pcfdev, "bus arbitration lost!\n");

	if (status & BER) {
		error = IIC_EBUSERR;
		iicbus_intr(pcf->iicbus, INTR_ERROR, &error);

		goto error;
	}

	do {
		status = PCF_GET_S1(pcf);

		switch(pcf->pcf_slave_mode) {

		case SLAVE_TRANSMITTER:
			if (status & LRB) {
				/* ack interrupt line */
				dummy_write(pcf);

				/* no ack, don't send anymore */
				pcf->pcf_slave_mode = SLAVE_RECEIVER;

				iicbus_intr(pcf->iicbus, INTR_NOACK, NULL);
				break;
			}

			/* get data from upper code */
			iicbus_intr(pcf->iicbus, INTR_TRANSMIT, &data);

			PCF_SET_S0(pcf, data);
			break;

		case SLAVE_RECEIVER:
			if (status & AAS) {
				addr = PCF_GET_S0(pcf);

				if (status & AD0)
					iicbus_intr(pcf->iicbus, INTR_GENERAL, &addr);
				else
					iicbus_intr(pcf->iicbus, INTR_START, &addr);

				if (addr & LSB) {
					pcf->pcf_slave_mode = SLAVE_TRANSMITTER;

					/* get the first char from upper code */
					iicbus_intr(pcf->iicbus, INTR_TRANSMIT, &data);

					/* send first data byte */
					PCF_SET_S0(pcf, data);
				}

				break;
			}

			/* stop condition received? */
			if (status & STS) {
				/* ack interrupt line */
				dummy_read(pcf);

				/* emulate intr stop condition */
				iicbus_intr(pcf->iicbus, INTR_STOP, NULL);

			} else {
				/* get data, ack interrupt line */
				data = PCF_GET_S0(pcf);

				/* deliver the character */
				iicbus_intr(pcf->iicbus, INTR_RECEIVE, &data);
			}
			break;

		    default:
			panic("%s: unknown slave mode (%d)!", __func__,
				pcf->pcf_slave_mode);
		    }

	} while ((PCF_GET_S1(pcf) & PIN) == 0);

	return;

error:
	/* unknown event on bus...reset PCF */
	PCF_SET_S1(pcf, PIN|ES0|ENI|ACK);

	pcf->pcf_slave_mode = SLAVE_RECEIVER;

	return;
}
Ejemplo n.º 5
0
static int
pcf_isa_attach(device_t dev)
{
	struct pcf_softc *sc;
	int rv = ENXIO;

	sc = DEVTOSOFTC(dev);
	mtx_init(&sc->pcf_lock, device_get_nameunit(dev), "pcf", MTX_DEF);

	/* IO port is mandatory */
	sc->res_ioport = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
						&sc->rid_ioport, RF_ACTIVE);
	if (sc->res_ioport == 0) {
		device_printf(dev, "cannot reserve I/O port range\n");
		goto error;
	}

	sc->pcf_flags = device_get_flags(dev);

	if (!(sc->pcf_flags & IIC_POLLED)) {
		sc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->rid_irq,
						     RF_ACTIVE);
		if (sc->res_irq == 0) {
			device_printf(dev, "can't reserve irq, polled mode.\n");
			sc->pcf_flags |= IIC_POLLED;
		}
	}

	/* reset the chip */
	pcf_rst_card(dev, IIC_FASTEST, PCF_DEFAULT_ADDR, NULL);

	if (sc->res_irq) {
		rv = bus_setup_intr(dev, sc->res_irq,
				    INTR_TYPE_NET /* | INTR_ENTROPY */,
				    NULL, pcf_intr, sc, &sc->intr_cookie);
		if (rv) {
			device_printf(dev, "could not setup IRQ\n");
			goto error;
		}
	}

	if ((sc->iicbus = device_add_child(dev, "iicbus", -1)) == NULL)
		device_printf(dev, "could not allocate iicbus instance\n");

	/* probe and attach the iicbus */
	bus_generic_attach(dev);

	return (0);

error:
	if (sc->res_irq != 0) {
		bus_release_resource(dev, SYS_RES_IRQ, sc->rid_irq,
				     sc->res_irq);
	}
	if (sc->res_ioport != 0) {
		bus_release_resource(dev, SYS_RES_IOPORT, sc->rid_ioport,
				     sc->res_ioport);
	}
	mtx_destroy(&sc->pcf_lock);
	return (rv);
}
Ejemplo n.º 6
0
u_char
ppc_io(device_t ppcdev, int iop, u_char *addr, int cnt, u_char byte)
{
	struct ppc_data *ppc = DEVTOSOFTC(ppcdev);

	PPC_ASSERT_LOCKED(ppc);
	switch (iop) {
	case PPB_OUTSB_EPP:
	    bus_write_multi_1(ppc->res_ioport, PPC_EPP_DATA, addr, cnt);
		break;
	case PPB_OUTSW_EPP:
	    bus_write_multi_2(ppc->res_ioport, PPC_EPP_DATA, (u_int16_t *)addr, cnt);
		break;
	case PPB_OUTSL_EPP:
	    bus_write_multi_4(ppc->res_ioport, PPC_EPP_DATA, (u_int32_t *)addr, cnt);
		break;
	case PPB_INSB_EPP:
	    bus_read_multi_1(ppc->res_ioport, PPC_EPP_DATA, addr, cnt);
		break;
	case PPB_INSW_EPP:
	    bus_read_multi_2(ppc->res_ioport, PPC_EPP_DATA, (u_int16_t *)addr, cnt);
		break;
	case PPB_INSL_EPP:
	    bus_read_multi_4(ppc->res_ioport, PPC_EPP_DATA, (u_int32_t *)addr, cnt);
		break;
	case PPB_RDTR:
		return (r_dtr(ppc));
	case PPB_RSTR:
		return (r_str(ppc));
	case PPB_RCTR:
		return (r_ctr(ppc));
	case PPB_REPP_A:
		return (r_epp_A(ppc));
	case PPB_REPP_D:
		return (r_epp_D(ppc));
	case PPB_RECR:
		return (r_ecr(ppc));
	case PPB_RFIFO:
		return (r_fifo(ppc));
	case PPB_WDTR:
		w_dtr(ppc, byte);
		break;
	case PPB_WSTR:
		w_str(ppc, byte);
		break;
	case PPB_WCTR:
		w_ctr(ppc, byte);
		break;
	case PPB_WEPP_A:
		w_epp_A(ppc, byte);
		break;
	case PPB_WEPP_D:
		w_epp_D(ppc, byte);
		break;
	case PPB_WECR:
		w_ecr(ppc, byte);
		break;
	case PPB_WFIFO:
		w_fifo(ppc, byte);
		break;
	default:
		panic("%s: unknown I/O operation", __func__);
		break;
	}

	return (0);	/* not significative */
}
Ejemplo n.º 7
0
int
ppc_probe(device_t dev, int rid)
{
#ifdef __i386__
	static short next_bios_ppc = 0;
#ifdef PC98
	unsigned int pc98_ieee_mode = 0x00;
	unsigned int tmp;
#endif
#endif
	struct ppc_data *ppc;
	int error;
	rman_res_t port;

	/*
	 * Allocate the ppc_data structure.
	 */
	ppc = DEVTOSOFTC(dev);
	bzero(ppc, sizeof(struct ppc_data));

	ppc->rid_ioport = rid;

	/* retrieve ISA parameters */
	error = bus_get_resource(dev, SYS_RES_IOPORT, rid, &port, NULL);

#ifdef __i386__
	/*
	 * If port not specified, use bios list.
	 */
	if (error) {
#ifdef PC98
		if (next_bios_ppc == 0) {
			/* Use default IEEE-1284 port of NEC PC-98x1 */
			port = PC98_IEEE_1284_PORT;
			next_bios_ppc += 1;
			if (bootverbose)
				device_printf(dev,
				    "parallel port found at 0x%lx\n", port);
		}
#else
		if ((next_bios_ppc < BIOS_MAX_PPC) &&
		    (*(BIOS_PORTS + next_bios_ppc) != 0)) {
			port = *(BIOS_PORTS + next_bios_ppc++);
			if (bootverbose)
				device_printf(dev,
				    "parallel port found at 0x%lx\n", port);
		} else {
			device_printf(dev, "parallel port not found.\n");
			return (ENXIO);
		}
#endif	/* PC98 */
		bus_set_resource(dev, SYS_RES_IOPORT, rid, port,
				 IO_LPTSIZE_EXTENDED);
	}
#endif

	/* IO port is mandatory */

	/* Try "extended" IO port range...*/
	ppc->res_ioport = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT,
						      &ppc->rid_ioport,
						      IO_LPTSIZE_EXTENDED,
						      RF_ACTIVE);

	if (ppc->res_ioport != 0) {
		if (bootverbose)
			device_printf(dev, "using extended I/O port range\n");
	} else {
		/* Failed? If so, then try the "normal" IO port range... */
		 ppc->res_ioport = bus_alloc_resource_anywhere(dev,
		 	 				       SYS_RES_IOPORT,
							       &ppc->rid_ioport,
							       IO_LPTSIZE_NORMAL,
							       RF_ACTIVE);
		if (ppc->res_ioport != 0) {
			if (bootverbose)
				device_printf(dev, "using normal I/O port range\n");
		} else {
			device_printf(dev, "cannot reserve I/O port range\n");
			goto error;
		}
	}

 	ppc->ppc_base = rman_get_start(ppc->res_ioport);

	ppc->ppc_flags = device_get_flags(dev);

	if (!(ppc->ppc_flags & 0x20)) {
		ppc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
						      &ppc->rid_irq,
						      RF_SHAREABLE);
		ppc->res_drq = bus_alloc_resource_any(dev, SYS_RES_DRQ,
						      &ppc->rid_drq,
						      RF_ACTIVE);
	}

	if (ppc->res_irq)
		ppc->ppc_irq = rman_get_start(ppc->res_irq);
	if (ppc->res_drq)
		ppc->ppc_dmachan = rman_get_start(ppc->res_drq);

	ppc->ppc_dev = dev;
	ppc->ppc_model = GENERIC;

	ppc->ppc_mode = PPB_COMPATIBLE;
	ppc->ppc_epp = (ppc->ppc_flags & 0x10) >> 4;

	ppc->ppc_type = PPC_TYPE_GENERIC;

#if defined(__i386__) && defined(PC98)
	/*
	 * IEEE STD 1284 Function Check and Enable
	 * for default IEEE-1284 port of NEC PC-98x1
	 */
	if (ppc->ppc_base == PC98_IEEE_1284_PORT &&
	    !(ppc->ppc_flags & PC98_IEEE_1284_DISABLE)) {
		tmp = inb(ppc->ppc_base + PPC_1284_ENABLE);
		pc98_ieee_mode = tmp;
		if ((tmp & 0x10) == 0x10) {
			outb(ppc->ppc_base + PPC_1284_ENABLE, tmp & ~0x10);
			tmp = inb(ppc->ppc_base + PPC_1284_ENABLE);
			if ((tmp & 0x10) == 0x10)
				goto error;
		} else {
			outb(ppc->ppc_base + PPC_1284_ENABLE, tmp | 0x10);
			tmp = inb(ppc->ppc_base + PPC_1284_ENABLE);
			if ((tmp & 0x10) != 0x10)
				goto error;
		}
		outb(ppc->ppc_base + PPC_1284_ENABLE, pc98_ieee_mode | 0x10);
	}
#endif

	/*
	 * Try to detect the chipset and its mode.
	 */
	if (ppc_detect(ppc, ppc->ppc_flags & 0xf))
		goto error;

	return (0);

error:
#if defined(__i386__) && defined(PC98)
	if (ppc->ppc_base == PC98_IEEE_1284_PORT &&
	    !(ppc->ppc_flags & PC98_IEEE_1284_DISABLE)) {
		outb(ppc->ppc_base + PPC_1284_ENABLE, pc98_ieee_mode);
	}
#endif
	if (ppc->res_irq != 0) {
		bus_release_resource(dev, SYS_RES_IRQ, ppc->rid_irq,
				     ppc->res_irq);
	}
	if (ppc->res_ioport != 0) {
		bus_release_resource(dev, SYS_RES_IOPORT, ppc->rid_ioport,
				     ppc->res_ioport);
	}
	if (ppc->res_drq != 0) {
		bus_release_resource(dev, SYS_RES_DRQ, ppc->rid_drq,
				     ppc->res_drq);
	}
	return (ENXIO);
}
Ejemplo n.º 8
0
/*
 * ppc_exec_microseq()
 *
 * Execute a microsequence.
 * Microsequence mechanism is supposed to handle fast I/O operations.
 */
int
ppc_exec_microseq(device_t dev, struct ppb_microseq **p_msq)
{
	struct ppc_data *ppc = DEVTOSOFTC(dev);
	struct ppb_microseq *mi;
	char cc, *p;
	int i, iter, len;
	int error;

	register int reg;
	register char mask;
	register int accum = 0;
	register char *ptr = 0;

	struct ppb_microseq *stack = 0;

/* microsequence registers are equivalent to PC-like port registers */

#define r_reg(reg,ppc) (bus_read_1((ppc)->res_ioport, reg))
#define w_reg(reg, ppc, byte) (bus_write_1((ppc)->res_ioport, reg, byte))

#define INCR_PC (mi ++)		/* increment program counter */

	PPC_ASSERT_LOCKED(ppc);
	mi = *p_msq;
	for (;;) {
		switch (mi->opcode) {
		case MS_OP_RSET:
			cc = r_reg(mi->arg[0].i, ppc);
			cc &= (char)mi->arg[2].i;	/* clear mask */
			cc |= (char)mi->arg[1].i;	/* assert mask */
			w_reg(mi->arg[0].i, ppc, cc);
			INCR_PC;
			break;

		case MS_OP_RASSERT_P:
			reg = mi->arg[1].i;
			ptr = ppc->ppc_ptr;

			if ((len = mi->arg[0].i) == MS_ACCUM) {
				accum = ppc->ppc_accum;
				for (; accum; accum--)
					w_reg(reg, ppc, *ptr++);
				ppc->ppc_accum = accum;
			} else
				for (i=0; i<len; i++)
					w_reg(reg, ppc, *ptr++);
			ppc->ppc_ptr = ptr;

			INCR_PC;
			break;

		case MS_OP_RFETCH_P:
			reg = mi->arg[1].i;
			mask = (char)mi->arg[2].i;
			ptr = ppc->ppc_ptr;

			if ((len = mi->arg[0].i) == MS_ACCUM) {
				accum = ppc->ppc_accum;
				for (; accum; accum--)
					*ptr++ = r_reg(reg, ppc) & mask;
				ppc->ppc_accum = accum;
			} else
				for (i=0; i<len; i++)
					*ptr++ = r_reg(reg, ppc) & mask;
			ppc->ppc_ptr = ptr;

			INCR_PC;
			break;

		case MS_OP_RFETCH:
			*((char *) mi->arg[2].p) = r_reg(mi->arg[0].i, ppc) &
							(char)mi->arg[1].i;
			INCR_PC;
			break;

		case MS_OP_RASSERT:
		case MS_OP_DELAY:

		/* let's suppose the next instr. is the same */
		prefetch:
			for (;mi->opcode == MS_OP_RASSERT; INCR_PC)
				w_reg(mi->arg[0].i, ppc, (char)mi->arg[1].i);

			if (mi->opcode == MS_OP_DELAY) {
				DELAY(mi->arg[0].i);
				INCR_PC;
				goto prefetch;
			}
			break;

		case MS_OP_ADELAY:
			if (mi->arg[0].i) {
				PPC_UNLOCK(ppc);
				pause("ppbdelay", mi->arg[0].i * (hz/1000));
				PPC_LOCK(ppc);
			}
			INCR_PC;
			break;

		case MS_OP_TRIG:
			reg = mi->arg[0].i;
			iter = mi->arg[1].i;
			p = (char *)mi->arg[2].p;

			/* XXX delay limited to 255 us */
			for (i=0; i<iter; i++) {
				w_reg(reg, ppc, *p++);
				DELAY((unsigned char)*p++);
			}
			INCR_PC;
			break;

		case MS_OP_SET:
			ppc->ppc_accum = mi->arg[0].i;
			INCR_PC;
			break;

		case MS_OP_DBRA:
			if (--ppc->ppc_accum > 0)
				mi += mi->arg[0].i;
			INCR_PC;
			break;

		case MS_OP_BRSET:
			cc = r_str(ppc);
			if ((cc & (char)mi->arg[0].i) == (char)mi->arg[0].i)
				mi += mi->arg[1].i;
			INCR_PC;
			break;

		case MS_OP_BRCLEAR:
			cc = r_str(ppc);
			if ((cc & (char)mi->arg[0].i) == 0)
				mi += mi->arg[1].i;
			INCR_PC;
			break;

		case MS_OP_BRSTAT:
			cc = r_str(ppc);
			if ((cc & ((char)mi->arg[0].i | (char)mi->arg[1].i)) ==
							(char)mi->arg[0].i)
				mi += mi->arg[2].i;
			INCR_PC;
			break;

		case MS_OP_C_CALL:
			/*
			 * If the C call returns !0 then end the microseq.
			 * The current state of ptr is passed to the C function
			 */
			if ((error = mi->arg[0].f(mi->arg[1].p, ppc->ppc_ptr)))
				return (error);

			INCR_PC;
			break;

		case MS_OP_PTR:
			ppc->ppc_ptr = (char *)mi->arg[0].p;
			INCR_PC;
			break;

		case MS_OP_CALL:
			if (stack)
				panic("%s: too much calls", __func__);

			if (mi->arg[0].p) {
				/* store the state of the actual
				 * microsequence
				 */
				stack = mi;

				/* jump to the new microsequence */
				mi = (struct ppb_microseq *)mi->arg[0].p;
			} else
				INCR_PC;

			break;

		case MS_OP_SUBRET:
			/* retrieve microseq and pc state before the call */
			mi = stack;

			/* reset the stack */
			stack = 0;

			/* XXX return code */

			INCR_PC;
			break;

		case MS_OP_PUT:
		case MS_OP_GET:
		case MS_OP_RET:
			/* can't return to ppb level during the execution
			 * of a submicrosequence */
			if (stack)
				panic("%s: can't return to ppb level",
								__func__);

			/* update pc for ppb level of execution */
			*p_msq = mi;

			/* return to ppb level of execution */
			return (0);

		default:
			panic("%s: unknown microsequence opcode 0x%x",
			    __func__, mi->opcode);
		}
	}

	/* unreached */
}
Ejemplo n.º 9
0
static int
envctrl_attach(device_t dev)
{
	struct pcf_softc *sc;
	int rv = ENXIO;

	sc = DEVTOSOFTC(dev);
	bzero(sc, sizeof(struct pcf_softc));

	/* IO port is mandatory */
	sc->res_ioport = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
						&sc->rid_ioport, RF_ACTIVE);
	if (sc->res_ioport == 0) {
		device_printf(dev, "cannot reserve I/O port range\n");
		goto error;
	}
	sc->bt_ioport = rman_get_bustag(sc->res_ioport);
	sc->bh_ioport = rman_get_bushandle(sc->res_ioport);

	sc->pcf_flags = device_get_flags(dev);

	if (!(sc->pcf_flags & IIC_POLLED)) {
		sc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->rid_irq,
						     RF_ACTIVE);
		if (sc->res_irq == 0) {
			device_printf(dev, "can't reserve irq, polled mode.\n");
			sc->pcf_flags |= IIC_POLLED;
		}
	}

	/* reset the chip */
	pcf_rst_card(dev, IIC_FASTEST, PCF_DEFAULT_ADDR, NULL);

	rv = BUS_SETUP_INTR(device_get_parent(dev), dev, sc->res_irq,
			    INTR_TYPE_NET /* | INTR_ENTROPY */,
			    pcf_intr, sc, &sc->intr_cookie);
	if (rv) {
		device_printf(dev, "could not setup IRQ\n");
		goto error;
	}

	if ((sc->iicbus = device_add_child(dev, "iicbus", -1)) == NULL)
		device_printf(dev, "could not allocate iicbus instance\n");

	/* probe and attach the iicbus */
	bus_generic_attach(dev);

	return (0);

error:
	if (sc->res_irq != 0) {
		bus_deactivate_resource(dev, SYS_RES_IRQ, sc->rid_irq,
					sc->res_irq);
		bus_release_resource(dev, SYS_RES_IRQ, sc->rid_irq,
				     sc->res_irq);
	}
	if (sc->res_ioport != 0) {
		bus_deactivate_resource(dev, SYS_RES_IOPORT, sc->rid_ioport,
					sc->res_ioport);
		bus_release_resource(dev, SYS_RES_IOPORT, sc->rid_ioport,
				     sc->res_ioport);
	}
	return (rv);
}