1*9270f1e8Sjdolecek /* $NetBSD: bha_pci.c,v 1.41 2016/10/13 17:11:09 jdolecek Exp $ */
270944d2eSmycroft
36dc90320Smycroft /*-
46dc90320Smycroft * Copyright (c) 1998 The NetBSD Foundation, Inc.
56dc90320Smycroft * All rights reserved.
66dc90320Smycroft *
76dc90320Smycroft * This code is derived from software contributed to The NetBSD Foundation
86dc90320Smycroft * by Charles M. Hannum.
970944d2eSmycroft *
1070944d2eSmycroft * Redistribution and use in source and binary forms, with or without
1170944d2eSmycroft * modification, are permitted provided that the following conditions
1270944d2eSmycroft * are met:
1370944d2eSmycroft * 1. Redistributions of source code must retain the above copyright
1470944d2eSmycroft * notice, this list of conditions and the following disclaimer.
1570944d2eSmycroft * 2. Redistributions in binary form must reproduce the above copyright
1670944d2eSmycroft * notice, this list of conditions and the following disclaimer in the
1770944d2eSmycroft * documentation and/or other materials provided with the distribution.
1870944d2eSmycroft *
196dc90320Smycroft * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
206dc90320Smycroft * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
216dc90320Smycroft * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
226dc90320Smycroft * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
236dc90320Smycroft * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
246dc90320Smycroft * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
256dc90320Smycroft * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
266dc90320Smycroft * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
276dc90320Smycroft * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
286dc90320Smycroft * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
296dc90320Smycroft * POSSIBILITY OF SUCH DAMAGE.
3070944d2eSmycroft */
3170944d2eSmycroft
329048aaaeSlukem #include <sys/cdefs.h>
33*9270f1e8Sjdolecek __KERNEL_RCSID(0, "$NetBSD: bha_pci.c,v 1.41 2016/10/13 17:11:09 jdolecek Exp $");
349048aaaeSlukem
3506fdef11Smycroft #include <sys/param.h>
369cbe3b9dSchristos #include <sys/systm.h>
3706fdef11Smycroft #include <sys/device.h>
3806fdef11Smycroft
39a2a38285Sad #include <sys/bus.h>
40a2a38285Sad #include <sys/intr.h>
4106fdef11Smycroft
426f3bab1fSbouyer #include <dev/scsipi/scsipi_all.h>
436f3bab1fSbouyer #include <dev/scsipi/scsiconf.h>
4406fdef11Smycroft
4506fdef11Smycroft #include <dev/pci/pcivar.h>
4606fdef11Smycroft #include <dev/pci/pcidevs.h>
4706fdef11Smycroft
4806fdef11Smycroft #include <dev/ic/bhareg.h>
4906fdef11Smycroft #include <dev/ic/bhavar.h>
5006fdef11Smycroft
5106fdef11Smycroft #define PCI_CBIO 0x10
5206fdef11Smycroft
5306fdef11Smycroft /*
5406fdef11Smycroft * Check the slots looking for a board we recognise
55f0a7346dSsnj * If we find one, note its address (slot) and call
5606fdef11Smycroft * the actual probe routine to check it out.
5706fdef11Smycroft */
58d36c43c5Sthorpej static int
bha_pci_match(device_t parent,cfdata_t match,void * aux)59a591bc88Scegger bha_pci_match(device_t parent, cfdata_t match, void *aux)
6006fdef11Smycroft {
6106fdef11Smycroft struct pci_attach_args *pa = aux;
6202ca6f92Scgd bus_space_tag_t iot;
63546c8abcSthorpej bus_space_handle_t ioh;
6402ca6f92Scgd bus_size_t iosize;
6506fdef11Smycroft int rv;
6606fdef11Smycroft
6706fdef11Smycroft if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_BUSLOGIC)
6806fdef11Smycroft return (0);
6906fdef11Smycroft
70788394a2Sjonathan if (PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_BUSLOGIC_MULTIMASTER_NC &&
71788394a2Sjonathan PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_BUSLOGIC_MULTIMASTER)
7206fdef11Smycroft return (0);
7306fdef11Smycroft
7436949596Scgd if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh,
7502ca6f92Scgd NULL, &iosize))
7606fdef11Smycroft return (0);
7706fdef11Smycroft
78e3f2f91bSross rv = bha_find(iot, ioh);
7906fdef11Smycroft
80546c8abcSthorpej bus_space_unmap(iot, ioh, iosize);
8106fdef11Smycroft
8206fdef11Smycroft return (rv);
8306fdef11Smycroft }
8406fdef11Smycroft
8506fdef11Smycroft /*
8606fdef11Smycroft * Attach all the sub-devices we can find
8706fdef11Smycroft */
88d36c43c5Sthorpej static void
bha_pci_attach(device_t parent,device_t self,void * aux)89a591bc88Scegger bha_pci_attach(device_t parent, device_t self, void *aux)
9006fdef11Smycroft {
9106fdef11Smycroft struct pci_attach_args *pa = aux;
92b8169823Scegger struct bha_softc *sc = device_private(self);
9302ca6f92Scgd bus_space_tag_t iot;
94546c8abcSthorpej bus_space_handle_t ioh;
9506fdef11Smycroft pci_chipset_tag_t pc = pa->pa_pc;
9606fdef11Smycroft pci_intr_handle_t ih;
9706fdef11Smycroft pcireg_t csr;
9806fdef11Smycroft const char *model, *intrstr;
99e58a356cSchristos char intrbuf[PCI_INTRSTR_LEN];
10006fdef11Smycroft
101cbab9cadSchs sc->sc_dev = self;
102cbab9cadSchs
1037ec10e2dSthorpej aprint_naive(": SCSI controller\n");
1047ec10e2dSthorpej
105788394a2Sjonathan if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BUSLOGIC_MULTIMASTER_NC)
10606fdef11Smycroft model = "BusLogic 9xxC SCSI";
107788394a2Sjonathan else if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BUSLOGIC_MULTIMASTER)
10806fdef11Smycroft model = "BusLogic 9xxC SCSI";
10906fdef11Smycroft else
11006fdef11Smycroft model = "unknown model!";
1117ec10e2dSthorpej aprint_normal(": %s\n", model);
11206fdef11Smycroft
11336949596Scgd if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0, &iot, &ioh,
11402ca6f92Scgd NULL, NULL)) {
115cbab9cadSchs aprint_error_dev(sc->sc_dev, "unable to map device registers\n");
11602ca6f92Scgd return;
11702ca6f92Scgd }
11806fdef11Smycroft
119546c8abcSthorpej sc->sc_iot = iot;
12006fdef11Smycroft sc->sc_ioh = ioh;
1216d9b3bc0Sthorpej sc->sc_dmat = pa->pa_dmat;
122e3f2f91bSross if (!bha_find(iot, ioh))
123080350dcSmycroft panic("bha_pci_attach: bha_find failed");
12406fdef11Smycroft
1256d9b3bc0Sthorpej sc->sc_dmaflags = 0;
1266d9b3bc0Sthorpej
12706fdef11Smycroft csr = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
12806fdef11Smycroft pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
12906fdef11Smycroft csr | PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_IO_ENABLE);
13006fdef11Smycroft
131851de295Ssommerfeld if (pci_intr_map(pa, &ih)) {
132cbab9cadSchs aprint_error_dev(sc->sc_dev, "couldn't map interrupt\n");
13306fdef11Smycroft return;
13406fdef11Smycroft }
135e58a356cSchristos intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf));
136*9270f1e8Sjdolecek sc->sc_ih = pci_intr_establish_xname(pc, ih, IPL_BIO, bha_intr, sc,
137*9270f1e8Sjdolecek device_xname(sc->sc_dev));
13806fdef11Smycroft if (sc->sc_ih == NULL) {
139cbab9cadSchs aprint_error_dev(sc->sc_dev, "couldn't establish interrupt");
14006fdef11Smycroft if (intrstr != NULL)
14185cadc23Snjoly aprint_error(" at %s", intrstr);
14285cadc23Snjoly aprint_error("\n");
14306fdef11Smycroft return;
14406fdef11Smycroft }
145cbab9cadSchs aprint_normal_dev(sc->sc_dev, "interrupting at %s\n", intrstr);
14606fdef11Smycroft
147e3f2f91bSross bha_attach(sc);
14879b026a8Sjonathan
14979b026a8Sjonathan bha_disable_isacompat(sc);
15006fdef11Smycroft }
151d36c43c5Sthorpej
152cbab9cadSchs CFATTACH_DECL_NEW(bha_pci, sizeof(struct bha_softc),
153d36c43c5Sthorpej bha_pci_match, bha_pci_attach, NULL, NULL);
154