コード例 #1
0
ファイル: ppc.c プロジェクト: MarginC/kame
int
ppc_probe(device_t dev)
{
#ifdef __i386__
	static short next_bios_ppc = 0;
#endif
	struct ppc_data *ppc;
	int error;
	u_long port;

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

	ppc->rid_irq = ppc->rid_drq = ppc->rid_ioport = 0;
	ppc->res_irq = ppc->res_drq = ppc->res_ioport = 0;

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

#ifdef __i386__
	/*
	 * If port not specified, use bios list.
	 */
	if (error) {
		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%x\n",
					(int) port);
		} else {
			device_printf(dev, "parallel port not found.\n");
			return ENXIO;
		}
		bus_set_resource(dev, SYS_RES_IOPORT, 0, port,
				 IO_LPTSIZE_EXTENDED);
	}
#endif
#ifdef __alpha__
	/*
	 * There isn't a bios list on alpha. Put it in the usual place.
	 */
	if (error) {
		bus_set_resource(dev, SYS_RES_IOPORT, 0, 0x3bc,
				 IO_LPTSIZE_NORMAL);
	}
#endif

	/* IO port is mandatory */

	/* Try "extended" IO port range...*/
	ppc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT,
					     &ppc->rid_ioport, 0, ~0,
					     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(dev, SYS_RES_IOPORT,
						      &ppc->rid_ioport, 0, ~0,
						      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->bsh = rman_get_bushandle(ppc->res_ioport);
	ppc->bst = rman_get_bustag(ppc->res_ioport);

	ppc->ppc_flags = device_get_flags(dev);

	if (!(ppc->ppc_flags & 0x20)) {
		ppc->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &ppc->rid_irq,
						  0ul, ~0ul, 1, RF_SHAREABLE);
		ppc->res_drq = bus_alloc_resource(dev, SYS_RES_DRQ, &ppc->rid_drq,
						  0ul, ~0ul, 1, 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_unit = device_get_unit(dev);
	ppc->ppc_model = GENERIC;

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

	ppc->ppc_type = PPC_TYPE_GENERIC;

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

	return (0);

error:
	if (ppc->res_irq != 0) {
		bus_release_resource(dev, SYS_RES_IRQ, ppc->rid_irq,
				     ppc->res_irq);
	}
	if (ppc->res_ioport != 0) {
		bus_deactivate_resource(dev, SYS_RES_IOPORT, ppc->rid_ioport,
					ppc->res_ioport);
		bus_release_resource(dev, SYS_RES_IOPORT, ppc->rid_ioport,
				     ppc->res_ioport);
	}
	if (ppc->res_drq != 0) {
		bus_deactivate_resource(dev, SYS_RES_DRQ, ppc->rid_drq,
					ppc->res_drq);
		bus_release_resource(dev, SYS_RES_DRQ, ppc->rid_drq,
				     ppc->res_drq);
	}
	return (ENXIO);
}
コード例 #2
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);
}