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