Beispiel #1
0
/********************************************************************************
 * Free all of the resources associated with (sc)
 *
 * Should not be called if the controller is active.
 */
static void
amr_pci_free(struct amr_softc *sc)
{
    void *p;

    debug_called(1);

    amr_free(sc);

    /* destroy data-transfer DMA tag */
    if (sc->amr_buffer_dmat)
	bus_dma_tag_destroy(sc->amr_buffer_dmat);
    if (sc->amr_buffer64_dmat)
	bus_dma_tag_destroy(sc->amr_buffer64_dmat);

    /* free and destroy DMA memory and tag for passthrough pool */
    if (sc->amr_ccb) {
	bus_dmamap_unload(sc->amr_ccb_dmat, sc->amr_ccb_dmamap);
	bus_dmamem_free(sc->amr_ccb_dmat, sc->amr_ccb, sc->amr_ccb_dmamap);
    }
    if (sc->amr_ccb_dmat)
	bus_dma_tag_destroy(sc->amr_ccb_dmat);

    /* free and destroy DMA memory and tag for s/g lists */
    if (sc->amr_sgtable) {
	bus_dmamap_unload(sc->amr_sg_dmat, sc->amr_sg_dmamap);
	bus_dmamem_free(sc->amr_sg_dmat, sc->amr_sgtable, sc->amr_sg_dmamap);
    }
    if (sc->amr_sg_dmat)
	bus_dma_tag_destroy(sc->amr_sg_dmat);

    /* free and destroy DMA memory and tag for mailbox */
    p = (void *)(uintptr_t)(volatile void *)sc->amr_mailbox64;
    if (sc->amr_mailbox) {
	bus_dmamap_unload(sc->amr_mailbox_dmat, sc->amr_mailbox_dmamap);
	bus_dmamem_free(sc->amr_mailbox_dmat, p, sc->amr_mailbox_dmamap);
    }
    if (sc->amr_mailbox_dmat)
	bus_dma_tag_destroy(sc->amr_mailbox_dmat);

    /* disconnect the interrupt handler */
    if (sc->amr_intr)
	bus_teardown_intr(sc->amr_dev, sc->amr_irq, sc->amr_intr);
    if (sc->amr_irq != NULL)
	bus_release_resource(sc->amr_dev, SYS_RES_IRQ, 0, sc->amr_irq);

    /* destroy the parent DMA tag */
    if (sc->amr_parent_dmat)
	bus_dma_tag_destroy(sc->amr_parent_dmat);

    /* release the register window mapping */
    if (sc->amr_reg != NULL)
	bus_release_resource(sc->amr_dev,
			     AMR_IS_QUARTZ(sc) ? SYS_RES_MEMORY : SYS_RES_IOPORT,
			     PCIR_BAR(0), sc->amr_reg);
}
Beispiel #2
0
static int
amr_pci_attach(device_t dev)
{
    struct amr_softc	*sc;
    int			rid, rtype, error;
    u_int32_t		command;

    debug("called");

    /*
     * Initialise softc.
     */
    sc = device_get_softc(dev);
    bzero(sc, sizeof(*sc));
    sc->amr_dev = dev;

    /*
     * Determine board type..
     */
    command = pci_read_config(dev, PCIR_COMMAND, 1);
    if ((pci_get_vendor(dev) == 0x8086) && (pci_get_device(dev) == 0x1960)) {
	sc->amr_type = AMR_TYPE_QUARTZ;

	/*
	 * Make sure we are going to be able to talk to this board.
	 */
	if ((command & PCIM_CMD_MEMEN) == 0) {
	    device_printf(dev, "memory window not available\n");
	    return(ENXIO);
	}

    } else {
	sc->amr_type = AMR_TYPE_STD;

	/*
	 * Make sure we are going to be able to talk to this board.
	 */
	if ((command & PCIM_CMD_PORTEN) == 0) {
	    device_printf(dev, "I/O window not available\n");
	    return(ENXIO);
	}
    }

    /*
     * Allocate the PCI register window.
     */
    rid = AMR_CFG_BASE;
    rtype = (sc->amr_type == AMR_TYPE_QUARTZ) ? SYS_RES_MEMORY : SYS_RES_IOPORT;
    sc->amr_reg = bus_alloc_resource(dev, rtype, &rid, 0, ~0, 1, RF_ACTIVE);
    if (sc->amr_reg == NULL) {
	device_printf(sc->amr_dev, "couldn't allocate register window\n");
	amr_free(sc);
	return(ENXIO);
    }
    sc->amr_btag = rman_get_bustag(sc->amr_reg);
    sc->amr_bhandle = rman_get_bushandle(sc->amr_reg);

    /*
     * Allocate the parent bus DMA tag appropriate for PCI.
     */
    error = bus_dma_tag_create(NULL, 			/* parent */
			       1, 0, 			/* alignment, boundary */
			       BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
			       BUS_SPACE_MAXADDR, 	/* highaddr */
			       NULL, NULL, 		/* filter, filterarg */
			       MAXBSIZE, AMR_NSEG,	/* maxsize, nsegments */
			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
			       BUS_DMA_ALLOCNOW,	/* flags */
			       &sc->amr_parent_dmat);
    if (error != 0) {
	device_printf(dev, "can't allocate parent DMA tag\n");
	amr_free(sc);
	return(ENOMEM);
    }

    /*
     * Do bus-independant initialisation.
     */
    error = amr_attach(sc);
    if (error != 0) {
	amr_free(sc);
	return(error);
    }
    
    /*
     * Start the controller.
     */
    amr_startup(sc);
    return(0);
}