Ejemplo n.º 1
0
static int
lpbb_callback(device_t dev, int index, caddr_t data)
{
	device_t ppbus = device_get_parent(dev);
	int error = 0;
	int how;

	switch (index) {
	case IIC_REQUEST_BUS:
		/* request the ppbus */
		how = *(int *)data;
		ppb_lock(ppbus);
		error = ppb_request_bus(ppbus, dev, how);
		ppb_unlock(ppbus);
		break;

	case IIC_RELEASE_BUS:
		/* release the ppbus */
		ppb_lock(ppbus);
		error = ppb_release_bus(ppbus, dev);
		ppb_unlock(ppbus);
		break;

	default:
		error = EINVAL;
	}

	return (error);
}
Ejemplo n.º 2
0
static int
lpbb_detect(device_t dev)
{
	device_t ppbus = device_get_parent(dev);

	ppb_lock(ppbus);
	if (ppb_request_bus(ppbus, dev, PPB_DONTWAIT)) {
		ppb_unlock(ppbus);
		device_printf(dev, "can't allocate ppbus\n");
		return (0);
	}

	lpbb_reset_bus(dev);

	if ((ppb_rstr(ppbus) & I2CKEY) ||
		((ppb_rstr(ppbus) & ALIM) != ALIM)) {
		ppb_release_bus(ppbus, dev);
		ppb_unlock(ppbus);
		return (0);
	}

	ppb_release_bus(ppbus, dev);
	ppb_unlock(ppbus);

	return (1);
}
Ejemplo n.º 3
0
/*
 * vpoio_attach()
 *
 * Low level attachment of vpo device
 *
 */
int
vpoio_attach(struct vpoio_data *vpo)
{
	DECLARE_NIBBLE_INBYTE_SUBMICROSEQ;
	device_t ppbus = device_get_parent(vpo->vpo_dev);
	int error = 0;

	vpo->vpo_nibble_inbyte_msq = (struct ppb_microseq *)malloc(
		sizeof(nibble_inbyte_submicroseq), M_DEVBUF, M_NOWAIT);

	if (!vpo->vpo_nibble_inbyte_msq)
		return (ENXIO);

	bcopy((void *)nibble_inbyte_submicroseq,
		(void *)vpo->vpo_nibble_inbyte_msq,
		sizeof(nibble_inbyte_submicroseq));

	ppb_MS_init_msq(vpo->vpo_nibble_inbyte_msq, 4,
		INB_NIBBLE_H, (void *)&(vpo)->vpo_nibble.h,
		INB_NIBBLE_L, (void *)&(vpo)->vpo_nibble.l,
		INB_NIBBLE_F, nibble_inbyte_hook,
		INB_NIBBLE_P, (void *)&(vpo)->vpo_nibble);

	/*
	 * Initialize mode dependent in/out microsequences
	 */
	ppb_lock(ppbus);
	if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, PPB_WAIT)))
		goto error;

	/* ppbus sets automatically the last mode entered during detection */
	switch (vpo->vpo_mode_found) {
	case VP0_MODE_EPP:
		ppb_MS_GET_init(ppbus, vpo->vpo_dev, epp17_instr_body);
		ppb_MS_PUT_init(ppbus, vpo->vpo_dev, epp17_outstr_body);
		device_printf(vpo->vpo_dev, "EPP mode\n");
		break;
	case VP0_MODE_PS2:
		ppb_MS_GET_init(ppbus, vpo->vpo_dev, ps2_inbyte_submicroseq);
		ppb_MS_PUT_init(ppbus, vpo->vpo_dev, spp_outbyte_submicroseq);
		device_printf(vpo->vpo_dev, "PS2 mode\n");
		break;
	case VP0_MODE_NIBBLE:
		ppb_MS_GET_init(ppbus, vpo->vpo_dev, vpo->vpo_nibble_inbyte_msq);
		ppb_MS_PUT_init(ppbus, vpo->vpo_dev, spp_outbyte_submicroseq);
		device_printf(vpo->vpo_dev, "NIBBLE mode\n");
		break;
	default:
		panic("vpo: unknown mode %d", vpo->vpo_mode_found);
	}

	ppb_release_bus(ppbus, vpo->vpo_dev);

