1139749Simp/*- 239217Sgibbs * Device probe and attach routines for the following 339217Sgibbs * Advanced Systems Inc. SCSI controllers: 439217Sgibbs * 539217Sgibbs * Connectivity Products: 655945Sgibbs * ABP902/3902 - Bus-Master PCI (16 CDB) 755945Sgibbs * ABP3905 - Bus-Master PCI (16 CDB) 855945Sgibbs * ABP915 - Bus-Master PCI (16 CDB) 955945Sgibbs * ABP920 - Bus-Master PCI (16 CDB) 1055945Sgibbs * ABP3922 - Bus-Master PCI (16 CDB) 1155945Sgibbs * ABP3925 - Bus-Master PCI (16 CDB) 1255945Sgibbs * ABP930 - Bus-Master PCI (16 CDB) * 1355945Sgibbs * ABP930U - Bus-Master PCI Ultra (16 CDB) 1455945Sgibbs * ABP930UA - Bus-Master PCI Ultra (16 CDB) 1555945Sgibbs * ABP960 - Bus-Master PCI MAC/PC (16 CDB) ** 1657679Sgibbs * ABP960U - Bus-Master PCI MAC/PC (16 CDB) ** 1739217Sgibbs * 1839217Sgibbs * Single Channel Products: 1957679Sgibbs * ABP940 - Bus-Master PCI (240 CDB) 2057679Sgibbs * ABP940U - Bus-Master PCI Ultra (240 CDB) 2157679Sgibbs * ABP940UA/3940UA - Bus-Master PCI Ultra (240 CDB) 2257679Sgibbs * ABP3960UA - Bus-Master PCI MAC/PC (240 CDB) 2357679Sgibbs * ABP970 - Bus-Master PCI MAC/PC (240 CDB) 2457679Sgibbs * ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB) 2539217Sgibbs * 2639217Sgibbs * Dual Channel Products: 2739217Sgibbs * ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel) 2857679Sgibbs * ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel) 2957679Sgibbs * ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel) 3055945Sgibbs * ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.) 3139217Sgibbs * 3239217Sgibbs * Footnotes: 3339217Sgibbs * * This board has been sold by SIIG as the Fast SCSI Pro PCI. 3439217Sgibbs * ** This board has been sold by Iomega as a Jaz Jet PCI adapter. 3539217Sgibbs * 3639217Sgibbs * Copyright (c) 1997 Justin Gibbs. 3739217Sgibbs * All rights reserved. 3839217Sgibbs * 3939217Sgibbs * Redistribution and use in source and binary forms, with or without 4039217Sgibbs * modification, are permitted provided that the following conditions 4139217Sgibbs * are met: 4239217Sgibbs * 1. Redistributions of source code must retain the above copyright 4339217Sgibbs * notice, this list of conditions, and the following disclaimer, 4455945Sgibbs * without modification. 4539217Sgibbs * 2. The name of the author may not be used to endorse or promote products 4639217Sgibbs * derived from this software without specific prior written permission. 4739217Sgibbs * 4839217Sgibbs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 4939217Sgibbs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 5039217Sgibbs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 5139217Sgibbs * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 5239217Sgibbs * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 5339217Sgibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 5439217Sgibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 5539217Sgibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 5639217Sgibbs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5739217Sgibbs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5839217Sgibbs * SUCH DAMAGE. 5939217Sgibbs */ 6039217Sgibbs 61119418Sobrien#include <sys/cdefs.h> 62119418Sobrien__FBSDID("$FreeBSD$"); 63119418Sobrien 6439217Sgibbs#include <sys/param.h> 6539217Sgibbs#include <sys/systm.h> 6639217Sgibbs#include <sys/kernel.h> 67117126Sscottl#include <sys/lock.h> 68129879Sphk#include <sys/module.h> 69117126Sscottl#include <sys/mutex.h> 7039217Sgibbs 7139217Sgibbs#include <machine/bus.h> 7259082Snyan#include <machine/resource.h> 7359082Snyan#include <sys/bus.h> 7459082Snyan#include <sys/rman.h> 7539217Sgibbs 76119277Simp#include <dev/pci/pcireg.h> 77119277Simp#include <dev/pci/pcivar.h> 7839217Sgibbs 7939217Sgibbs#include <dev/advansys/advansys.h> 8039217Sgibbs 81119690Sjhb#define PCI_BASEADR0 PCIR_BAR(0) /* I/O Address */ 82119690Sjhb#define PCI_BASEADR1 PCIR_BAR(1) /* Mem I/O Address */ 8339217Sgibbs 8439217Sgibbs#define PCI_DEVICE_ID_ADVANSYS_1200A 0x110010CD 8539217Sgibbs#define PCI_DEVICE_ID_ADVANSYS_1200B 0x120010CD 8655945Sgibbs#define PCI_DEVICE_ID_ADVANSYS_3000 0x130010CD 8739217Sgibbs#define PCI_DEVICE_REV_ADVANSYS_3150 0x02 8839217Sgibbs#define PCI_DEVICE_REV_ADVANSYS_3050 0x03 8939217Sgibbs 9039217Sgibbs#define ADV_PCI_MAX_DMA_ADDR (0xFFFFFFFFL) 9139217Sgibbs#define ADV_PCI_MAX_DMA_COUNT (0xFFFFFFFFL) 9239217Sgibbs 9359082Snyanstatic int adv_pci_probe(device_t); 9459082Snyanstatic int adv_pci_attach(device_t); 9539217Sgibbs 9639217Sgibbs/* 9739217Sgibbs * The overrun buffer shared amongst all PCI adapters. 9839217Sgibbs */ 99155319Simpstatic void* overrun_buf; 10042012Sgibbsstatic bus_dma_tag_t overrun_dmat; 10142012Sgibbsstatic bus_dmamap_t overrun_dmamap; 10242012Sgibbsstatic bus_addr_t overrun_physbase; 10339217Sgibbs 10459082Snyanstatic int 10559082Snyanadv_pci_probe(device_t dev) 10639217Sgibbs{ 10759082Snyan int rev = pci_get_revid(dev); 10855945Sgibbs 10959082Snyan switch (pci_get_devid(dev)) { 11039217Sgibbs case PCI_DEVICE_ID_ADVANSYS_1200A: 11159082Snyan device_set_desc(dev, "AdvanSys ASC1200A SCSI controller"); 112143164Simp return BUS_PROBE_DEFAULT; 11339217Sgibbs case PCI_DEVICE_ID_ADVANSYS_1200B: 11459082Snyan device_set_desc(dev, "AdvanSys ASC1200B SCSI controller"); 115143164Simp return BUS_PROBE_DEFAULT; 11655945Sgibbs case PCI_DEVICE_ID_ADVANSYS_3000: 11759082Snyan if (rev == PCI_DEVICE_REV_ADVANSYS_3150) { 11859082Snyan device_set_desc(dev, 11959082Snyan "AdvanSys ASC3150 SCSI controller"); 120143164Simp return BUS_PROBE_DEFAULT; 12159082Snyan } else if (rev == PCI_DEVICE_REV_ADVANSYS_3050) { 12259082Snyan device_set_desc(dev, 12359082Snyan "AdvanSys ASC3030/50 SCSI controller"); 124143164Simp return BUS_PROBE_DEFAULT; 12559082Snyan } else if (rev >= PCI_DEVICE_REV_ADVANSYS_3150) { 12659082Snyan device_set_desc(dev, "Unknown AdvanSys controller"); 127143164Simp return BUS_PROBE_DEFAULT; 12859082Snyan } 12939217Sgibbs break; 13039217Sgibbs default: 13139217Sgibbs break; 13239217Sgibbs } 13359082Snyan return ENXIO; 13439217Sgibbs} 13539217Sgibbs 13659082Snyanstatic int 13759082Snyanadv_pci_attach(device_t dev) 13839217Sgibbs{ 13939217Sgibbs struct adv_softc *adv; 14039217Sgibbs u_int32_t id; 14176307Snyan int error, rid, irqrid; 14259082Snyan void *ih; 14359082Snyan struct resource *iores, *irqres; 14459082Snyan 14539217Sgibbs /* 14639217Sgibbs * Determine the chip version. 14739217Sgibbs */ 148241492Sjhb id = pci_get_devid(dev); 149241492Sjhb pci_enable_busmaster(dev); 15039217Sgibbs 15139217Sgibbs /* 15239217Sgibbs * Early chips can't handle non-zero latency timer settings. 15339217Sgibbs */ 15439217Sgibbs if (id == PCI_DEVICE_ID_ADVANSYS_1200A 15539217Sgibbs || id == PCI_DEVICE_ID_ADVANSYS_1200B) { 15659082Snyan pci_write_config(dev, PCIR_LATTIMER, /*value*/0, /*bytes*/1); 15739217Sgibbs } 15839217Sgibbs 15959171Snyan rid = PCI_BASEADR0; 160127135Snjl iores = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, 161127135Snjl RF_ACTIVE); 16259082Snyan if (iores == NULL) 16359082Snyan return ENXIO; 16439217Sgibbs 165241492Sjhb if (adv_find_signature(iores) == 0) { 16676307Snyan bus_release_resource(dev, SYS_RES_IOPORT, rid, iores); 16759082Snyan return ENXIO; 16859171Snyan } 16939217Sgibbs 170241492Sjhb adv = adv_alloc(dev, iores, 0); 17159171Snyan if (adv == NULL) { 17276307Snyan bus_release_resource(dev, SYS_RES_IOPORT, rid, iores); 17359082Snyan return ENXIO; 17459171Snyan } 17539217Sgibbs 17639217Sgibbs /* Allocate a dmatag for our transfer DMA maps */ 177112782Smdodd error = bus_dma_tag_create( 178232854Sscottl /* parent */ bus_get_dma_tag(dev), 179112782Smdodd /* alignment */ 1, 180112782Smdodd /* boundary */ 0, 181112782Smdodd /* lowaddr */ ADV_PCI_MAX_DMA_ADDR, 182112782Smdodd /* highaddr */ BUS_SPACE_MAXADDR, 183112782Smdodd /* filter */ NULL, 184112782Smdodd /* filterarg */ NULL, 185112782Smdodd /* maxsize */ BUS_SPACE_MAXSIZE_32BIT, 186112782Smdodd /* nsegments */ ~0, 187112782Smdodd /* maxsegsz */ ADV_PCI_MAX_DMA_COUNT, 188112782Smdodd /* flags */ 0, 189241492Sjhb /* lockfunc */ NULL, 190241492Sjhb /* lockarg */ NULL, 191112782Smdodd &adv->parent_dmat); 19239217Sgibbs 19339217Sgibbs if (error != 0) { 194241492Sjhb device_printf(dev, "Could not allocate DMA tag - error %d\n", 195241492Sjhb error); 19639217Sgibbs adv_free(adv); 19776307Snyan bus_release_resource(dev, SYS_RES_IOPORT, rid, iores); 19859082Snyan return ENXIO; 19939217Sgibbs } 20039217Sgibbs 20139217Sgibbs adv->init_level++; 20239217Sgibbs 20339217Sgibbs if (overrun_buf == NULL) { 20439217Sgibbs /* Need to allocate our overrun buffer */ 205112782Smdodd if (bus_dma_tag_create( 206112782Smdodd /* parent */ adv->parent_dmat, 207112782Smdodd /* alignment */ 8, 208112782Smdodd /* boundary */ 0, 209112782Smdodd /* lowaddr */ ADV_PCI_MAX_DMA_ADDR, 210112782Smdodd /* highaddr */ BUS_SPACE_MAXADDR, 211112782Smdodd /* filter */ NULL, 212112782Smdodd /* filterarg */ NULL, 213112782Smdodd /* maxsize */ ADV_OVERRUN_BSIZE, 214112782Smdodd /* nsegments */ 1, 215112782Smdodd /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, 216112782Smdodd /* flags */ 0, 217241492Sjhb /* lockfunc */ NULL, 218241492Sjhb /* lockarg */ NULL, 219112782Smdodd &overrun_dmat) != 0) { 22039217Sgibbs bus_dma_tag_destroy(adv->parent_dmat); 22139217Sgibbs adv_free(adv); 22276307Snyan bus_release_resource(dev, SYS_RES_IOPORT, rid, iores); 22359082Snyan return ENXIO; 22439217Sgibbs } 22539217Sgibbs if (bus_dmamem_alloc(overrun_dmat, 226155319Simp &overrun_buf, 22739217Sgibbs BUS_DMA_NOWAIT, 22839217Sgibbs &overrun_dmamap) != 0) { 22939217Sgibbs bus_dma_tag_destroy(overrun_dmat); 23039217Sgibbs bus_dma_tag_destroy(adv->parent_dmat); 23139217Sgibbs adv_free(adv); 23276307Snyan bus_release_resource(dev, SYS_RES_IOPORT, rid, iores); 23359082Snyan return ENXIO; 23439217Sgibbs } 23539217Sgibbs /* And permanently map it in */ 23639217Sgibbs bus_dmamap_load(overrun_dmat, overrun_dmamap, 23739217Sgibbs overrun_buf, ADV_OVERRUN_BSIZE, 23839217Sgibbs adv_map, &overrun_physbase, 23939217Sgibbs /*flags*/0); 24039217Sgibbs } 24139217Sgibbs 24239217Sgibbs adv->overrun_physbase = overrun_physbase; 24339217Sgibbs 24439217Sgibbs /* 24539217Sgibbs * Stop the chip. 24639217Sgibbs */ 24739217Sgibbs ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_HALT); 24839217Sgibbs ADV_OUTW(adv, ADV_CHIP_STATUS, 0); 24939217Sgibbs 25039217Sgibbs adv->chip_version = ADV_INB(adv, ADV_NONEISA_CHIP_REVISION); 25139217Sgibbs adv->type = ADV_PCI; 25239217Sgibbs 25339217Sgibbs /* 25439217Sgibbs * Setup active negation and signal filtering. 25539217Sgibbs */ 25639217Sgibbs { 25739217Sgibbs u_int8_t extra_cfg; 25839217Sgibbs 25939217Sgibbs if (adv->chip_version >= ADV_CHIP_VER_PCI_ULTRA_3150) 26039217Sgibbs adv->type |= ADV_ULTRA; 26155945Sgibbs if (adv->chip_version == ADV_CHIP_VER_PCI_ULTRA_3050) 26239217Sgibbs extra_cfg = ADV_IFC_ACT_NEG | ADV_IFC_WR_EN_FILTER; 26339217Sgibbs else 26439217Sgibbs extra_cfg = ADV_IFC_ACT_NEG | ADV_IFC_SLEW_RATE; 26539217Sgibbs ADV_OUTB(adv, ADV_REG_IFC, extra_cfg); 26639217Sgibbs } 26739217Sgibbs 26839217Sgibbs if (adv_init(adv) != 0) { 26939217Sgibbs adv_free(adv); 27076307Snyan bus_release_resource(dev, SYS_RES_IOPORT, rid, iores); 27159082Snyan return ENXIO; 27239217Sgibbs } 27339217Sgibbs 27439217Sgibbs adv->max_dma_count = ADV_PCI_MAX_DMA_COUNT; 27539217Sgibbs adv->max_dma_addr = ADV_PCI_MAX_DMA_ADDR; 27639217Sgibbs 277153072Sru#if defined(CC_DISABLE_PCI_PARITY_INT) && CC_DISABLE_PCI_PARITY_INT 27841591Sarchie { 27941591Sarchie u_int16_t config_msw; 28041591Sarchie 28141591Sarchie config_msw = ADV_INW(adv, ADV_CONFIG_MSW); 28241591Sarchie config_msw &= 0xFFC0; 28341591Sarchie ADV_OUTW(adv, ADV_CONFIG_MSW, config_msw); 28441591Sarchie } 28539217Sgibbs#endif 28639217Sgibbs 28739217Sgibbs if (id == PCI_DEVICE_ID_ADVANSYS_1200A 28839217Sgibbs || id == PCI_DEVICE_ID_ADVANSYS_1200B) { 28939217Sgibbs adv->bug_fix_control |= ADV_BUG_FIX_IF_NOT_DWB; 29039217Sgibbs adv->bug_fix_control |= ADV_BUG_FIX_ASYN_USE_SYN; 29139217Sgibbs adv->fix_asyn_xfer = ~0; 29239217Sgibbs } 29339217Sgibbs 29476307Snyan irqrid = 0; 295127135Snjl irqres = bus_alloc_resource_any(dev, SYS_RES_IRQ, &irqrid, 296127135Snjl RF_SHAREABLE | RF_ACTIVE); 29759082Snyan if (irqres == NULL || 298241492Sjhb bus_setup_intr(dev, irqres, INTR_TYPE_CAM|INTR_ENTROPY|INTR_MPSAFE, 299241492Sjhb NULL, adv_intr, adv, &ih) != 0) { 300241492Sjhb if (irqres != NULL) 301241492Sjhb bus_release_resource(dev, SYS_RES_IRQ, irqrid, irqres); 30239217Sgibbs adv_free(adv); 30376307Snyan bus_release_resource(dev, SYS_RES_IOPORT, rid, iores); 30459082Snyan return ENXIO; 30539217Sgibbs } 30659082Snyan 307241492Sjhb if (adv_attach(adv) != 0) { 308241492Sjhb bus_teardown_intr(dev, irqres, ih); 309241492Sjhb bus_release_resource(dev, SYS_RES_IRQ, irqrid, irqres); 310241492Sjhb adv_free(adv); 311241492Sjhb bus_release_resource(dev, SYS_RES_IOPORT, rid, iores); 312241492Sjhb return ENXIO; 313241492Sjhb } 31459082Snyan return 0; 31539217Sgibbs} 31659082Snyan 31759082Snyanstatic device_method_t adv_pci_methods[] = { 31859082Snyan /* Device interface */ 31959082Snyan DEVMETHOD(device_probe, adv_pci_probe), 32059082Snyan DEVMETHOD(device_attach, adv_pci_attach), 32159082Snyan { 0, 0 } 32259082Snyan}; 32359082Snyan 32459082Snyanstatic driver_t adv_pci_driver = { 32559082Snyan "adv", adv_pci_methods, sizeof(struct adv_softc) 32659082Snyan}; 32759082Snyan 32859082Snyanstatic devclass_t adv_pci_devclass; 32959082SnyanDRIVER_MODULE(adv, pci, adv_pci_driver, adv_pci_devclass, 0, 0); 330165102SmjacobMODULE_DEPEND(adv, pci, 1, 1, 1); 331