Exemple #1
0
static void
cmd680_channel_map(struct pci_attach_args *pa, struct pciide_softc *sc,
    int channel)
{
	struct pciide_channel *cp = &sc->pciide_channels[channel];
	bus_size_t cmdsize, ctlsize;
	int interface, i, reg;
	static const u_int8_t init_val[] =
	    {             0x8a, 0x32, 0x8a, 0x32, 0x8a, 0x32,
	      0x92, 0x43, 0x92, 0x43, 0x09, 0x40, 0x09, 0x40 };

	if (PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_MASS_STORAGE_IDE) {
		interface = PCIIDE_INTERFACE_SETTABLE(0) |
		    PCIIDE_INTERFACE_SETTABLE(1);
		interface |= PCIIDE_INTERFACE_PCI(0) |
		    PCIIDE_INTERFACE_PCI(1);
	} else {
		interface = PCI_INTERFACE(pa->pa_class);
	}

	sc->wdc_chanarray[channel] = &cp->wdc_channel;
	cp->name = PCIIDE_CHANNEL_NAME(channel);
	cp->wdc_channel.ch_channel = channel;
	cp->wdc_channel.ch_wdc = &sc->sc_wdcdev;

	cp->wdc_channel.ch_queue =
	    malloc(sizeof(struct ata_queue), M_DEVBUF, M_NOWAIT);
	if (cp->wdc_channel.ch_queue == NULL) {
		aprint_error("%s %s channel: "
		    "can't allocate memory for command queue",
		    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
		    return;
	}

	/* XXX */
	reg = 0xa2 + channel * 16;
	for (i = 0; i < sizeof(init_val); i++)
		pciide_pci_write(sc->sc_pc, sc->sc_tag, reg + i, init_val[i]);

	aprint_normal("%s: %s channel %s to %s mode\n",
	    sc->sc_wdcdev.sc_dev.dv_xname, cp->name,
	    (interface & PCIIDE_INTERFACE_SETTABLE(channel)) ?
	    "configured" : "wired",
	    (interface & PCIIDE_INTERFACE_PCI(channel)) ?
	    "native-PCI" : "compatibility");

	pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, pciide_pci_intr);
}
Exemple #2
0
static void
cy693_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa)
{
    struct pciide_channel *cp;
    pcireg_t interface = PCI_INTERFACE(pa->pa_class);

    if (pciide_chipen(sc, pa) == 0)
        return;

    /*
     * this chip has 2 PCI IDE functions, one for primary and one for
     * secondary. So we need to call pciide_mapregs_compat() with
     * the real channel
     */
    if (pa->pa_function == 1) {
        sc->sc_cy_compatchan = 0;
    } else if (pa->pa_function == 2) {
        sc->sc_cy_compatchan = 1;
    } else {
        aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev,
                         "unexpected PCI function %d\n", pa->pa_function);
        return;
    }
    if (interface & PCIIDE_INTERFACE_BUS_MASTER_DMA) {
        aprint_verbose_dev(sc->sc_wdcdev.sc_atac.atac_dev,
                           "bus-master DMA support present\n");
        pciide_mapreg_dma(sc, pa);
    } else {
        aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev,
                          "hardware does not support DMA\n");
        sc->sc_dma_ok = 0;
    }

    sc->sc_cy_handle = cy82c693_init(pa->pa_iot);
    if (sc->sc_cy_handle == NULL) {
        aprint_error_dev(sc->sc_wdcdev.sc_atac.atac_dev,
                         "unable to map hyperCache control registers\n");
        sc->sc_dma_ok = 0;
    }

    sc->sc_wdcdev.sc_atac.atac_cap = ATAC_CAP_DATA16 | ATAC_CAP_DATA32;
    if (sc->sc_dma_ok) {
        sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DMA;
        sc->sc_wdcdev.irqack = pciide_irqack;
    }
    sc->sc_wdcdev.sc_atac.atac_pio_cap = 4;
    sc->sc_wdcdev.sc_atac.atac_dma_cap = 2;
    sc->sc_wdcdev.sc_atac.atac_set_modes = cy693_setup_channel;

    sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray;
    sc->sc_wdcdev.sc_atac.atac_nchannels = 1;
    sc->sc_wdcdev.wdc_maxdrives = 2;

    wdc_allocate_regs(&sc->sc_wdcdev);

    /* Only one channel for this chip; if we are here it's enabled */
    cp = &sc->pciide_channels[0];
    sc->wdc_chanarray[0] = &cp->ata_channel;
    cp->name = PCIIDE_CHANNEL_NAME(0);
    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);
    if (cp->ata_channel.ch_queue == NULL) {
        aprint_error("%s primary channel: "
                     "can't allocate memory for command queue",
                     device_xname(sc->sc_wdcdev.sc_atac.atac_dev));
        return;
    }
    aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev,
                      "primary channel %s to ",
                      (interface & PCIIDE_INTERFACE_SETTABLE(0)) ?
                      "configured" : "wired");
    if (interface & PCIIDE_INTERFACE_PCI(0)) {
        aprint_normal("native-PCI mode\n");
        pciide_mapregs_native(pa, cp, pciide_pci_intr);
    } else {
        aprint_normal("compatibility mode\n");
        pciide_mapregs_compat(pa, cp, sc->sc_cy_compatchan);
        if ((cp->ata_channel.ch_flags & ATACH_DISABLED) == 0)
            pciide_map_compat_intr(pa, cp, sc->sc_cy_compatchan);
    }
    wdcattach(&cp->ata_channel);
}
Exemple #3
0
static void
cmd_channel_map(struct pci_attach_args *pa, struct pciide_softc *sc,
    int channel)
{
	struct pciide_channel *cp = &sc->pciide_channels[channel];
	bus_size_t cmdsize, ctlsize;
	u_int8_t ctrl = pciide_pci_read(sc->sc_pc, sc->sc_tag, CMD_CTRL);
	int interface, one_channel;

	/* 
	 * The 0648/0649 can be told to identify as a RAID controller.
	 * In this case, we have to fake interface
	 */
	if (PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_MASS_STORAGE_IDE) {
		interface = PCIIDE_INTERFACE_SETTABLE(0) |
		    PCIIDE_INTERFACE_SETTABLE(1);
		if (pciide_pci_read(pa->pa_pc, pa->pa_tag, CMD_CONF) &
		    CMD_CONF_DSA1)
			interface |= PCIIDE_INTERFACE_PCI(0) |
			    PCIIDE_INTERFACE_PCI(1);
	} else {
		interface = PCI_INTERFACE(pa->pa_class);
	}

	sc->wdc_chanarray[channel] = &cp->wdc_channel;
	cp->name = PCIIDE_CHANNEL_NAME(channel);
	cp->wdc_channel.ch_channel = channel;
	cp->wdc_channel.ch_wdc = &sc->sc_wdcdev;

	/*
	 * Older CMD64X doesn't have independant channels
	 */
	switch (sc->sc_pp->ide_product) {
	case PCI_PRODUCT_CMDTECH_649:
		one_channel = 0;
		break;
	default:
		one_channel = 1;
		break;
	}

	if (channel > 0 && one_channel) {
		cp->wdc_channel.ch_queue =
		    sc->pciide_channels[0].wdc_channel.ch_queue;
	} else {
		cp->wdc_channel.ch_queue =
		    malloc(sizeof(struct ata_queue), M_DEVBUF, M_NOWAIT);
	}
	if (cp->wdc_channel.ch_queue == NULL) {
		aprint_error("%s %s channel: "
		    "can't allocate memory for command queue",
		    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
		    return;
	}

	aprint_normal("%s: %s channel %s to %s mode\n",
	    sc->sc_wdcdev.sc_dev.dv_xname, cp->name,
	    (interface & PCIIDE_INTERFACE_SETTABLE(channel)) ?
	    "configured" : "wired",
	    (interface & PCIIDE_INTERFACE_PCI(channel)) ?
	    "native-PCI" : "compatibility");

	/*
	 * with a CMD PCI64x, if we get here, the first channel is enabled:
	 * there's no way to disable the first channel without disabling
	 * the whole device
	 */
	if (channel != 0 && (ctrl & CMD_CTRL_2PORT) == 0) {
		aprint_normal("%s: %s channel ignored (disabled)\n",
		    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
		cp->wdc_channel.ch_flags |= WDCF_DISABLED;
		return;
	}

	pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, cmd_pci_intr);
}