예제 #1
0
void
com_pnpbios_attach(device_t parent, device_t self, void *aux)
{
	struct com_pnpbios_softc *psc = device_private(self);
	struct com_softc *sc = &psc->sc_com;
	struct pnpbiosdev_attach_args *aa = aux;
	bus_space_tag_t iot;
	bus_space_handle_t ioh;
	int iobase;

	sc->sc_dev = self;

	if (pnpbios_getiobase(aa->pbt, aa->resc, 0, &iot, &iobase)) {
		aprint_error(": can't get iobase\n");
		return;
	}

	if ((!com_is_console(iot, iobase, &ioh)) &&
	    pnpbios_io_map(aa->pbt, aa->resc, 0, &iot, &ioh)) { 	
		aprint_error(": can't map i/o space\n");
		return;
	}

	COM_INIT_REGS(sc->sc_regs, iot, ioh, iobase);

	aprint_normal("\n");
	pnpbios_print_devres(self, aa);

	aprint_normal("%s", device_xname(self));

	/*
	 * if the chip isn't something we recognise skip it.
	 */
	if (com_probe_subr(&sc->sc_regs) == 0) {
		aprint_error(": com probe failed\n");
		return;
	}

	sc->sc_frequency = 115200 * 16;

	com_attach_subr(sc);

	psc->sc_ih = pnpbios_intr_establish(aa->pbt, aa->resc, 0, IPL_SERIAL,
					    comintr, sc);
}
예제 #2
0
void
lpt_pnpbios_attach(device_t parent, device_t self, void *aux)
{
	struct lpt_pnpbios_softc *psc = device_private(self);
	struct lpt_softc *sc = &psc->sc_lpt;
	struct pnpbiosdev_attach_args *aa = aux;

	sc->sc_dev = self;

	if (pnpbios_io_map(aa->pbt, aa->resc, 0, &sc->sc_iot, &sc->sc_ioh)) { 	
		printf(": can't map i/o space\n");
		return;
	}

	printf("\n");
	pnpbios_print_devres(self, aa);

	lpt_attach_subr(sc);

	sc->sc_ih = pnpbios_intr_establish(aa->pbt, aa->resc, 0, IPL_TTY,
					    lptintr, sc);
}
예제 #3
0
void
pciide_pnpbios_attach(device_t parent, device_t self, void *aux)
{
	struct pciide_softc *sc = device_private(self);
	struct pnpbiosdev_attach_args *aa = aux;
	struct pciide_channel *cp;
	struct ata_channel *wdc_cp;
	struct wdc_regs *wdr;
	bus_space_tag_t compat_iot;
	bus_space_handle_t cmd_baseioh, ctl_ioh;
	int i, drive, size;
	uint8_t idedma_ctl;

	sc->sc_wdcdev.sc_atac.atac_dev = self;

	aprint_naive(": disk controller\n");
	aprint_normal("\n");
	pnpbios_print_devres(self, aa);

	aprint_normal_dev(self, "Toshiba Extended IDE Controller\n");

	if (pnpbios_io_map(aa->pbt, aa->resc, 2, &sc->sc_dma_iot,
	    &sc->sc_dma_ioh) != 0) {
		aprint_error_dev(self, "unable to map DMA registers\n");
		return;
	}
	if (pnpbios_io_map(aa->pbt, aa->resc, 0, &compat_iot,
	    &cmd_baseioh) != 0) {
		aprint_error_dev(self, "unable to map command registers\n");
		return;
	}
	if (pnpbios_io_map(aa->pbt, aa->resc, 1, &compat_iot,
	    &ctl_ioh) != 0) {
		aprint_error_dev(self, "unable to map control register\n");
		return;
	}

	sc->sc_dmat = &pci_bus_dma_tag;

	cp = &sc->pciide_channels[0];
	sc->wdc_chanarray[0] = &cp->ata_channel;
	cp->ata_channel.ch_channel = 0;
	cp->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac;
	cp->ata_channel.ch_queue = malloc(sizeof(struct ata_queue),
					  M_DEVBUF, M_NOWAIT);
	cp->ata_channel.ch_ndrive = 2;
	if (cp->ata_channel.ch_queue == NULL) {
		aprint_error_dev(self, "unable to allocate memory for command "
		    "queue\n");
		return;
	}

	sc->sc_dma_ok = 1;
	for (i = 0; i < IDEDMA_NREGS; i++) {
		size = 4;
		if (size > (IDEDMA_SCH_OFFSET - i))
			size = IDEDMA_SCH_OFFSET - i;
		if (bus_space_subregion(sc->sc_dma_iot, sc->sc_dma_ioh,
		    i, size, &cp->dma_iohs[i]) != 0) {
			aprint_error_dev(self, "can't subregion offset %d "
			    "size %lu", i, (u_long)size);
			return;
		}
	}
	sc->sc_dma_maxsegsz = IDEDMA_BYTE_COUNT_MAX;
	sc->sc_dma_boundary = IDEDMA_BYTE_COUNT_ALIGN;
	sc->sc_wdcdev.dma_arg = sc;
	sc->sc_wdcdev.dma_init = pciide_dma_init;
	sc->sc_wdcdev.dma_start = pciide_dma_start;
	sc->sc_wdcdev.dma_finish = pciide_dma_finish;
	sc->sc_wdcdev.irqack = pciide_irqack;
	sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DMA;
	sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray;
	sc->sc_wdcdev.sc_atac.atac_nchannels = 1;
	sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA16 | ATAC_CAP_DATA32;
	sc->sc_wdcdev.sc_atac.atac_pio_cap = 0;
	sc->sc_wdcdev.sc_atac.atac_dma_cap = 0;		/* XXX */
	sc->sc_wdcdev.sc_atac.atac_udma_cap = 0;	/* XXX */

	wdc_allocate_regs(&sc->sc_wdcdev);

	wdc_cp = &cp->ata_channel;
	wdr = CHAN_TO_WDC_REGS(wdc_cp);
	wdr->cmd_iot = compat_iot;
	wdr->cmd_baseioh = cmd_baseioh;

	for (i = 0; i < WDC_NREG; i++) {
		if (bus_space_subregion(wdr->cmd_iot, wdr->cmd_baseioh, i,
		    i == 0 ? 4 : 1, &wdr->cmd_iohs[i]) != 0) {
			    aprint_error_dev(self, "unable to subregion "
				"control register\n");
			    return;
		}
	}
	wdc_init_shadow_regs(wdc_cp);

	wdr->ctl_iot = wdr->data32iot = compat_iot;
	wdr->ctl_ioh = wdr->data32ioh = ctl_ioh;

	cp->compat = 1;

	cp->ih = pnpbios_intr_establish(aa->pbt, aa->resc, 0, IPL_BIO,
					pciide_compat_intr, cp);

	wdcattach(wdc_cp);

	idedma_ctl = 0;
	for (drive = 0; drive < cp->ata_channel.ch_ndrive; drive++) {
		/*
		 * we have not probed the drives yet,
		 * allocate ressources for all of them.
		 */
		if (pciide_dma_table_setup(sc, 0, drive) != 0) {
			/* Abort DMA setup */
			aprint_error(
			    "%s:%d:%d: can't allocate DMA maps, "
			    "using PIO transfers\n",
			    device_xname(self), 0, drive);
			sc->sc_dma_ok = 0;
			sc->sc_wdcdev.sc_atac.atac_cap &= ~ATAC_CAP_DMA;
			sc->sc_wdcdev.irqack = NULL;
			idedma_ctl = 0;
			break;
		}
		idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
	}
	if (idedma_ctl != 0) {
		/* Add software bits in status register */
		bus_space_write_1(sc->sc_dma_iot,
		    cp->dma_iohs[IDEDMA_CTL], 0, idedma_ctl);
	}
}
예제 #4
0
void
fdc_pnpbios_attach(device_t parent, device_t self, void *aux)
{
        struct fdc_pnpbios_softc *pdc = device_private(self);
	struct fdc_softc *fdc = &pdc->sc_fdc;
	struct pnpbiosdev_attach_args *aa = aux;
        int size, base;
        
	aprint_normal("\n");

	fdc->sc_dev = self;
	fdc->sc_ic = aa->ic;

	if (pnpbios_io_map(aa->pbt, aa->resc, 0, &fdc->sc_iot,
            &pdc->sc_baseioh)) {
		aprint_error_dev(self, "unable to map I/O space\n");
		return;
	}

	/* 
         * Start accounting for "odd" pnpbios's. Some probe as 4 ports,
         * some as 6 and some don't give the ctl port back. 
         */

        if (pnpbios_getiosize(aa->pbt, aa->resc, 0, &size)) {
                aprint_error_dev(self, "can't get iobase size\n");
                return;
        }

        switch (size) {

        /* Easy case. This matches right up with what the fdc code expects. */
        case 4:
                fdc->sc_ioh = pdc->sc_baseioh;
                break;

        /* Map a subregion so this all lines up with the fdc code. */
        case 6:
                if (bus_space_subregion(fdc->sc_iot, pdc->sc_baseioh, 2, 4,
                    &fdc->sc_ioh)) {
                        aprint_error_dev(self,
			    "unable to subregion I/O space\n");
                        return;
                }
                break;
        default:
                aprint_error_dev(self, "unknown size: %d of io mapping\n", size);
                return;
        }
        
        /* 
         * XXX: This is bad. If the pnpbios claims only 1 I/O range then it's
         * omitting the controller I/O port. (One has to exist for there to
         * be a working fdc). Just try and force the mapping in. 
         */

        if (aa->resc->numio == 1) {

                if (pnpbios_getiobase(aa->pbt, aa->resc, 0, 0, &base)) {
                        aprint_error_dev(self, "can't get iobase\n");
                        return;
                }
                if (bus_space_map(fdc->sc_iot, base + size + 1, 1, 0,
                    &fdc->sc_fdctlioh)) {
                        aprint_error_dev(self,
			    "unable to force map CTL I/O space\n");
                        return;
                }
        } else if (pnpbios_io_map(aa->pbt, aa->resc, 1, &fdc->sc_iot,
            &fdc->sc_fdctlioh)) {
                aprint_error_dev(self, "unable to map CTL I/O space\n");
		return;
	}

	if (pnpbios_getdmachan(aa->pbt, aa->resc, 0, &fdc->sc_drq)) {
		aprint_error_dev(self, "unable to get DMA channel\n");
		return;
	}

	pnpbios_print_devres(self, aa);
        if (aa->resc->numio == 1)
                aprint_error_dev(self,
		    "ctl io %x didn't probe. Forced attach\n",
		    base + size + 1);

	fdc->sc_ih = pnpbios_intr_establish(aa->pbt, aa->resc, 0, IPL_BIO,
	    fdcintr, fdc);

	fdcattach(fdc);
}