xref: /netbsd-src/sys/dev/pci/bha_pci.c (revision 9270f1e85e91a4e19d7db60afec041d0c6f09d74)
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