1 /* $OpenBSD: iha_pci.c,v 1.21 2022/04/16 19:19:59 naddy Exp $ */
2 /*-------------------------------------------------------------------------
3 *
4 * Device driver for the INI-9XXXU/UW or INIC-940/950 PCI SCSI Controller.
5 *
6 * Written for 386bsd and FreeBSD by
7 * Winston Hung <winstonh@initio.com>
8 *
9 * Copyright (c) 1997-1999 Initio Corp
10 * Copyright (c) 2000-2002 Ken Westerback
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer,
17 * without modification, immediately at the beginning of the file.
18 * 2. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 *-------------------------------------------------------------------------
34 */
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/device.h>
38
39 #include <dev/pci/pcidevs.h>
40 #include <dev/pci/pcivar.h>
41
42 #include <scsi/scsi_all.h>
43 #include <scsi/scsiconf.h>
44
45 #include <dev/ic/iha.h>
46
47 int iha_pci_probe(struct device *, void *, void *);
48 void iha_pci_attach(struct device *, struct device *, void *);
49
50 const struct cfattach iha_pci_ca = {
51 sizeof(struct iha_softc), iha_pci_probe, iha_pci_attach
52 };
53
54 struct cfdriver iha_cd = {
55 NULL, "iha", DV_DULL
56 };
57
58 const struct scsi_adapter iha_switch = {
59 iha_scsi_cmd, NULL, NULL, NULL, NULL
60 };
61
62 int
iha_pci_probe(struct device * parent,void * match,void * aux)63 iha_pci_probe(struct device *parent, void *match, void *aux)
64 {
65 struct pci_attach_args *pa = aux;
66
67 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INITIO)
68 switch (PCI_PRODUCT(pa->pa_id)) {
69 case PCI_PRODUCT_INITIO_INIC940:
70 case PCI_PRODUCT_INITIO_INIC941:
71 case PCI_PRODUCT_INITIO_INIC950:
72 return (1);
73 }
74
75 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_DTCTECH)
76 switch (PCI_PRODUCT(pa->pa_id)) {
77 case PCI_PRODUCT_DTCTECH_DMX3194U:
78 return (1);
79 }
80
81 return (0);
82 }
83
84 void
iha_pci_attach(struct device * parent,struct device * self,void * aux)85 iha_pci_attach(struct device *parent, struct device *self, void *aux)
86 {
87 struct pci_attach_args *pa = aux;
88 struct scsibus_attach_args saa;
89 bus_space_handle_t ioh;
90 pci_intr_handle_t ih;
91 struct iha_softc *sc = (void *)self;
92 bus_space_tag_t iot;
93 const char *intrstr;
94 int ioh_valid;
95
96 /*
97 * XXX - Tried memory mapping (using code from adw and ahc)
98 * rather that IO mapping, but it didn't work at all..
99 */
100 ioh_valid = pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_TYPE_IO, 0,
101 &iot, &ioh, NULL, NULL, 0);
102
103 if (ioh_valid != 0) {
104 printf("%s: unable to map registers\n", sc->sc_dev.dv_xname);
105 return;
106 }
107
108 sc->sc_iot = iot;
109 sc->sc_ioh = ioh;
110 sc->sc_dmat = pa->pa_dmat;
111
112 if (pci_intr_map(pa, &ih)) {
113 printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
114 return;
115 }
116 intrstr = pci_intr_string(pa->pa_pc, ih);
117
118 sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, iha_intr, sc,
119 sc->sc_dev.dv_xname);
120
121 if (sc->sc_ih == NULL) {
122 printf(": couldn't establish interrupt");
123 if (intrstr != NULL)
124 printf(" at %s", intrstr);
125 printf("\n");
126 } else {
127 if (intrstr != NULL)
128 printf(": %s\n", intrstr);
129
130 if (iha_init_tulip(sc) == 0) {
131 saa.saa_adapter_softc = sc;
132 saa.saa_adapter = &iha_switch;
133 saa.saa_adapter_target = sc->sc_id;
134 saa.saa_adapter_buswidth = sc->sc_maxtargets;
135 saa.saa_luns = 8;
136 saa.saa_openings = 4; /* # xs's allowed per device */
137 saa.saa_pool = &sc->sc_iopool;
138 saa.saa_quirks = saa.saa_flags = 0;
139 saa.saa_wwpn = saa.saa_wwnn = 0;
140
141 config_found(&sc->sc_dev, &saa, scsiprint);
142 }
143 }
144 }
145