adv_pci.c revision 119690
113240Sprr/*
213240Sprr * Device probe and attach routines for the following
313240Sprr * Advanced Systems Inc. SCSI controllers:
413240Sprr *
513240Sprr *   Connectivity Products:
613240Sprr *	ABP902/3902	- Bus-Master PCI (16 CDB)
713240Sprr *	ABP3905		- Bus-Master PCI (16 CDB)
813240Sprr *	ABP915		- Bus-Master PCI (16 CDB)
915400Sprr *	ABP920		- Bus-Master PCI (16 CDB)
1015400Sprr *	ABP3922		- Bus-Master PCI (16 CDB)
1115400Sprr *	ABP3925		- Bus-Master PCI (16 CDB)
1215400Sprr *	ABP930		- Bus-Master PCI (16 CDB) *
1315400Sprr *	ABP930U		- Bus-Master PCI Ultra (16 CDB)
1415400Sprr *	ABP930UA	- Bus-Master PCI Ultra (16 CDB)
1513240Sprr *	ABP960		- Bus-Master PCI MAC/PC (16 CDB) **
1613240Sprr *	ABP960U		- Bus-Master PCI MAC/PC (16 CDB) **
1713240Sprr *
1813240Sprr *   Single Channel Products:
1913240Sprr *	ABP940		- Bus-Master PCI (240 CDB)
2013240Sprr *	ABP940U		- Bus-Master PCI Ultra (240 CDB)
2113240Sprr *	ABP940UA/3940UA - Bus-Master PCI Ultra (240 CDB)
2213240Sprr *	ABP3960UA	- Bus-Master PCI MAC/PC (240 CDB)
2313240Sprr *	ABP970		- Bus-Master PCI MAC/PC (240 CDB)
2413240Sprr *	ABP970U		- Bus-Master PCI MAC/PC Ultra (240 CDB)
2513240Sprr *
2613240Sprr *   Dual Channel Products:
2713240Sprr *	ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
2813240Sprr *      ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel)
2913240Sprr *      ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel)
3013240Sprr *	ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.)
3113240Sprr *
3213240Sprr *   Footnotes:
3313240Sprr *	 * This board has been sold by SIIG as the Fast SCSI Pro PCI.
3413240Sprr *	** This board has been sold by Iomega as a Jaz Jet PCI adapter.
3513240Sprr *
3613240Sprr * Copyright (c) 1997 Justin Gibbs.
3713240Sprr * All rights reserved.
3813240Sprr *
3913240Sprr * Redistribution and use in source and binary forms, with or without
4013240Sprr * modification, are permitted provided that the following conditions
4113240Sprr * are met:
4213240Sprr * 1. Redistributions of source code must retain the above copyright
4313240Sprr *    notice, this list of conditions, and the following disclaimer,
4413240Sprr *    without modification.
4513240Sprr * 2. The name of the author may not be used to endorse or promote products
4613240Sprr *    derived from this software without specific prior written permission.
4713240Sprr *
4813240Sprr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
4913240Sprr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5013240Sprr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5113240Sprr * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
5213240Sprr * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5313240Sprr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
5413240Sprr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5513240Sprr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5613240Sprr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5713240Sprr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5813240Sprr * SUCH DAMAGE.
5913240Sprr */
6013240Sprr
6113240Sprr#include <sys/cdefs.h>
6213240Sprr__FBSDID("$FreeBSD: head/sys/dev/advansys/adv_pci.c 119690 2003-09-02 17:30:40Z jhb $");
6313240Sprr
6413240Sprr#include <sys/param.h>
6513240Sprr#include <sys/systm.h>
6613240Sprr#include <sys/kernel.h>
6713240Sprr#include <sys/lock.h>
6813240Sprr#include <sys/mutex.h>
6913240Sprr
7013240Sprr#include <machine/bus_pio.h>
7113240Sprr#include <machine/bus.h>
7213240Sprr#include <machine/resource.h>
7313240Sprr#include <sys/bus.h>
7413240Sprr#include <sys/rman.h>
7513240Sprr
7613240Sprr#include <dev/pci/pcireg.h>
7713240Sprr#include <dev/pci/pcivar.h>
7813240Sprr
7913240Sprr#include <dev/advansys/advansys.h>
8013240Sprr
8113240Sprr#define PCI_BASEADR0	PCIR_BAR(0)		/* I/O Address */
8215400Sprr#define PCI_BASEADR1	PCIR_BAR(1)		/* Mem I/O Address */
8315400Sprr
8413240Sprr#define	PCI_DEVICE_ID_ADVANSYS_1200A	0x110010CD
8513240Sprr#define	PCI_DEVICE_ID_ADVANSYS_1200B	0x120010CD
8613240Sprr#define	PCI_DEVICE_ID_ADVANSYS_3000	0x130010CD
8713240Sprr#define	PCI_DEVICE_REV_ADVANSYS_3150	0x02
8815400Sprr#define	PCI_DEVICE_REV_ADVANSYS_3050	0x03
8915400Sprr
9013240Sprr#define ADV_PCI_MAX_DMA_ADDR    (0xFFFFFFFFL)
9113240Sprr#define ADV_PCI_MAX_DMA_COUNT   (0xFFFFFFFFL)
9213240Sprr
9315400Sprrstatic int adv_pci_probe(device_t);
9415400Sprrstatic int adv_pci_attach(device_t);
9513240Sprr
9613240Sprr/*
9713240Sprr * The overrun buffer shared amongst all PCI adapters.
9813240Sprr */
9915400Sprrstatic  u_int8_t*	overrun_buf;
10013240Sprrstatic	bus_dma_tag_t	overrun_dmat;
10113240Sprrstatic	bus_dmamap_t	overrun_dmamap;
10213240Sprrstatic	bus_addr_t	overrun_physbase;
10313240Sprr
10415400Sprrstatic int
10515400Sprradv_pci_probe(device_t dev)
10613240Sprr{
10713240Sprr	int	rev = pci_get_revid(dev);
10813240Sprr
10913240Sprr	switch (pci_get_devid(dev)) {
11013240Sprr	case PCI_DEVICE_ID_ADVANSYS_1200A:
11113240Sprr		device_set_desc(dev, "AdvanSys ASC1200A SCSI controller");
11213240Sprr		return 0;
11313240Sprr	case PCI_DEVICE_ID_ADVANSYS_1200B:
11413240Sprr		device_set_desc(dev, "AdvanSys ASC1200B SCSI controller");
11515400Sprr		return 0;
11615400Sprr	case PCI_DEVICE_ID_ADVANSYS_3000:
11713240Sprr		if (rev == PCI_DEVICE_REV_ADVANSYS_3150) {
11813240Sprr			device_set_desc(dev,
11913240Sprr					"AdvanSys ASC3150 SCSI controller");
12013240Sprr			return 0;
12115400Sprr		} else if (rev == PCI_DEVICE_REV_ADVANSYS_3050) {
12213240Sprr			device_set_desc(dev,
12313240Sprr					"AdvanSys ASC3030/50 SCSI controller");
12413240Sprr			return 0;
12513240Sprr		} else if (rev >= PCI_DEVICE_REV_ADVANSYS_3150) {
12615400Sprr			device_set_desc(dev, "Unknown AdvanSys controller");
12715400Sprr			return 0;
12813240Sprr		}
12913240Sprr		break;
13013240Sprr	default:
13113240Sprr		break;
13215400Sprr	}
13313240Sprr	return ENXIO;
13413240Sprr}
13513240Sprr
13613240Sprrstatic int
13715400Sprradv_pci_attach(device_t dev)
13815400Sprr{
13913240Sprr	struct		adv_softc *adv;
14013240Sprr	u_int32_t	id;
14113240Sprr	u_int32_t	command;
14213240Sprr	int		error, rid, irqrid;
14313240Sprr	void		*ih;
14413240Sprr	struct resource	*iores, *irqres;
14513240Sprr
14613240Sprr	/*
14713240Sprr	 * Determine the chip version.
14815400Sprr	 */
14915400Sprr	id = pci_read_config(dev, PCIR_DEVVENDOR, /*bytes*/4);
15013240Sprr	command = pci_read_config(dev, PCIR_COMMAND, /*bytes*/1);
15113240Sprr
15213240Sprr	/*
15313240Sprr	 * These cards do not allow memory mapped accesses, so we must
15415400Sprr	 * ensure that I/O accesses are available or we won't be able
15513240Sprr	 * to talk to them.
15613240Sprr	 */
15713240Sprr	if ((command & (PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN))
15813240Sprr	 != (PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN)) {
15915400Sprr		command |= PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN;
16015400Sprr		pci_write_config(dev, PCIR_COMMAND, command, /*bytes*/1);
16113240Sprr	}
16213240Sprr
16313240Sprr	/*
16413240Sprr	 * Early chips can't handle non-zero latency timer settings.
16515400Sprr	 */
16613240Sprr	if (id == PCI_DEVICE_ID_ADVANSYS_1200A
16713240Sprr	 || id == PCI_DEVICE_ID_ADVANSYS_1200B) {
16813240Sprr		pci_write_config(dev, PCIR_LATTIMER, /*value*/0, /*bytes*/1);
16913240Sprr	}
17015400Sprr
17115400Sprr	rid = PCI_BASEADR0;
17213240Sprr	iores = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1,
17313240Sprr				   RF_ACTIVE);
17413240Sprr	if (iores == NULL)
17515400Sprr		return ENXIO;
17615400Sprr
17713240Sprr	if (adv_find_signature(rman_get_bustag(iores),
17813240Sprr			       rman_get_bushandle(iores)) == 0) {
17913240Sprr		bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
18013240Sprr		return ENXIO;
18115400Sprr	}
18215400Sprr
18313240Sprr	adv = adv_alloc(dev, rman_get_bustag(iores), rman_get_bushandle(iores));
18413240Sprr	if (adv == NULL) {
18513240Sprr		bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
18613240Sprr		return ENXIO;
18713240Sprr	}
18813240Sprr
18913240Sprr	/* Allocate a dmatag for our transfer DMA maps */
19013240Sprr	/* XXX Should be a child of the PCI bus dma tag */
19113240Sprr	error = bus_dma_tag_create(
19213240Sprr			/* parent	*/ NULL,
19313240Sprr			/* alignment	*/ 1,
19413240Sprr			/* boundary	*/ 0,
19513240Sprr			/* lowaddr	*/ ADV_PCI_MAX_DMA_ADDR,
19613240Sprr			/* highaddr	*/ BUS_SPACE_MAXADDR,
19715400Sprr			/* filter	*/ NULL,
19813240Sprr			/* filterarg	*/ NULL,
19913240Sprr			/* maxsize	*/ BUS_SPACE_MAXSIZE_32BIT,
20015400Sprr			/* nsegments	*/ ~0,
20113240Sprr			/* maxsegsz	*/ ADV_PCI_MAX_DMA_COUNT,
20213240Sprr			/* flags	*/ 0,
20313240Sprr			/* lockfunc	*/ busdma_lock_mutex,
20413240Sprr			/* lockarg	*/ &Giant,
20513240Sprr			&adv->parent_dmat);
20613240Sprr
20713240Sprr	if (error != 0) {
20813240Sprr		printf("%s: Could not allocate DMA tag - error %d\n",
20913240Sprr		       adv_name(adv), error);
21013240Sprr		adv_free(adv);
21115400Sprr		bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
21213240Sprr		return ENXIO;
21313240Sprr	}
21413240Sprr
21513240Sprr	adv->init_level++;
21615400Sprr
21713240Sprr	if (overrun_buf == NULL) {
21813240Sprr		/* Need to allocate our overrun buffer */
21913240Sprr		if (bus_dma_tag_create(
22013240Sprr				/* parent	*/ adv->parent_dmat,
22115400Sprr				/* alignment	*/ 8,
22213240Sprr				/* boundary	*/ 0,
22313240Sprr				/* lowaddr	*/ ADV_PCI_MAX_DMA_ADDR,
22413240Sprr				/* highaddr	*/ BUS_SPACE_MAXADDR,
22513240Sprr				/* filter	*/ NULL,
22615400Sprr				/* filterarg	*/ NULL,
22713240Sprr				/* maxsize	*/ ADV_OVERRUN_BSIZE,
22813240Sprr				/* nsegments	*/ 1,
22913240Sprr				/* maxsegsz	*/ BUS_SPACE_MAXSIZE_32BIT,
23013240Sprr				/* flags	*/ 0,
23113240Sprr				/* lockfunc	*/ busdma_lock_mutex,
23213240Sprr				/* lockarg	*/ &Giant,
23315400Sprr				&overrun_dmat) != 0) {
23415400Sprr			bus_dma_tag_destroy(adv->parent_dmat);
23513240Sprr			adv_free(adv);
23613240Sprr			bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
23713240Sprr			return ENXIO;
23813240Sprr       		}
23913240Sprr		if (bus_dmamem_alloc(overrun_dmat,
24013240Sprr				     (void **)&overrun_buf,
24113240Sprr				     BUS_DMA_NOWAIT,
24213240Sprr				     &overrun_dmamap) != 0) {
24313240Sprr			bus_dma_tag_destroy(overrun_dmat);
24413240Sprr			bus_dma_tag_destroy(adv->parent_dmat);
24513240Sprr			adv_free(adv);
24613240Sprr			bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
24713240Sprr			return ENXIO;
24813240Sprr		}
24913240Sprr		/* And permanently map it in */
25013240Sprr		bus_dmamap_load(overrun_dmat, overrun_dmamap,
25113240Sprr				overrun_buf, ADV_OVERRUN_BSIZE,
25213240Sprr				adv_map, &overrun_physbase,
25313240Sprr				/*flags*/0);
25413240Sprr	}
25513240Sprr
25613240Sprr	adv->overrun_physbase = overrun_physbase;
25713240Sprr
25813240Sprr	/*
25913240Sprr	 * Stop the chip.
26013240Sprr	 */
26113240Sprr	ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_HALT);
26213240Sprr	ADV_OUTW(adv, ADV_CHIP_STATUS, 0);
26313240Sprr
26413240Sprr	adv->chip_version = ADV_INB(adv, ADV_NONEISA_CHIP_REVISION);
26513240Sprr	adv->type = ADV_PCI;
26613240Sprr
26713240Sprr	/*
26813240Sprr	 * Setup active negation and signal filtering.
26913240Sprr	 */
27013240Sprr	{
27113240Sprr		u_int8_t extra_cfg;
27213240Sprr
27313240Sprr		if (adv->chip_version >= ADV_CHIP_VER_PCI_ULTRA_3150)
27413240Sprr			adv->type |= ADV_ULTRA;
27513240Sprr		if (adv->chip_version == ADV_CHIP_VER_PCI_ULTRA_3050)
27615400Sprr			extra_cfg = ADV_IFC_ACT_NEG | ADV_IFC_WR_EN_FILTER;
27715400Sprr		else
27813240Sprr			extra_cfg = ADV_IFC_ACT_NEG | ADV_IFC_SLEW_RATE;
27913240Sprr		ADV_OUTB(adv, ADV_REG_IFC, extra_cfg);
28013240Sprr	}
28113240Sprr
28213240Sprr	if (adv_init(adv) != 0) {
28313240Sprr		adv_free(adv);
28413240Sprr		bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
28513240Sprr		return ENXIO;
28613240Sprr	}
28713240Sprr
28815400Sprr	adv->max_dma_count = ADV_PCI_MAX_DMA_COUNT;
28915400Sprr	adv->max_dma_addr = ADV_PCI_MAX_DMA_ADDR;
29013240Sprr
29113240Sprr#if CC_DISABLE_PCI_PARITY_INT
29213240Sprr	{
29313240Sprr		u_int16_t config_msw;
29413240Sprr
29513240Sprr		config_msw = ADV_INW(adv, ADV_CONFIG_MSW);
29613240Sprr		config_msw &= 0xFFC0;
29713240Sprr		ADV_OUTW(adv, ADV_CONFIG_MSW, config_msw);
29813240Sprr	}
29915400Sprr#endif
30013240Sprr
30113240Sprr	if (id == PCI_DEVICE_ID_ADVANSYS_1200A
30213240Sprr	 || id == PCI_DEVICE_ID_ADVANSYS_1200B) {
30313240Sprr		adv->bug_fix_control |= ADV_BUG_FIX_IF_NOT_DWB;
30413240Sprr		adv->bug_fix_control |= ADV_BUG_FIX_ASYN_USE_SYN;
30513240Sprr		adv->fix_asyn_xfer = ~0;
30613240Sprr	}
30713240Sprr
30815400Sprr	irqrid = 0;
30913240Sprr	irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &irqrid, 0, ~0, 1,
31013240Sprr				    RF_SHAREABLE | RF_ACTIVE);
31113240Sprr	if (irqres == NULL ||
31213240Sprr	    bus_setup_intr(dev, irqres, INTR_TYPE_CAM|INTR_ENTROPY, adv_intr, adv, &ih)) {
31313240Sprr		adv_free(adv);
31413240Sprr		bus_release_resource(dev, SYS_RES_IOPORT, rid, iores);
31513240Sprr		return ENXIO;
31613240Sprr	}
31713240Sprr
31813240Sprr	adv_attach(adv);
31913240Sprr	return 0;
32013240Sprr}
32113240Sprr
32213240Sprrstatic device_method_t adv_pci_methods[] = {
32313240Sprr	/* Device interface */
32413240Sprr	DEVMETHOD(device_probe,		adv_pci_probe),
32513240Sprr	DEVMETHOD(device_attach,	adv_pci_attach),
32613240Sprr	{ 0, 0 }
32713240Sprr};
32815400Sprr
32915400Sprrstatic driver_t adv_pci_driver = {
33015400Sprr	"adv", adv_pci_methods, sizeof(struct adv_softc)
33115400Sprr};
33215400Sprr
33315400Sprrstatic devclass_t adv_pci_devclass;
33415400SprrDRIVER_MODULE(adv, pci, adv_pci_driver, adv_pci_devclass, 0, 0);
33513240Sprr