if_mtd_pci.c revision 1.1
1/*
2 * Copyright (c) 2003 Oleg Safiullin
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice unmodified, this list of conditions, and the following
10 *    disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 */
28
29#include <sys/param.h>
30#include <sys/device.h>
31#include <sys/systm.h>
32#include <sys/socket.h>
33#include <net/if.h>
34#include <net/if_media.h>
35#ifdef INET
36#include <netinet/in.h>
37#include <netinet/if_ether.h>
38#endif
39#include <machine/bus.h>
40#include <dev/mii/miivar.h>
41#include <dev/pci/pcidevs.h>
42#include <dev/pci/pcireg.h>
43#include <dev/pci/pcivar.h>
44#include <dev/ic/mtd803reg.h>
45#include <dev/ic/mtd803var.h>
46
47static int mtd_pci_match(struct device *, void *, void *);
48static void mtd_pci_attach(struct device *, struct device *, void *);
49
50struct cfattach mtd_pci_ca = {
51	sizeof(struct mtd_softc), mtd_pci_match, mtd_pci_attach
52};
53
54const static struct pci_matchid mtd_pci_devices[] = {
55	{ PCI_VENDOR_MYSON, PCI_PRODUCT_MYSON_MTD803 },
56};
57
58static int
59mtd_pci_match(struct device *parent, void *match, void *aux)
60{
61	return (pci_matchbyid((struct pci_attach_args *)aux, mtd_pci_devices,
62	    sizeof(mtd_pci_devices) / sizeof(mtd_pci_devices[0])));
63}
64
65static void
66mtd_pci_attach(struct device *parent, struct device *self, void *aux)
67{
68	struct mtd_softc *sc = (void *)self;
69	struct pci_attach_args *pa = aux;
70	pci_intr_handle_t ih;
71	const char *intrstr = NULL;
72	bus_addr_t iobase;
73	bus_size_t iosize;
74	u_int32_t command;
75
76	command = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
77
78#ifdef MTD_USE_MEMIO
79	if (!(command & PCI_COMMAND_MEM_ENABLE)) {
80		printf(": failed to enable memory mapping\n");
81		return;
82	}
83	if (pci_mem_find(pa->pa_pc, pa->pa_tag, MTD_PCI_LOMEM, &iobase,
84	    &iosize, NULL)) {
85		printf(": can't find mem space\n");
86		return;
87	}
88	if (bus_space_map(pa->pa_memt, iobase, iosize, 0, &sc->bus_handle)) {
89		printf(": can't map mem space\n");
90		return;
91	}
92	sc->bus_tag = pa->pa_memt;
93#else	/* !MTD_USE_MEMIO */
94	if (!(command & PCI_COMMAND_IO_ENABLE)) {
95		printf(": failed to enable i/o ports\n");
96		return;
97	}
98
99	if (pci_io_find(pa->pa_pc, pa->pa_tag, MTD_PCI_LOIO, &iobase,
100	    &iosize)) {
101		printf(": can't find i/o space\n");
102		return;
103	}
104	if (bus_space_map(pa->pa_iot, iobase, iosize, 0, &sc->bus_handle)) {
105		printf(": can't map i/o space\n");
106		return;
107	}
108	sc->bus_tag = pa->pa_iot;
109#endif	/* MTD_USE_MEMIO */
110
111	/*
112	 * Allocate our interrupt.
113	 */
114	if (pci_intr_map(pa, &ih)) {
115		printf(": couldn't map interrupt\n");
116		return;
117	}
118
119	intrstr = pci_intr_string(pa->pa_pc, ih);
120	if (pci_intr_establish(pa->pa_pc, ih, IPL_NET, mtd_irq_h, sc,
121	    self->dv_xname) == NULL) {
122		printf(": couldn't establish interrupt");
123		if (intrstr != NULL)
124			printf(" at %s", intrstr);
125		printf("\n");
126		return;
127	}
128	printf(": %s", intrstr);
129
130	sc->dma_tag = pa->pa_dmat;
131	mtd_config(sc);
132}
133