bt_pci.c revision 40749
1/* 2 * Product specific probe and attach routines for: 3 * Buslogic BT946, BT948, BT956, BT958 SCSI controllers 4 * 5 * Copyright (c) 1995, 1997, 1998 Justin T. Gibbs 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions, and the following disclaimer, 13 * without modification, immediately at the beginning of the file. 14 * 2. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $Id: bt_pci.c,v 1.1 1998/09/15 07:32:57 gibbs Exp $ 30 */ 31 32#include "pci.h" 33#if NPCI > 0 34#include <sys/param.h> 35#include <sys/systm.h> 36#include <sys/kernel.h> 37 38#include <pci/pcireg.h> 39#include <pci/pcivar.h> 40 41#include <machine/bus_memio.h> 42#include <machine/bus_pio.h> 43#include <machine/bus.h> 44 45#include <dev/buslogic/btreg.h> 46 47#define BT_PCI_IOADDR PCIR_MAPS 48#define BT_PCI_MEMADDR PCIR_MAPS + 4 49 50#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER 0x1040104Bul 51#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140104Bul 52#define PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT 0x8130104Bul 53 54static int btpcideterminebusspace(pcici_t config_id, bus_space_tag_t* tagp, 55 bus_space_handle_t* bshp); 56static char* bt_pci_probe(pcici_t tag, pcidi_t type); 57static void bt_pci_attach(pcici_t config_id, int unit); 58 59static struct pci_device bt_pci_driver = { 60 "bt", 61 bt_pci_probe, 62 bt_pci_attach, 63 &bt_unit, 64 NULL 65}; 66 67DATA_SET (pcidevice_set, bt_pci_driver); 68 69static int 70btpcideterminebusspace(pcici_t config_id, bus_space_tag_t* tagp, 71 bus_space_handle_t* bshp) 72{ 73 vm_offset_t vaddr; 74 vm_offset_t paddr; 75 u_int16_t io_port; 76 int command; 77 78 vaddr = 0; 79 paddr = 0; 80 command = pci_cfgread(config_id, PCIR_COMMAND, /*bytes*/1); 81 /* XXX Memory Mapped I/O seems to cause problems */ 82#if 0 83 if ((command & PCIM_CMD_MEMEN) == 0 84 || (pci_map_mem(config_id, BT_PCI_MEMADDR, &vaddr, &paddr)) == 0) 85#endif 86 if ((command & PCIM_CMD_PORTEN) == 0 87 || (pci_map_port(config_id, BT_PCI_IOADDR, &io_port)) == 0) 88 return (-1); 89 90 if (vaddr != 0) { 91 *tagp = I386_BUS_SPACE_MEM; 92 *bshp = vaddr; 93 } else { 94 *tagp = I386_BUS_SPACE_IO; 95 *bshp = io_port; 96 } 97 98 return (0); 99} 100 101static char* 102bt_pci_probe (pcici_t config_id, pcidi_t type) 103{ 104 switch(type) { 105 case PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER: 106 case PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC: 107 { 108 struct bt_softc *bt; 109 bus_space_tag_t tag; 110 bus_space_handle_t bsh; 111 pci_info_data_t pci_info; 112 int error; 113 114 if (btpcideterminebusspace(config_id, &tag, &bsh) != 0) 115 break; 116 117 bt = bt_alloc(BT_TEMP_UNIT, tag, bsh); 118 if (bt == NULL) 119 break; 120 121 /* 122 * Determine if an ISA compatible I/O port has been 123 * enabled. If so, record the port so it will not 124 * be probed by our ISA probe. If the PCI I/O port 125 * was not set to the compatibility port, disable it. 126 */ 127 error = bt_cmd(bt, BOP_INQUIRE_PCI_INFO, 128 /*param*/NULL, /*paramlen*/0, 129 (u_int8_t*)&pci_info, sizeof(pci_info), 130 DEFAULT_CMD_TIMEOUT); 131 if (error == 0 132 && pci_info.io_port < BIO_DISABLED) { 133 bt_mark_probed_bio(pci_info.io_port); 134 if (bsh != bt_fetch_isa_iop(pci_info.io_port)) { 135 u_int8_t new_addr; 136 137 new_addr = BIO_DISABLED; 138 bt_cmd(bt, BOP_MODIFY_IO_ADDR, 139 /*param*/&new_addr, 140 /*paramlen*/1, /*reply_buf*/NULL, 141 /*reply_len*/0, 142 DEFAULT_CMD_TIMEOUT); 143 } 144 } 145 bt_free(bt); 146 return ("Buslogic Multimaster SCSI host adapter"); 147 break; 148 } 149 default: 150 break; 151 } 152 153 return (NULL); 154} 155 156static void 157bt_pci_attach(pcici_t config_id, int unit) 158{ 159 struct bt_softc *bt; 160 bus_space_tag_t tag; 161 bus_space_handle_t bsh; 162 int opri; 163 164 if (btpcideterminebusspace(config_id, &tag, &bsh) != 0) 165 return; 166 167 if ((bt = bt_alloc(unit, tag, bsh)) == NULL) 168 return; /* XXX PCI code should take return status */ 169 170 /* Allocate a dmatag for our CCB DMA maps */ 171 /* XXX Should be a child of the PCI bus dma tag */ 172 if (bus_dma_tag_create(/*parent*/NULL, /*alignemnt*/0, /*boundary*/0, 173 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 174 /*highaddr*/BUS_SPACE_MAXADDR, 175 /*filter*/NULL, /*filterarg*/NULL, 176 /*maxsize*/BUS_SPACE_MAXSIZE_32BIT, 177 /*nsegments*/BUS_SPACE_UNRESTRICTED, 178 /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, 179 /*flags*/0, &bt->parent_dmat) != 0) { 180 bt_free(bt); 181 return; 182 } 183 184 if ((pci_map_int(config_id, bt_intr, (void *)bt, &cam_imask)) == 0) { 185 bt_free(bt); 186 return; 187 } 188 /* 189 * Protect ourself from spurrious interrupts during 190 * intialization and attach. We should really rely 191 * on interrupts during attach, but we don't have 192 * access to our interrupts during ISA probes, so until 193 * that changes, we mask our interrupts during attach 194 * too. 195 */ 196 opri = splcam(); 197 198 if (bt_probe(bt) || bt_fetch_adapter_info(bt) || bt_init(bt)) { 199 bt_free(bt); 200 splx(opri); 201 return; /* XXX PCI code should take return status */ 202 } 203 204 bt_attach(bt); 205 206 splx(opri); 207 return; 208} 209 210#endif /* NPCI > 0 */ 211