2 * Product specific probe and attach routines for:
3 * Buslogic BT946, BT948, BT956, BT958 SCSI controllers
5 * Copyright (c) 1995, 1997, 1998 Justin T. Gibbs
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/kernel.h>
36 #include <sys/module.h>
38 #include <sys/mutex.h>
41 #include <dev/pci/pcireg.h>
42 #include <dev/pci/pcivar.h>
44 #include <machine/bus.h>
45 #include <machine/resource.h>
48 #include <dev/buslogic/btreg.h>
50 #define BT_PCI_IOADDR PCIR_BAR(0)
51 #define BT_PCI_MEMADDR PCIR_BAR(1)
53 #define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER 0x1040104Bul
54 #define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140104Bul
55 #define PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT 0x8130104Bul
58 bt_pci_alloc_resources(device_t dev
)
60 int command
, type
= 0, rid
, zero
;
61 struct resource
*regs
= 0;
62 struct resource
*irq
= 0;
64 command
= pci_read_config(dev
, PCIR_COMMAND
, /*bytes*/1);
66 /* XXX Memory Mapped I/O seems to cause problems */
67 if (command
& PCIM_CMD_MEMEN
) {
68 type
= SYS_RES_MEMORY
;
70 regs
= bus_alloc_resource_any(dev
, type
, &rid
, RF_ACTIVE
);
73 if (!regs
&& (command
& PCIM_CMD_PORTEN
)) {
74 type
= SYS_RES_IOPORT
;
76 regs
= bus_alloc_resource_any(dev
, type
, &rid
, RF_ACTIVE
);
83 irq
= bus_alloc_resource_any(dev
, SYS_RES_IRQ
, &zero
,
84 RF_ACTIVE
| RF_SHAREABLE
);
86 bus_release_resource(dev
, type
, rid
, regs
);
90 bt_init_softc(dev
, regs
, irq
, 0);
96 bt_pci_release_resources(device_t dev
)
98 struct bt_softc
*bt
= device_get_softc(dev
);
101 /* XXX can't cope with memory registers anyway */
102 bus_release_resource(dev
, SYS_RES_IOPORT
,
103 BT_PCI_IOADDR
, bt
->port
);
105 bus_release_resource(dev
, SYS_RES_IRQ
, 0, bt
->irq
);
110 bt_pci_probe(device_t dev
)
112 switch (pci_get_devid(dev
)) {
113 case PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER
:
114 case PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC
:
116 struct bt_softc
*bt
= device_get_softc(dev
);
117 pci_info_data_t pci_info
;
120 error
= bt_pci_alloc_resources(dev
);
125 * Determine if an ISA compatible I/O port has been
126 * enabled. If so, record the port so it will not
127 * be probed by our ISA probe. If the PCI I/O port
128 * was not set to the compatibility port, disable it.
130 error
= bt_cmd(bt
, BOP_INQUIRE_PCI_INFO
,
131 /*param*/NULL
, /*paramlen*/0,
132 (u_int8_t
*)&pci_info
, sizeof(pci_info
),
133 DEFAULT_CMD_TIMEOUT
);
135 && pci_info
.io_port
< BIO_DISABLED
) {
136 bt_mark_probed_bio(pci_info
.io_port
);
137 if (rman_get_start(bt
->port
) !=
138 bt_iop_from_bio(pci_info
.io_port
)) {
141 new_addr
= BIO_DISABLED
;
142 bt_cmd(bt
, BOP_MODIFY_IO_ADDR
,
144 /*paramlen*/1, /*reply_buf*/NULL
,
146 DEFAULT_CMD_TIMEOUT
);
149 bt_pci_release_resources(dev
);
150 device_set_desc(dev
, "Buslogic Multi-Master SCSI Host Adapter");
161 bt_pci_attach(device_t dev
)
163 struct bt_softc
*bt
= device_get_softc(dev
);
167 /* Initialize softc */
168 error
= bt_pci_alloc_resources(dev
);
170 device_printf(dev
, "can't allocate resources in bt_pci_attach\n");
174 /* Allocate a dmatag for our CCB DMA maps */
175 /* XXX Should be a child of the PCI bus dma tag */
176 if (bus_dma_tag_create( /* parent */ NULL
,
179 /* lowaddr */ BUS_SPACE_MAXADDR_32BIT
,
180 /* highaddr */ BUS_SPACE_MAXADDR
,
182 /* filterarg */ NULL
,
183 /* maxsize */ BUS_SPACE_MAXSIZE_32BIT
,
185 /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT
,
187 /* lockfunc */ busdma_lock_mutex
,
188 /* lockarg */ &Giant
,
189 &bt
->parent_dmat
) != 0) {
190 bt_pci_release_resources(dev
);
195 * Protect ourself from spurrious interrupts during
196 * intialization and attach. We should really rely
197 * on interrupts during attach, but we don't have
198 * access to our interrupts during ISA probes, so until
199 * that changes, we mask our interrupts during attach
204 if (bt_probe(dev
) || bt_fetch_adapter_info(dev
) || bt_init(dev
)) {
205 bt_pci_release_resources(dev
);
210 error
= bt_attach(dev
);
214 bt_pci_release_resources(dev
);
221 static device_method_t bt_pci_methods
[] = {
222 /* Device interface */
223 DEVMETHOD(device_probe
, bt_pci_probe
),
224 DEVMETHOD(device_attach
, bt_pci_attach
),
229 static driver_t bt_pci_driver
= {
232 sizeof(struct bt_softc
),
235 static devclass_t bt_devclass
;
237 DRIVER_MODULE(bt
, pci
, bt_pci_driver
, bt_devclass
, 0, 0);
238 MODULE_DEPEND(bt
, pci
, 1, 1, 1);