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); }
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); }