error:
	ppb_unlock(ppbus);
	return (error);
}
Ejemplo n.º 4
0
static int
lpbb_reset(device_t dev, u_char speed, u_char addr, u_char * oldaddr)
{
	device_t ppbus = device_get_parent(dev);

	ppb_lock(ppbus);
	if (ppb_request_bus(ppbus, dev, PPB_DONTWAIT)) {
		ppb_unlock(ppbus);
		device_printf(dev, "can't allocate ppbus\n");
		return (0);
	}

	lpbb_reset_bus(dev);

	ppb_release_bus(ppbus, dev);
	ppb_unlock(ppbus);

	return (IIC_ENOADDR);
}
Ejemplo n.º 5
0
static int 
pcfclock_open(dev_t dev, int flag, int fms, struct thread *td)
{
	u_int unit = minor(dev);
	struct pcfclock_data *sc = UNITOSOFTC(unit);
	device_t pcfclockdev = UNITODEVICE(unit);
	device_t ppbus = device_get_parent(pcfclockdev);
	int res;
	
	if (!sc)
		return (ENXIO);

	if ((res = ppb_request_bus(ppbus, pcfclockdev,
		(flag & O_NONBLOCK) ? PPB_DONTWAIT : PPB_WAIT)))
		return (res);

	sc->count++;
	
	return (0);
}
Ejemplo n.º 6
0
/*
 * how	: PPB_WAIT or PPB_DONTWAIT
 */
static int
vpoio_connect(struct vpoio_data *vpo, int how)
{
	device_t ppbus = device_get_parent(vpo->vpo_dev);
	int error;
	int ret;

	if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, how))) {

#ifdef VP0_DEBUG
		printf("%s: can't request bus!\n", __func__);
#endif
		return (error);
	}

	if (PPB_IN_EPP_MODE(ppbus))
		ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_epp_microseq, &ret);
	else
		ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_spp_microseq, &ret);

	return (0);
}
Ejemplo n.º 7
0
/*
 * vpoio_detect()
 *
 * Detect and initialise the VP0 adapter.
 */
static int
vpoio_detect(struct vpoio_data *vpo)
{
	device_t ppbus = device_get_parent(vpo->vpo_dev);
	int error, ret;

	/* allocate the bus, then apply microsequences */
	if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, PPB_DONTWAIT)))
		return (error);

	/* Force disconnection */
	ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq, &ret);

	/* Try to enter EPP mode, then connect to the drive in EPP mode */
	if (ppb_set_mode(ppbus, PPB_EPP) != -1) {
		/* call manually the microseq instead of using the appropriate function
		 * since we already requested the ppbus */
		ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_epp_microseq, &ret);
	}

	/* If EPP mode switch failed or ZIP connection in EPP mode failed,
	 * try to connect in NIBBLE mode */
	if (!vpoio_in_disk_mode(vpo)) {

		/* The interface must be at least PS/2 or NIBBLE capable.
		 * There is no way to know if the ZIP will work with
		 * PS/2 mode since PS/2 and SPP both use the same connect
		 * sequence. One must supress PS/2 with boot flags if
		 * PS/2 mode fails (see ppc(4)).
		 */
		if (ppb_set_mode(ppbus, PPB_PS2) != -1) {
			vpo->vpo_mode_found = VP0_MODE_PS2;
		} else {
			if (ppb_set_mode(ppbus, PPB_NIBBLE) == -1)
				goto error;

			vpo->vpo_mode_found = VP0_MODE_NIBBLE;
		}

		/* Can't know if the interface is capable of PS/2 yet */
		ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_spp_microseq, &ret);
		if (!vpoio_in_disk_mode(vpo)) {
			vpo->vpo_mode_found = VP0_MODE_UNDEFINED;
			if (bootverbose)
				device_printf(vpo->vpo_dev,
				    "can't connect to the drive\n");

			/* disconnect and release the bus */
			ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq,
					&ret);
			goto error;
		}
	} else {
		vpo->vpo_mode_found = VP0_MODE_EPP;
	}

	/* send SCSI reset signal */
	vpoio_reset(vpo);

	ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq, &ret);

	/* ensure we are disconnected or daisy chained peripheral
	 * may cause serious problem to the disk */
	if (vpoio_in_disk_mode(vpo)) {
		if (bootverbose)
			device_printf(vpo->vpo_dev,
			    "can't disconnect from the drive\n");
		goto error;
	}

	ppb_release_bus(ppbus, vpo->vpo_dev);
	return (0);

error:
	ppb_release_bus(ppbus, vpo->vpo_dev);
	return (VP0_EINITFAILED);
}