mpt_pci.c revision 224493
1119418Sobrien/*- 2102596Smjacob * PCI specific probe and attach routines for LSI Fusion Adapters 3101704Smjacob * FreeBSD Version. 4101704Smjacob * 5119418Sobrien * Copyright (c) 2000, 2001 by Greg Ansley 6101704Smjacob * Partially derived from Matt Jacob's ISP driver. 7119418Sobrien * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002 by Matthew Jacob 8119418Sobrien * Feral Software 9119418Sobrien * All rights reserved. 10101704Smjacob * 11101704Smjacob * Redistribution and use in source and binary forms, with or without 12101704Smjacob * modification, are permitted provided that the following conditions 13101704Smjacob * are met: 14101704Smjacob * 1. Redistributions of source code must retain the above copyright 15101704Smjacob * notice immediately at the beginning of the file, without modification, 16101704Smjacob * this list of conditions, and the following disclaimer. 17101704Smjacob * 2. The name of the author may not be used to endorse or promote products 18101704Smjacob * derived from this software without specific prior written permission. 19101704Smjacob * 20101704Smjacob * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21101704Smjacob * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22101704Smjacob * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23101704Smjacob * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 24101704Smjacob * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25101704Smjacob * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26101704Smjacob * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27101704Smjacob * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28101704Smjacob * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29101704Smjacob * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30101704Smjacob * SUCH DAMAGE. 31101704Smjacob */ 32156000Smjacob/*- 33156000Smjacob * Copyright (c) 2002, 2006 by Matthew Jacob 34156000Smjacob * All rights reserved. 35156000Smjacob * 36156000Smjacob * Redistribution and use in source and binary forms, with or without 37156000Smjacob * modification, are permitted provided that the following conditions are 38156000Smjacob * met: 39156000Smjacob * 1. Redistributions of source code must retain the above copyright 40156000Smjacob * notice, this list of conditions and the following disclaimer. 41156000Smjacob * 2. Redistributions in binary form must reproduce at minimum a disclaimer 42156000Smjacob * substantially similar to the "NO WARRANTY" disclaimer below 43156000Smjacob * ("Disclaimer") and any redistribution must be conditioned upon including 44156000Smjacob * a substantially similar Disclaimer requirement for further binary 45156000Smjacob * redistribution. 46156000Smjacob * 3. Neither the names of the above listed copyright holders nor the names 47156000Smjacob * of any contributors may be used to endorse or promote products derived 48156000Smjacob * from this software without specific prior written permission. 49156000Smjacob * 50156000Smjacob * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 51156000Smjacob * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52156000Smjacob * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 53156000Smjacob * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 54156000Smjacob * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 55156000Smjacob * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 56156000Smjacob * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 57156000Smjacob * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 58156000Smjacob * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 59156000Smjacob * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT 60156000Smjacob * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 61156000Smjacob * 62156000Smjacob * Support from Chris Ellsworth in order to make SAS adapters work 63156000Smjacob * is gratefully acknowledged. 64159052Smjacob * 65159052Smjacob * Support from LSI-Logic has also gone a great deal toward making this a 66159052Smjacob * workable subsystem and is gratefully acknowledged. 67156000Smjacob */ 68147883Sscottl/* 69147883Sscottl * Copyright (c) 2004, Avid Technology, Inc. and its contributors. 70147883Sscottl * Copyright (c) 2005, WHEEL Sp. z o.o. 71147883Sscottl * Copyright (c) 2004, 2005 Justin T. Gibbs 72147883Sscottl * All rights reserved. 73147883Sscottl * 74147883Sscottl * Redistribution and use in source and binary forms, with or without 75147883Sscottl * modification, are permitted provided that the following conditions are 76147883Sscottl * met: 77147883Sscottl * 1. Redistributions of source code must retain the above copyright 78147883Sscottl * notice, this list of conditions and the following disclaimer. 79147883Sscottl * 2. Redistributions in binary form must reproduce at minimum a disclaimer 80147883Sscottl * substantially similar to the "NO WARRANTY" disclaimer below 81147883Sscottl * ("Disclaimer") and any redistribution must be conditioned upon including 82147883Sscottl * a substantially similar Disclaimer requirement for further binary 83147883Sscottl * redistribution. 84148679Sgibbs * 3. Neither the names of the above listed copyright holders nor the names 85148679Sgibbs * of any contributors may be used to endorse or promote products derived 86148679Sgibbs * from this software without specific prior written permission. 87147883Sscottl * 88147883Sscottl * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 89147883Sscottl * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 90147883Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 91147883Sscottl * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 92147883Sscottl * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 93147883Sscottl * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 94147883Sscottl * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 95147883Sscottl * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 96147883Sscottl * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 97147883Sscottl * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT 98147883Sscottl * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 99147883Sscottl */ 100101704Smjacob 101119418Sobrien#include <sys/cdefs.h> 102119418Sobrien__FBSDID("$FreeBSD: head/sys/dev/mpt/mpt_pci.c 224493 2011-07-29 18:35:10Z marius $"); 103119418Sobrien 104147883Sscottl#include <dev/mpt/mpt.h> 105147883Sscottl#include <dev/mpt/mpt_cam.h> 106147883Sscottl#include <dev/mpt/mpt_raid.h> 107102199Smjacob 108165814Smjacob#if __FreeBSD_version < 700000 109166721Sjhb#define pci_msix_count(x) 0 110165814Smjacob#define pci_msi_count(x) 0 111165814Smjacob#define pci_alloc_msi(x, y) 1 112166721Sjhb#define pci_alloc_msix(x, y) 1 113165814Smjacob#define pci_release_msi(x) do { ; } while (0) 114165814Smjacob#endif 115101704Smjacob 116101704Smjacob#ifndef PCI_VENDOR_LSI 117101704Smjacob#define PCI_VENDOR_LSI 0x1000 118101704Smjacob#endif 119101704Smjacob 120101704Smjacob#ifndef PCI_PRODUCT_LSI_FC909 121101704Smjacob#define PCI_PRODUCT_LSI_FC909 0x0620 122101704Smjacob#endif 123101704Smjacob 124102596Smjacob#ifndef PCI_PRODUCT_LSI_FC909A 125102596Smjacob#define PCI_PRODUCT_LSI_FC909A 0x0621 126102596Smjacob#endif 127102596Smjacob 128103829Smjacob#ifndef PCI_PRODUCT_LSI_FC919 129103829Smjacob#define PCI_PRODUCT_LSI_FC919 0x0624 130103829Smjacob#endif 131103829Smjacob 132101704Smjacob#ifndef PCI_PRODUCT_LSI_FC929 133101704Smjacob#define PCI_PRODUCT_LSI_FC929 0x0622 134101704Smjacob#endif 135101704Smjacob 136150007Smjacob#ifndef PCI_PRODUCT_LSI_FC929X 137150007Smjacob#define PCI_PRODUCT_LSI_FC929X 0x0626 138150007Smjacob#endif 139150007Smjacob 140159494Smjacob#ifndef PCI_PRODUCT_LSI_FC919X 141159494Smjacob#define PCI_PRODUCT_LSI_FC919X 0x0628 142159494Smjacob#endif 143159494Smjacob 144158279Smjacob#ifndef PCI_PRODUCT_LSI_FC7X04X 145158279Smjacob#define PCI_PRODUCT_LSI_FC7X04X 0x0640 146158279Smjacob#endif 147158279Smjacob 148162140Smjacob#ifndef PCI_PRODUCT_LSI_FC646 149162140Smjacob#define PCI_PRODUCT_LSI_FC646 0x0646 150162140Smjacob#endif 151162140Smjacob 152101704Smjacob#ifndef PCI_PRODUCT_LSI_1030 153101704Smjacob#define PCI_PRODUCT_LSI_1030 0x0030 154101704Smjacob#endif 155101704Smjacob 156155521Smjacob#ifndef PCI_PRODUCT_LSI_SAS1064 157155521Smjacob#define PCI_PRODUCT_LSI_SAS1064 0x0050 158155521Smjacob#endif 159155521Smjacob 160155521Smjacob#ifndef PCI_PRODUCT_LSI_SAS1064A 161155521Smjacob#define PCI_PRODUCT_LSI_SAS1064A 0x005C 162155521Smjacob#endif 163155521Smjacob 164155521Smjacob#ifndef PCI_PRODUCT_LSI_SAS1064E 165155521Smjacob#define PCI_PRODUCT_LSI_SAS1064E 0x0056 166155521Smjacob#endif 167155521Smjacob 168155521Smjacob#ifndef PCI_PRODUCT_LSI_SAS1066 169155521Smjacob#define PCI_PRODUCT_LSI_SAS1066 0x005E 170155521Smjacob#endif 171155521Smjacob 172155521Smjacob#ifndef PCI_PRODUCT_LSI_SAS1066E 173155521Smjacob#define PCI_PRODUCT_LSI_SAS1066E 0x005A 174155521Smjacob#endif 175155521Smjacob 176155521Smjacob#ifndef PCI_PRODUCT_LSI_SAS1068 177155521Smjacob#define PCI_PRODUCT_LSI_SAS1068 0x0054 178155521Smjacob#endif 179155521Smjacob 180155521Smjacob#ifndef PCI_PRODUCT_LSI_SAS1068E 181155521Smjacob#define PCI_PRODUCT_LSI_SAS1068E 0x0058 182155521Smjacob#endif 183155521Smjacob 184155521Smjacob#ifndef PCI_PRODUCT_LSI_SAS1078 185172219Sambrisko#define PCI_PRODUCT_LSI_SAS1078 0x0062 186155521Smjacob#endif 187155521Smjacob 188178896Sdelphij#ifndef PCI_PRODUCT_LSI_SAS1078DE 189178896Sdelphij#define PCI_PRODUCT_LSI_SAS1078DE 0x007C 190178896Sdelphij#endif 191178896Sdelphij 192102303Smjacob#ifndef PCIM_CMD_SERRESPEN 193102303Smjacob#define PCIM_CMD_SERRESPEN 0x0100 194102303Smjacob#endif 195101704Smjacob 196147883Sscottlstatic int mpt_pci_probe(device_t); 197147883Sscottlstatic int mpt_pci_attach(device_t); 198147883Sscottlstatic void mpt_free_bus_resources(struct mpt_softc *mpt); 199147883Sscottlstatic int mpt_pci_detach(device_t); 200147883Sscottlstatic int mpt_pci_shutdown(device_t); 201147883Sscottlstatic int mpt_dma_mem_alloc(struct mpt_softc *mpt); 202147883Sscottlstatic void mpt_dma_mem_free(struct mpt_softc *mpt); 203147883Sscottlstatic void mpt_read_config_regs(struct mpt_softc *mpt); 204224493Smarius#if 0 205224493Smariusstatic void mpt_set_config_regs(struct mpt_softc *mpt); 206224493Smarius#endif 207102199Smjacobstatic void mpt_pci_intr(void *); 208101704Smjacob 209101704Smjacobstatic device_method_t mpt_methods[] = { 210101704Smjacob /* Device interface */ 211147883Sscottl DEVMETHOD(device_probe, mpt_pci_probe), 212147883Sscottl DEVMETHOD(device_attach, mpt_pci_attach), 213147883Sscottl DEVMETHOD(device_detach, mpt_pci_detach), 214147883Sscottl DEVMETHOD(device_shutdown, mpt_pci_shutdown), 215101704Smjacob { 0, 0 } 216101704Smjacob}; 217101704Smjacob 218101704Smjacobstatic driver_t mpt_driver = { 219147883Sscottl "mpt", mpt_methods, sizeof(struct mpt_softc) 220101704Smjacob}; 221101704Smjacobstatic devclass_t mpt_devclass; 222101704SmjacobDRIVER_MODULE(mpt, pci, mpt_driver, mpt_devclass, 0, 0); 223165058SmjacobMODULE_DEPEND(mpt, pci, 1, 1, 1); 224101704SmjacobMODULE_VERSION(mpt, 1); 225101704Smjacob 226101704Smjacobstatic int 227147883Sscottlmpt_pci_probe(device_t dev) 228101704Smjacob{ 229101704Smjacob char *desc; 230101704Smjacob 231160290Smjacob if (pci_get_vendor(dev) != PCI_VENDOR_LSI) { 232101704Smjacob return (ENXIO); 233160290Smjacob } 234101704Smjacob 235101704Smjacob switch ((pci_get_device(dev) & ~1)) { 236101704Smjacob case PCI_PRODUCT_LSI_FC909: 237101704Smjacob desc = "LSILogic FC909 FC Adapter"; 238101704Smjacob break; 239102596Smjacob case PCI_PRODUCT_LSI_FC909A: 240102596Smjacob desc = "LSILogic FC909A FC Adapter"; 241102596Smjacob break; 242103829Smjacob case PCI_PRODUCT_LSI_FC919: 243103829Smjacob desc = "LSILogic FC919 FC Adapter"; 244103829Smjacob break; 245101704Smjacob case PCI_PRODUCT_LSI_FC929: 246162140Smjacob desc = "Dual LSILogic FC929 FC Adapter"; 247101704Smjacob break; 248159494Smjacob case PCI_PRODUCT_LSI_FC919X: 249162140Smjacob desc = "LSILogic FC919 FC PCI-X Adapter"; 250159494Smjacob break; 251150007Smjacob case PCI_PRODUCT_LSI_FC929X: 252162140Smjacob desc = "Dual LSILogic FC929X 2Gb/s FC PCI-X Adapter"; 253150007Smjacob break; 254162140Smjacob case PCI_PRODUCT_LSI_FC646: 255162140Smjacob desc = "Dual LSILogic FC7X04X 4Gb/s FC PCI-Express Adapter"; 256162140Smjacob break; 257158279Smjacob case PCI_PRODUCT_LSI_FC7X04X: 258162140Smjacob desc = "Dual LSILogic FC7X04X 4Gb/s FC PCI-X Adapter"; 259158279Smjacob break; 260101704Smjacob case PCI_PRODUCT_LSI_1030: 261101704Smjacob desc = "LSILogic 1030 Ultra4 Adapter"; 262101704Smjacob break; 263155521Smjacob case PCI_PRODUCT_LSI_SAS1064: 264155521Smjacob case PCI_PRODUCT_LSI_SAS1064A: 265155521Smjacob case PCI_PRODUCT_LSI_SAS1064E: 266155521Smjacob case PCI_PRODUCT_LSI_SAS1066: 267155521Smjacob case PCI_PRODUCT_LSI_SAS1066E: 268155521Smjacob case PCI_PRODUCT_LSI_SAS1068: 269155521Smjacob case PCI_PRODUCT_LSI_SAS1068E: 270155521Smjacob case PCI_PRODUCT_LSI_SAS1078: 271178896Sdelphij case PCI_PRODUCT_LSI_SAS1078DE: 272162140Smjacob desc = "LSILogic SAS/SATA Adapter"; 273155521Smjacob break; 274101704Smjacob default: 275101704Smjacob return (ENXIO); 276101704Smjacob } 277101704Smjacob 278101704Smjacob device_set_desc(dev, desc); 279147883Sscottl return (0); 280101704Smjacob} 281101704Smjacob 282157117Smjacob#if __FreeBSD_version < 500000 283101704Smjacobstatic void 284147883Sscottlmpt_set_options(struct mpt_softc *mpt) 285101704Smjacob{ 286101704Smjacob int bitmap; 287101704Smjacob 288101704Smjacob bitmap = 0; 289101704Smjacob if (getenv_int("mpt_disable", &bitmap)) { 290101704Smjacob if (bitmap & (1 << mpt->unit)) { 291101704Smjacob mpt->disabled = 1; 292101704Smjacob } 293101704Smjacob } 294101704Smjacob bitmap = 0; 295101704Smjacob if (getenv_int("mpt_debug", &bitmap)) { 296101704Smjacob if (bitmap & (1 << mpt->unit)) { 297147883Sscottl mpt->verbose = MPT_PRT_DEBUG; 298101704Smjacob } 299101704Smjacob } 300157117Smjacob bitmap = 0; 301157662Smjacob if (getenv_int("mpt_debug1", &bitmap)) { 302157117Smjacob if (bitmap & (1 << mpt->unit)) { 303157662Smjacob mpt->verbose = MPT_PRT_DEBUG1; 304157117Smjacob } 305157117Smjacob } 306157117Smjacob bitmap = 0; 307157662Smjacob if (getenv_int("mpt_debug2", &bitmap)) { 308157117Smjacob if (bitmap & (1 << mpt->unit)) { 309157662Smjacob mpt->verbose = MPT_PRT_DEBUG2; 310157117Smjacob } 311157117Smjacob } 312157117Smjacob bitmap = 0; 313157662Smjacob if (getenv_int("mpt_debug3", &bitmap)) { 314157117Smjacob if (bitmap & (1 << mpt->unit)) { 315157662Smjacob mpt->verbose = MPT_PRT_DEBUG3; 316157117Smjacob } 317157117Smjacob } 318160290Smjacob 319160290Smjacob mpt->cfg_role = MPT_ROLE_DEFAULT; 320160290Smjacob bitmap = 0; 321160290Smjacob if (getenv_int("mpt_nil_role", &bitmap)) { 322160290Smjacob if (bitmap & (1 << mpt->unit)) { 323160290Smjacob mpt->cfg_role = 0; 324160290Smjacob } 325160290Smjacob mpt->do_cfg_role = 1; 326160290Smjacob } 327160290Smjacob bitmap = 0; 328160290Smjacob if (getenv_int("mpt_tgt_role", &bitmap)) { 329160290Smjacob if (bitmap & (1 << mpt->unit)) { 330160290Smjacob mpt->cfg_role |= MPT_ROLE_TARGET; 331160290Smjacob } 332160290Smjacob mpt->do_cfg_role = 1; 333160290Smjacob } 334160290Smjacob bitmap = 0; 335160290Smjacob if (getenv_int("mpt_ini_role", &bitmap)) { 336160290Smjacob if (bitmap & (1 << mpt->unit)) { 337160290Smjacob mpt->cfg_role |= MPT_ROLE_INITIATOR; 338160290Smjacob } 339160290Smjacob mpt->do_cfg_role = 1; 340160290Smjacob } 341164416Smjacob mpt->msi_enable = 0; 342101704Smjacob} 343101704Smjacob#else 344101704Smjacobstatic void 345147883Sscottlmpt_set_options(struct mpt_softc *mpt) 346101704Smjacob{ 347101704Smjacob int tval; 348101704Smjacob 349101704Smjacob tval = 0; 350101704Smjacob if (resource_int_value(device_get_name(mpt->dev), 351101704Smjacob device_get_unit(mpt->dev), "disable", &tval) == 0 && tval != 0) { 352101704Smjacob mpt->disabled = 1; 353101704Smjacob } 354101704Smjacob tval = 0; 355101704Smjacob if (resource_int_value(device_get_name(mpt->dev), 356101704Smjacob device_get_unit(mpt->dev), "debug", &tval) == 0 && tval != 0) { 357159041Smjacob mpt->verbose = tval; 358101704Smjacob } 359160290Smjacob tval = -1; 360157117Smjacob if (resource_int_value(device_get_name(mpt->dev), 361160290Smjacob device_get_unit(mpt->dev), "role", &tval) == 0 && tval >= 0 && 362157117Smjacob tval <= 3) { 363160290Smjacob mpt->cfg_role = tval; 364160290Smjacob mpt->do_cfg_role = 1; 365157117Smjacob } 366164416Smjacob tval = 0; 367164417Smjacob mpt->msi_enable = 0; 368223985Smarius if (mpt->is_sas) 369223985Smarius mpt->msi_enable = 1; 370164416Smjacob if (resource_int_value(device_get_name(mpt->dev), 371223985Smarius device_get_unit(mpt->dev), "msi_enable", &tval) == 0) { 372223985Smarius mpt->msi_enable = tval; 373164416Smjacob } 374101704Smjacob} 375101704Smjacob#endif 376101704Smjacob 377102303Smjacobstatic void 378147883Sscottlmpt_link_peer(struct mpt_softc *mpt) 379102303Smjacob{ 380147883Sscottl struct mpt_softc *mpt2; 381102303Smjacob 382157662Smjacob if (mpt->unit == 0) { 383102303Smjacob return; 384157662Smjacob } 385102303Smjacob /* 386102303Smjacob * XXX: depends on probe order 387102303Smjacob */ 388147883Sscottl mpt2 = (struct mpt_softc *)devclass_get_softc(mpt_devclass,mpt->unit-1); 389102303Smjacob 390102303Smjacob if (mpt2 == NULL) { 391102303Smjacob return; 392102303Smjacob } 393102303Smjacob if (pci_get_vendor(mpt2->dev) != pci_get_vendor(mpt->dev)) { 394102303Smjacob return; 395102303Smjacob } 396102303Smjacob if (pci_get_device(mpt2->dev) != pci_get_device(mpt->dev)) { 397102303Smjacob return; 398102303Smjacob } 399102303Smjacob mpt->mpt2 = mpt2; 400102303Smjacob mpt2->mpt2 = mpt; 401147883Sscottl if (mpt->verbose >= MPT_PRT_DEBUG) { 402147883Sscottl mpt_prt(mpt, "linking with peer (mpt%d)\n", 403102303Smjacob device_get_unit(mpt2->dev)); 404102303Smjacob } 405102303Smjacob} 406102303Smjacob 407157662Smjacobstatic void 408157662Smjacobmpt_unlink_peer(struct mpt_softc *mpt) 409157662Smjacob{ 410224493Smarius 411157662Smjacob if (mpt->mpt2) { 412157662Smjacob mpt->mpt2->mpt2 = NULL; 413157662Smjacob } 414157662Smjacob} 415102303Smjacob 416101704Smjacobstatic int 417147883Sscottlmpt_pci_attach(device_t dev) 418101704Smjacob{ 419147883Sscottl struct mpt_softc *mpt; 420147883Sscottl int iqd; 421147883Sscottl uint32_t data, cmd; 422210943Smjacob int mpt_io_bar, mpt_mem_bar; 423101704Smjacob 424101704Smjacob /* Allocate the softc structure */ 425147883Sscottl mpt = (struct mpt_softc*)device_get_softc(dev); 426101704Smjacob if (mpt == NULL) { 427101704Smjacob device_printf(dev, "cannot allocate softc\n"); 428101704Smjacob return (ENOMEM); 429101704Smjacob } 430157354Smjacob memset(mpt, 0, sizeof(struct mpt_softc)); 431101704Smjacob switch ((pci_get_device(dev) & ~1)) { 432101704Smjacob case PCI_PRODUCT_LSI_FC909: 433102596Smjacob case PCI_PRODUCT_LSI_FC909A: 434103829Smjacob case PCI_PRODUCT_LSI_FC919: 435101704Smjacob case PCI_PRODUCT_LSI_FC929: 436159494Smjacob case PCI_PRODUCT_LSI_FC919X: 437162140Smjacob case PCI_PRODUCT_LSI_FC646: 438158279Smjacob case PCI_PRODUCT_LSI_FC7X04X: 439101704Smjacob mpt->is_fc = 1; 440101704Smjacob break; 441155521Smjacob case PCI_PRODUCT_LSI_SAS1064: 442155521Smjacob case PCI_PRODUCT_LSI_SAS1064A: 443155521Smjacob case PCI_PRODUCT_LSI_SAS1064E: 444155521Smjacob case PCI_PRODUCT_LSI_SAS1066: 445155521Smjacob case PCI_PRODUCT_LSI_SAS1066E: 446155521Smjacob case PCI_PRODUCT_LSI_SAS1068: 447155521Smjacob case PCI_PRODUCT_LSI_SAS1068E: 448155521Smjacob case PCI_PRODUCT_LSI_SAS1078: 449178896Sdelphij case PCI_PRODUCT_LSI_SAS1078DE: 450155521Smjacob mpt->is_sas = 1; 451155521Smjacob break; 452101704Smjacob default: 453159178Smjacob mpt->is_spi = 1; 454101704Smjacob break; 455101704Smjacob } 456101704Smjacob mpt->dev = dev; 457101704Smjacob mpt->unit = device_get_unit(dev); 458147883Sscottl mpt->raid_resync_rate = MPT_RAID_RESYNC_RATE_DEFAULT; 459147883Sscottl mpt->raid_mwce_setting = MPT_RAID_MWCE_DEFAULT; 460147883Sscottl mpt->raid_queue_depth = MPT_RAID_QUEUE_DEPTH_DEFAULT; 461155521Smjacob mpt->verbose = MPT_PRT_NONE; 462157662Smjacob mpt->role = MPT_ROLE_NONE; 463207287Smarius mpt->mpt_ini_id = MPT_INI_ID_NONE; 464207287Smarius#ifdef __sparc64__ 465207287Smarius if (mpt->is_spi) 466207287Smarius mpt->mpt_ini_id = OF_getscsinitid(dev); 467207287Smarius#endif 468101704Smjacob mpt_set_options(mpt); 469155521Smjacob if (mpt->verbose == MPT_PRT_NONE) { 470155521Smjacob mpt->verbose = MPT_PRT_WARN; 471155521Smjacob /* Print INFO level (if any) if bootverbose is set */ 472155521Smjacob mpt->verbose += (bootverbose != 0)? 1 : 0; 473155521Smjacob } 474101704Smjacob /* Make sure memory access decoders are enabled */ 475101704Smjacob cmd = pci_read_config(dev, PCIR_COMMAND, 2); 476101704Smjacob if ((cmd & PCIM_CMD_MEMEN) == 0) { 477101704Smjacob device_printf(dev, "Memory accesses disabled"); 478157662Smjacob return (ENXIO); 479101704Smjacob } 480101704Smjacob 481101704Smjacob /* 482101704Smjacob * Make sure that SERR, PERR, WRITE INVALIDATE and BUSMASTER are set. 483101704Smjacob */ 484101704Smjacob cmd |= 485101704Smjacob PCIM_CMD_SERRESPEN | PCIM_CMD_PERRESPEN | 486101704Smjacob PCIM_CMD_BUSMASTEREN | PCIM_CMD_MWRICEN; 487101704Smjacob pci_write_config(dev, PCIR_COMMAND, cmd, 2); 488101704Smjacob 489101704Smjacob /* 490101704Smjacob * Make sure we've disabled the ROM. 491101704Smjacob */ 492101704Smjacob data = pci_read_config(dev, PCIR_BIOS, 4); 493201275Sjhb data &= ~PCIM_BIOS_ENABLE; 494101704Smjacob pci_write_config(dev, PCIR_BIOS, data, 4); 495101704Smjacob 496102303Smjacob /* 497102303Smjacob * Is this part a dual? 498102303Smjacob * If so, link with our partner (around yet) 499102303Smjacob */ 500102303Smjacob if ((pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_FC929 || 501162140Smjacob (pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_FC646 || 502158279Smjacob (pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_FC7X04X || 503102303Smjacob (pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_1030) { 504102303Smjacob mpt_link_peer(mpt); 505101704Smjacob } 506101704Smjacob 507147883Sscottl /* 508210943Smjacob * Figure out which are the I/O and MEM Bars 509210943Smjacob */ 510210943Smjacob data = pci_read_config(dev, PCIR_BAR(0), 4); 511210943Smjacob if (PCI_BAR_IO(data)) { 512210943Smjacob /* BAR0 is IO, BAR1 is memory */ 513210943Smjacob mpt_io_bar = 0; 514210943Smjacob mpt_mem_bar = 1; 515210943Smjacob } else { 516210943Smjacob /* BAR0 is memory, BAR1 is IO */ 517210943Smjacob mpt_mem_bar = 0; 518210943Smjacob mpt_io_bar = 1; 519210943Smjacob } 520210943Smjacob 521210943Smjacob /* 522147883Sscottl * Set up register access. PIO mode is required for 523155521Smjacob * certain reset operations (but must be disabled for 524155521Smjacob * some cards otherwise). 525147883Sscottl */ 526223985Smarius mpt_io_bar = PCIR_BAR(mpt_io_bar); 527216764Sjhb mpt->pci_pio_reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT, 528223985Smarius &mpt_io_bar, RF_ACTIVE); 529147883Sscottl if (mpt->pci_pio_reg == NULL) { 530147883Sscottl device_printf(dev, "unable to map registers in PIO mode\n"); 531147883Sscottl goto bad; 532147883Sscottl } 533147883Sscottl mpt->pci_pio_st = rman_get_bustag(mpt->pci_pio_reg); 534147883Sscottl mpt->pci_pio_sh = rman_get_bushandle(mpt->pci_pio_reg); 535147883Sscottl 536101704Smjacob /* Allocate kernel virtual memory for the 9x9's Mem0 region */ 537223985Smarius mpt_mem_bar = PCIR_BAR(mpt_mem_bar); 538216764Sjhb mpt->pci_reg = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 539223985Smarius &mpt_mem_bar, RF_ACTIVE); 540101704Smjacob if (mpt->pci_reg == NULL) { 541147883Sscottl device_printf(dev, "Unable to memory map registers.\n"); 542155521Smjacob if (mpt->is_sas) { 543155521Smjacob device_printf(dev, "Giving Up.\n"); 544155521Smjacob goto bad; 545155521Smjacob } 546147883Sscottl device_printf(dev, "Falling back to PIO mode.\n"); 547147883Sscottl mpt->pci_st = mpt->pci_pio_st; 548147883Sscottl mpt->pci_sh = mpt->pci_pio_sh; 549147883Sscottl } else { 550147883Sscottl mpt->pci_st = rman_get_bustag(mpt->pci_reg); 551147883Sscottl mpt->pci_sh = rman_get_bushandle(mpt->pci_reg); 552101704Smjacob } 553101704Smjacob 554101704Smjacob /* Get a handle to the interrupt */ 555101704Smjacob iqd = 0; 556166721Sjhb if (mpt->msi_enable) { 557166721Sjhb /* 558166721Sjhb * First try to alloc an MSI-X message. If that 559166721Sjhb * fails, then try to alloc an MSI message instead. 560166721Sjhb */ 561166721Sjhb if (pci_msix_count(dev) == 1) { 562166721Sjhb mpt->pci_msi_count = 1; 563166721Sjhb if (pci_alloc_msix(dev, &mpt->pci_msi_count) == 0) { 564166721Sjhb iqd = 1; 565166721Sjhb } else { 566166721Sjhb mpt->pci_msi_count = 0; 567166721Sjhb } 568164416Smjacob } 569166721Sjhb if (iqd == 0 && pci_msi_count(dev) == 1) { 570166721Sjhb mpt->pci_msi_count = 1; 571166721Sjhb if (pci_alloc_msi(dev, &mpt->pci_msi_count) == 0) { 572166721Sjhb iqd = 1; 573166721Sjhb } else { 574166721Sjhb mpt->pci_msi_count = 0; 575166721Sjhb } 576166721Sjhb } 577166721Sjhb } 578127135Snjl mpt->pci_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &iqd, 579223985Smarius RF_ACTIVE | (mpt->pci_msi_count ? 0 : RF_SHAREABLE)); 580101704Smjacob if (mpt->pci_irq == NULL) { 581101704Smjacob device_printf(dev, "could not allocate interrupt\n"); 582101704Smjacob goto bad; 583101704Smjacob } 584101704Smjacob 585147883Sscottl MPT_LOCK_SETUP(mpt); 586147883Sscottl 587147883Sscottl /* Disable interrupts at the part */ 588147883Sscottl mpt_disable_ints(mpt); 589147883Sscottl 590101704Smjacob /* Register the interrupt handler */ 591166935Smjacob if (mpt_setup_intr(dev, mpt->pci_irq, MPT_IFLAGS, NULL, mpt_pci_intr, 592101704Smjacob mpt, &mpt->ih)) { 593101704Smjacob device_printf(dev, "could not setup interrupt\n"); 594101704Smjacob goto bad; 595101704Smjacob } 596101704Smjacob 597101704Smjacob /* Allocate dma memory */ 598101704Smjacob if (mpt_dma_mem_alloc(mpt)) { 599159091Smjacob mpt_prt(mpt, "Could not allocate DMA memory\n"); 600101704Smjacob goto bad; 601101704Smjacob } 602101704Smjacob 603102199Smjacob /* 604102199Smjacob * Save the PCI config register values 605102199Smjacob * 606102199Smjacob * Hard resets are known to screw up the BAR for diagnostic 607102199Smjacob * memory accesses (Mem1). 608102199Smjacob * 609102199Smjacob * Using Mem1 is known to make the chip stop responding to 610102199Smjacob * configuration space transfers, so we need to save it now 611102199Smjacob */ 612101704Smjacob 613101704Smjacob mpt_read_config_regs(mpt); 614101704Smjacob 615155521Smjacob /* 616155521Smjacob * Disable PIO until we need it 617155521Smjacob */ 618159919Smjacob if (mpt->is_sas) { 619159919Smjacob pci_disable_io(dev, SYS_RES_IOPORT); 620159919Smjacob } 621155521Smjacob 622101704Smjacob /* Initialize the hardware */ 623101704Smjacob if (mpt->disabled == 0) { 624147883Sscottl if (mpt_attach(mpt) != 0) { 625101704Smjacob goto bad; 626102199Smjacob } 627157117Smjacob } else { 628157117Smjacob mpt_prt(mpt, "device disabled at user request\n"); 629157117Smjacob goto bad; 630101704Smjacob } 631101704Smjacob 632157117Smjacob mpt->eh = EVENTHANDLER_REGISTER(shutdown_post_sync, mpt_pci_shutdown, 633157117Smjacob dev, SHUTDOWN_PRI_DEFAULT); 634157117Smjacob 635157117Smjacob if (mpt->eh == NULL) { 636157117Smjacob mpt_prt(mpt, "shutdown event registration failed\n"); 637157117Smjacob (void) mpt_detach(mpt); 638157117Smjacob goto bad; 639157117Smjacob } 640101704Smjacob return (0); 641101704Smjacob 642101704Smjacobbad: 643101704Smjacob mpt_dma_mem_free(mpt); 644101704Smjacob mpt_free_bus_resources(mpt); 645157662Smjacob mpt_unlink_peer(mpt); 646101704Smjacob 647157662Smjacob MPT_LOCK_DESTROY(mpt); 648157662Smjacob 649101704Smjacob /* 650101704Smjacob * but return zero to preserve unit numbering 651101704Smjacob */ 652101704Smjacob return (0); 653101704Smjacob} 654101704Smjacob 655102199Smjacob/* 656101704Smjacob * Free bus resources 657101704Smjacob */ 658101704Smjacobstatic void 659147883Sscottlmpt_free_bus_resources(struct mpt_softc *mpt) 660101704Smjacob{ 661224493Smarius 662101704Smjacob if (mpt->ih) { 663101704Smjacob bus_teardown_intr(mpt->dev, mpt->pci_irq, mpt->ih); 664223985Smarius mpt->ih = NULL; 665101704Smjacob } 666101704Smjacob 667101704Smjacob if (mpt->pci_irq) { 668164305Sjhb bus_release_resource(mpt->dev, SYS_RES_IRQ, 669223985Smarius rman_get_rid(mpt->pci_irq), mpt->pci_irq); 670223985Smarius mpt->pci_irq = NULL; 671101704Smjacob } 672101704Smjacob 673164305Sjhb if (mpt->pci_msi_count) { 674164305Sjhb pci_release_msi(mpt->dev); 675164305Sjhb mpt->pci_msi_count = 0; 676164305Sjhb } 677164305Sjhb 678147883Sscottl if (mpt->pci_pio_reg) { 679223985Smarius bus_release_resource(mpt->dev, SYS_RES_IOPORT, 680223985Smarius rman_get_rid(mpt->pci_pio_reg), mpt->pci_pio_reg); 681223985Smarius mpt->pci_pio_reg = NULL; 682147883Sscottl } 683101704Smjacob if (mpt->pci_reg) { 684223985Smarius bus_release_resource(mpt->dev, SYS_RES_MEMORY, 685223985Smarius rman_get_rid(mpt->pci_reg), mpt->pci_reg); 686223985Smarius mpt->pci_reg = NULL; 687101704Smjacob } 688102199Smjacob MPT_LOCK_DESTROY(mpt); 689101704Smjacob} 690101704Smjacob 691102199Smjacob/* 692101704Smjacob * Disconnect ourselves from the system. 693101704Smjacob */ 694101704Smjacobstatic int 695147883Sscottlmpt_pci_detach(device_t dev) 696101704Smjacob{ 697147883Sscottl struct mpt_softc *mpt; 698101704Smjacob 699147883Sscottl mpt = (struct mpt_softc*)device_get_softc(dev); 700101704Smjacob 701101704Smjacob if (mpt) { 702101704Smjacob mpt_disable_ints(mpt); 703147883Sscottl mpt_detach(mpt); 704147883Sscottl mpt_reset(mpt, /*reinit*/FALSE); 705101704Smjacob mpt_dma_mem_free(mpt); 706101704Smjacob mpt_free_bus_resources(mpt); 707158982Smjacob mpt_raid_free_mem(mpt); 708158982Smjacob if (mpt->eh != NULL) { 709180152Sjhb EVENTHANDLER_DEREGISTER(shutdown_post_sync, mpt->eh); 710147883Sscottl } 711101704Smjacob } 712101704Smjacob return(0); 713101704Smjacob} 714101704Smjacob 715102199Smjacob/* 716101704Smjacob * Disable the hardware 717101704Smjacob */ 718101704Smjacobstatic int 719147883Sscottlmpt_pci_shutdown(device_t dev) 720101704Smjacob{ 721147883Sscottl struct mpt_softc *mpt; 722101704Smjacob 723147883Sscottl mpt = (struct mpt_softc *)device_get_softc(dev); 724157117Smjacob if (mpt) { 725157117Smjacob int r; 726157117Smjacob r = mpt_shutdown(mpt); 727157117Smjacob return (r); 728157117Smjacob } 729101704Smjacob return(0); 730101704Smjacob} 731101704Smjacob 732101704Smjacobstatic int 733147883Sscottlmpt_dma_mem_alloc(struct mpt_softc *mpt) 734101704Smjacob{ 735103871Smjacob size_t len; 736147883Sscottl struct mpt_map_info mi; 737101704Smjacob 738101704Smjacob /* Check if we alreay have allocated the reply memory */ 739123740Speter if (mpt->reply_phys != 0) { 740101704Smjacob return 0; 741103871Smjacob } 742101704Smjacob 743147883Sscottl len = sizeof (request_t) * MPT_MAX_REQUESTS(mpt); 744103871Smjacob#ifdef RELENG_4 745147883Sscottl mpt->request_pool = (request_t *)malloc(len, M_DEVBUF, M_WAITOK); 746103871Smjacob if (mpt->request_pool == NULL) { 747159091Smjacob mpt_prt(mpt, "cannot allocate request pool\n"); 748103871Smjacob return (1); 749103871Smjacob } 750157354Smjacob memset(mpt->request_pool, 0, len); 751103871Smjacob#else 752147883Sscottl mpt->request_pool = (request_t *)malloc(len, M_DEVBUF, M_WAITOK|M_ZERO); 753103871Smjacob if (mpt->request_pool == NULL) { 754159091Smjacob mpt_prt(mpt, "cannot allocate request pool\n"); 755103871Smjacob return (1); 756103871Smjacob } 757103871Smjacob#endif 758103871Smjacob 759101704Smjacob /* 760155521Smjacob * Create a parent dma tag for this device. 761101704Smjacob * 762159091Smjacob * Align at byte boundaries, 763159091Smjacob * Limit to 32-bit addressing for request/reply queues. 764101704Smjacob */ 765164314Sjb if (mpt_dma_tag_create(mpt, /*parent*/bus_get_dma_tag(mpt->dev), 766164314Sjb /*alignment*/1, /*boundary*/0, /*lowaddr*/BUS_SPACE_MAXADDR, 767147883Sscottl /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, 768147883Sscottl /*maxsize*/BUS_SPACE_MAXSIZE_32BIT, 769209961Smarius /*nsegments*/BUS_SPACE_UNRESTRICTED, 770209961Smarius /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, /*flags*/0, 771147883Sscottl &mpt->parent_dmat) != 0) { 772159091Smjacob mpt_prt(mpt, "cannot create parent dma tag\n"); 773101704Smjacob return (1); 774101704Smjacob } 775101704Smjacob 776101704Smjacob /* Create a child tag for reply buffers */ 777159091Smjacob if (mpt_dma_tag_create(mpt, mpt->parent_dmat, PAGE_SIZE, 0, 778159091Smjacob BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, 779155521Smjacob NULL, NULL, 2 * PAGE_SIZE, 1, BUS_SPACE_MAXSIZE_32BIT, 0, 780147883Sscottl &mpt->reply_dmat) != 0) { 781159091Smjacob mpt_prt(mpt, "cannot create a dma tag for replies\n"); 782101704Smjacob return (1); 783101704Smjacob } 784101704Smjacob 785220945Smarius /* Allocate some DMA accessible memory for replies */ 786101704Smjacob if (bus_dmamem_alloc(mpt->reply_dmat, (void **)&mpt->reply, 787101704Smjacob BUS_DMA_NOWAIT, &mpt->reply_dmap) != 0) { 788159091Smjacob mpt_prt(mpt, "cannot allocate %lu bytes of reply memory\n", 789155521Smjacob (u_long) (2 * PAGE_SIZE)); 790101704Smjacob return (1); 791101704Smjacob } 792101704Smjacob 793147883Sscottl mi.mpt = mpt; 794147883Sscottl mi.error = 0; 795101704Smjacob 796101704Smjacob /* Load and lock it into "bus space" */ 797101704Smjacob bus_dmamap_load(mpt->reply_dmat, mpt->reply_dmap, mpt->reply, 798155521Smjacob 2 * PAGE_SIZE, mpt_map_rquest, &mi, 0); 799101704Smjacob 800147883Sscottl if (mi.error) { 801159091Smjacob mpt_prt(mpt, "error %d loading dma map for DMA reply queue\n", 802159091Smjacob mi.error); 803101704Smjacob return (1); 804101704Smjacob } 805147883Sscottl mpt->reply_phys = mi.phys; 806101704Smjacob 807101704Smjacob return (0); 808101704Smjacob} 809101704Smjacob 810101704Smjacob/* Deallocate memory that was allocated by mpt_dma_mem_alloc 811101704Smjacob */ 812101704Smjacobstatic void 813147883Sscottlmpt_dma_mem_free(struct mpt_softc *mpt) 814101704Smjacob{ 815101704Smjacob 816101704Smjacob /* Make sure we aren't double destroying */ 817101704Smjacob if (mpt->reply_dmat == 0) { 818159091Smjacob mpt_lprt(mpt, MPT_PRT_DEBUG, "already released dma memory\n"); 819101704Smjacob return; 820101704Smjacob } 821101704Smjacob 822101704Smjacob bus_dmamap_unload(mpt->reply_dmat, mpt->reply_dmap); 823101704Smjacob bus_dmamem_free(mpt->reply_dmat, mpt->reply, mpt->reply_dmap); 824101704Smjacob bus_dma_tag_destroy(mpt->reply_dmat); 825101704Smjacob bus_dma_tag_destroy(mpt->parent_dmat); 826223985Smarius mpt->reply_dmat = NULL; 827103871Smjacob free(mpt->request_pool, M_DEVBUF); 828223985Smarius mpt->request_pool = NULL; 829101704Smjacob} 830101704Smjacob 831101704Smjacob/* Reads modifiable (via PCI transactions) config registers */ 832101704Smjacobstatic void 833147883Sscottlmpt_read_config_regs(struct mpt_softc *mpt) 834101704Smjacob{ 835224493Smarius 836101704Smjacob mpt->pci_cfg.Command = pci_read_config(mpt->dev, PCIR_COMMAND, 2); 837101704Smjacob mpt->pci_cfg.LatencyTimer_LineSize = 838101704Smjacob pci_read_config(mpt->dev, PCIR_CACHELNSZ, 2); 839119690Sjhb mpt->pci_cfg.IO_BAR = pci_read_config(mpt->dev, PCIR_BAR(0), 4); 840119690Sjhb mpt->pci_cfg.Mem0_BAR[0] = pci_read_config(mpt->dev, PCIR_BAR(1), 4); 841119690Sjhb mpt->pci_cfg.Mem0_BAR[1] = pci_read_config(mpt->dev, PCIR_BAR(2), 4); 842119690Sjhb mpt->pci_cfg.Mem1_BAR[0] = pci_read_config(mpt->dev, PCIR_BAR(3), 4); 843119690Sjhb mpt->pci_cfg.Mem1_BAR[1] = pci_read_config(mpt->dev, PCIR_BAR(4), 4); 844101704Smjacob mpt->pci_cfg.ROM_BAR = pci_read_config(mpt->dev, PCIR_BIOS, 4); 845101704Smjacob mpt->pci_cfg.IntLine = pci_read_config(mpt->dev, PCIR_INTLINE, 1); 846101704Smjacob mpt->pci_cfg.PMCSR = pci_read_config(mpt->dev, 0x44, 4); 847101704Smjacob} 848101704Smjacob 849224493Smarius#if 0 850101704Smjacob/* Sets modifiable config registers */ 851224493Smariusstatic void 852147883Sscottlmpt_set_config_regs(struct mpt_softc *mpt) 853101704Smjacob{ 854147883Sscottl uint32_t val; 855101704Smjacob 856101704Smjacob#define MPT_CHECK(reg, offset, size) \ 857101704Smjacob val = pci_read_config(mpt->dev, offset, size); \ 858101704Smjacob if (mpt->pci_cfg.reg != val) { \ 859103914Smjacob mpt_prt(mpt, \ 860101704Smjacob "Restoring " #reg " to 0x%X from 0x%X\n", \ 861101704Smjacob mpt->pci_cfg.reg, val); \ 862101704Smjacob } 863101704Smjacob 864147883Sscottl if (mpt->verbose >= MPT_PRT_DEBUG) { 865101704Smjacob MPT_CHECK(Command, PCIR_COMMAND, 2); 866101704Smjacob MPT_CHECK(LatencyTimer_LineSize, PCIR_CACHELNSZ, 2); 867119690Sjhb MPT_CHECK(IO_BAR, PCIR_BAR(0), 4); 868119690Sjhb MPT_CHECK(Mem0_BAR[0], PCIR_BAR(1), 4); 869119690Sjhb MPT_CHECK(Mem0_BAR[1], PCIR_BAR(2), 4); 870119690Sjhb MPT_CHECK(Mem1_BAR[0], PCIR_BAR(3), 4); 871119690Sjhb MPT_CHECK(Mem1_BAR[1], PCIR_BAR(4), 4); 872101704Smjacob MPT_CHECK(ROM_BAR, PCIR_BIOS, 4); 873101704Smjacob MPT_CHECK(IntLine, PCIR_INTLINE, 1); 874101704Smjacob MPT_CHECK(PMCSR, 0x44, 4); 875101704Smjacob } 876101704Smjacob#undef MPT_CHECK 877101704Smjacob 878101704Smjacob pci_write_config(mpt->dev, PCIR_COMMAND, mpt->pci_cfg.Command, 2); 879101704Smjacob pci_write_config(mpt->dev, PCIR_CACHELNSZ, 880101704Smjacob mpt->pci_cfg.LatencyTimer_LineSize, 2); 881119690Sjhb pci_write_config(mpt->dev, PCIR_BAR(0), mpt->pci_cfg.IO_BAR, 4); 882119690Sjhb pci_write_config(mpt->dev, PCIR_BAR(1), mpt->pci_cfg.Mem0_BAR[0], 4); 883119690Sjhb pci_write_config(mpt->dev, PCIR_BAR(2), mpt->pci_cfg.Mem0_BAR[1], 4); 884119690Sjhb pci_write_config(mpt->dev, PCIR_BAR(3), mpt->pci_cfg.Mem1_BAR[0], 4); 885119690Sjhb pci_write_config(mpt->dev, PCIR_BAR(4), mpt->pci_cfg.Mem1_BAR[1], 4); 886101704Smjacob pci_write_config(mpt->dev, PCIR_BIOS, mpt->pci_cfg.ROM_BAR, 4); 887101704Smjacob pci_write_config(mpt->dev, PCIR_INTLINE, mpt->pci_cfg.IntLine, 1); 888101704Smjacob pci_write_config(mpt->dev, 0x44, mpt->pci_cfg.PMCSR, 4); 889101704Smjacob} 890224493Smarius#endif 891102199Smjacob 892102199Smjacobstatic void 893102199Smjacobmpt_pci_intr(void *arg) 894102199Smjacob{ 895147883Sscottl struct mpt_softc *mpt; 896147883Sscottl 897147883Sscottl mpt = (struct mpt_softc *)arg; 898102199Smjacob MPT_LOCK(mpt); 899147883Sscottl mpt_intr(mpt); 900102199Smjacob MPT_UNLOCK(mpt); 901102199Smjacob} 902