This source file includes following definitions.
- mfi_pci_find_device
- mfi_pci_match
- mfi_pci_attach
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #include <sys/param.h>
19 #include <sys/systm.h>
20 #include <sys/kernel.h>
21 #include <sys/malloc.h>
22 #include <sys/device.h>
23 #include <sys/rwlock.h>
24
25 #include <dev/pci/pcidevs.h>
26 #include <dev/pci/pcivar.h>
27
28 #include <machine/bus.h>
29
30 #include <scsi/scsi_all.h>
31 #include <scsi/scsi_disk.h>
32 #include <scsi/scsiconf.h>
33
34 #include <dev/ic/mfireg.h>
35 #include <dev/ic/mfivar.h>
36
37 #define MFI_BAR 0x10
38 #define MFI_PCI_MEMSIZE 0x2000
39
40 int mfi_pci_find_device(void *);
41 int mfi_pci_match(struct device *, void *, void *);
42 void mfi_pci_attach(struct device *, struct device *, void *);
43
44 struct cfattach mfi_pci_ca = {
45 sizeof(struct mfi_softc), mfi_pci_match, mfi_pci_attach
46 };
47
48 static const
49 struct mfi_pci_device {
50 pcireg_t mpd_vendor;
51 pcireg_t mpd_product;
52 pcireg_t mpd_subvendor;
53 pcireg_t mpd_subproduct;
54 char *mpd_model;
55 uint32_t mpd_flags;
56 } mfi_pci_devices[] = {
57 { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_MEGARAID_SAS,
58 0, 0, "", 0 },
59 { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_MEGARAID_VERDE_ZCR,
60 0, 0, "", 0 },
61 { PCI_VENDOR_DELL, PCI_PRODUCT_DELL_PERC5,
62 PCI_VENDOR_DELL, 0x1f01, "Dell PERC 5/e", 0 },
63 { PCI_VENDOR_DELL, PCI_PRODUCT_DELL_PERC5,
64 PCI_VENDOR_DELL, 0x1f02, "Dell PERC 5/i", 0 },
65 { 0 }
66 };
67
68 int
69 mfi_pci_find_device(void *aux) {
70 struct pci_attach_args *pa = aux;
71 int i;
72
73 for (i = 0; mfi_pci_devices[i].mpd_vendor; i++) {
74 if (mfi_pci_devices[i].mpd_vendor == PCI_VENDOR(pa->pa_id) &&
75 mfi_pci_devices[i].mpd_product == PCI_PRODUCT(pa->pa_id)) {
76 DNPRINTF(MFI_D_MISC, "mfi_pci_find_device: %i\n", i);
77 return (i);
78 }
79 }
80
81 return (-1);
82 }
83
84 int
85 mfi_pci_match(struct device *parent, void *match, void *aux)
86 {
87 int i;
88
89 if ((i = mfi_pci_find_device(aux)) != -1) {
90 DNPRINTF(MFI_D_MISC,
91 "mfi_pci_match: vendor: %04x product: %04x\n",
92 mfi_pci_devices[i].mpd_vendor,
93 mfi_pci_devices[i].mpd_product);
94
95 return (1);
96 }
97
98 return (0);
99 }
100
101 void
102 mfi_pci_attach(struct device *parent, struct device *self, void *aux)
103 {
104 struct mfi_softc *sc = (struct mfi_softc *)self;
105 struct pci_attach_args *pa = aux;
106 const char *intrstr;
107 pci_intr_handle_t ih;
108 bus_size_t size;
109 pcireg_t csr;
110 uint32_t subsysid, i;
111
112 subsysid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
113 for (i = 0; mfi_pci_devices[i].mpd_vendor; i++)
114 if (mfi_pci_devices[i].mpd_subvendor == PCI_VENDOR(subsysid) &&
115 mfi_pci_devices[i].mpd_subproduct == PCI_PRODUCT(subsysid)){
116 printf(", %s", mfi_pci_devices[i].mpd_model);
117 break;
118 }
119
120 csr = pci_mapreg_type(pa->pa_pc, pa->pa_tag, MFI_BAR);
121 csr |= PCI_MAPREG_MEM_TYPE_32BIT;
122 if (pci_mapreg_map(pa, MFI_BAR, csr, 0,
123 &sc->sc_iot, &sc->sc_ioh, NULL, &size, MFI_PCI_MEMSIZE)) {
124 printf(": can't map controller pci space\n");
125 return;
126 }
127
128 sc->sc_dmat = pa->pa_dmat;
129
130 if (pci_intr_map(pa, &ih)) {
131 printf(": can't map interrupt\n");
132 bus_space_unmap(sc->sc_iot, sc->sc_ioh, size);
133 return;
134 }
135 intrstr = pci_intr_string(pa->pa_pc, ih);
136 sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, mfi_intr, sc,
137 sc->sc_dev.dv_xname);
138 if (!sc->sc_ih) {
139 printf(": can't establish interrupt");
140 if (intrstr)
141 printf(" at %s", intrstr);
142 printf("\n");
143 bus_space_unmap(sc->sc_iot, sc->sc_ioh, size);
144 return;
145 }
146
147 printf(": %s\n", intrstr);
148
149 if (mfi_attach(sc)) {
150 printf("%s: can't attach", DEVNAME(sc));
151 pci_intr_disestablish(pa->pa_pc, sc->sc_ih);
152 sc->sc_ih = NULL;
153 bus_space_unmap(sc->sc_iot, sc->sc_ioh, size);
154 }
155 }