1/*
2 * Device probe and attach routines for the following
3 * Advanced Systems Inc. SCSI controllers:
4 *
5 * Connectivity Products:
6 * ABP920 - Bus-Master PCI (16 CDB)
7 * ABP930 - Bus-Master PCI (16 CDB) *
8 * ABP930U - Bus-Master PCI Ultra (16 CDB)
9 * ABP930UA - Bus-Master PCI Ultra (16 CDB)
10 * ABP960 - Bus-Master PCI MAC/PC (16 CDB) **
11 * ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB)
12 *
13 * Single Channel Products:
14 * ABP940 - Bus-Master PCI (240 CDB)
15 * ABP940U - Bus-Master PCI Ultra (240 CDB)
16 * ABP970 - Bus-Master PCI MAC/PC (240 CDB)
17 * ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
18 *
19 * Dual Channel Products:
20 * ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
21 *
22 * Footnotes:
23 * * This board has been sold by SIIG as the Fast SCSI Pro PCI.
24 * ** This board has been sold by Iomega as a Jaz Jet PCI adapter.
25 *
26 * Copyright (c) 1997 Justin Gibbs.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions, and the following disclaimer,
34 * without modification, immediately at the beginning of the file.
35 * 2. The name of the author may not be used to endorse or promote products
36 * derived from this software without specific prior written permission.
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
39 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
42 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
44 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
46 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
47 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * SUCH DAMAGE.
49 *
50 * $Id: adv_pci.c,v 1.2 1998/12/07 21:58:45 archie Exp $
51 */
52
53#include <pci.h>
54#if NPCI > 0
55#include <sys/param.h>
56#include <sys/systm.h>
57#include <sys/kernel.h>
58
59#include <machine/bus_pio.h>
60#include <machine/bus.h>
61
62#include <pci/pcireg.h>
63#include <pci/pcivar.h>
64
65#include <dev/advansys/advansys.h>
66
67#define PCI_BASEADR0 PCI_MAP_REG_START /* I/O Address */
68#define PCI_BASEADR1 PCI_MAP_REG_START + 4 /* Mem I/O Address */
69
70#define PCI_DEVICE_ID_ADVANSYS_1200A 0x110010CD
71#define PCI_DEVICE_ID_ADVANSYS_1200B 0x120010CD
72#define PCI_DEVICE_ID_ADVANSYS_ULTRA 0x130010CD
73#define PCI_DEVICE_REV_ADVANSYS_3150 0x02
74#define PCI_DEVICE_REV_ADVANSYS_3050 0x03
75
76#define ADV_PCI_MAX_DMA_ADDR (0xFFFFFFFFL)
77#define ADV_PCI_MAX_DMA_COUNT (0xFFFFFFFFL)
78
79static const char* advpciprobe(pcici_t tag, pcidi_t type);
80static void advpciattach(pcici_t config_id, int unit);
81
82/*
83 * The overrun buffer shared amongst all PCI adapters.
84 */
85static u_int8_t* overrun_buf;
86bus_dma_tag_t overrun_dmat;
87bus_dmamap_t overrun_dmamap;
88bus_addr_t overrun_physbase;
89
90static struct pci_device adv_pci_driver = {
91 "adv",
92 advpciprobe,
93 advpciattach,
94 &adv_unit,
95 NULL
96};
97
98DATA_SET (pcidevice_set, adv_pci_driver);
99
100static const char*
101advpciprobe(pcici_t tag, pcidi_t type)
102{
103 int rev = pci_conf_read(tag, PCI_CLASS_REG) & 0xff;
104 switch (type) {
105 case PCI_DEVICE_ID_ADVANSYS_1200A:
106 return ("AdvanSys ASC1200A SCSI controller");
107 case PCI_DEVICE_ID_ADVANSYS_1200B:
108 return ("AdvanSys ASC1200B SCSI controller");
109 case PCI_DEVICE_ID_ADVANSYS_ULTRA:
110 if (rev == PCI_DEVICE_REV_ADVANSYS_3150)
111 return ("AdvanSys ASC3150 Ultra SCSI controller");
112 else
113 return ("AdvanSys ASC3050 Ultra SCSI controller");
114 break;
115 default:
116 break;
117 }
118 return (NULL);
119}
120
121static void
122advpciattach(pcici_t config_id, int unit)
123{
124 u_int16_t io_port;
125 struct adv_softc *adv;
126 u_int32_t id;
127 u_int32_t command;
128 int error;
129
130 /*
131 * Determine the chip version.
132 */
133 id = pci_cfgread(config_id, PCI_ID_REG, /*bytes*/4);
134 command = pci_cfgread(config_id, PCIR_COMMAND, /*bytes*/1);
135
136 /*
137 * These cards do not allow memory mapped accesses, so we must
138 * ensure that I/O accesses are available or we won't be able
139 * to talk to them.
140 */
141 if ((command & (PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN))
142 != (PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN)) {
143 command |= PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN;
144 pci_cfgwrite(config_id, PCIR_COMMAND, command, /*bytes*/1);
145 }
146
147 /*
148 * Early chips can't handle non-zero latency timer settings.
149 */
150 if (id == PCI_DEVICE_ID_ADVANSYS_1200A
151 || id == PCI_DEVICE_ID_ADVANSYS_1200B) {
152 pci_cfgwrite(config_id, PCIR_LATTIMER, /*value*/0, /*bytes*/1);
153 }
154
155
156 if (pci_map_port(config_id, PCI_BASEADR0, &io_port) == 0)
157 return;
158
159 if (adv_find_signature(I386_BUS_SPACE_IO, io_port) == 0)
160 return;
161
162 adv = adv_alloc(unit, I386_BUS_SPACE_IO, io_port);
163 if (adv == NULL)
164 return;
165
166 /* Allocate a dmatag for our transfer DMA maps */
167 /* XXX Should be a child of the PCI bus dma tag */
168 error = bus_dma_tag_create(/*parent*/NULL, /*alignment*/0,
169 /*boundary*/0,
170 /*lowaddr*/ADV_PCI_MAX_DMA_ADDR,
171 /*highaddr*/BUS_SPACE_MAXADDR,
172 /*filter*/NULL, /*filterarg*/NULL,
173 /*maxsize*/BUS_SPACE_MAXSIZE_32BIT,
174 /*nsegments*/BUS_SPACE_UNRESTRICTED,
175 /*maxsegsz*/ADV_PCI_MAX_DMA_COUNT,
176 /*flags*/0,
177 &adv->parent_dmat);
178
179 if (error != 0) {
180 printf("%s: Could not allocate DMA tag - error %d\n",
181 adv_name(adv), error);
182 adv_free(adv);
183 return;
184 }
185
186 adv->init_level++;
187
188 if (overrun_buf == NULL) {
189 /* Need to allocate our overrun buffer */
190 if (bus_dma_tag_create(adv->parent_dmat,
191 /*alignment*/8, /*boundary*/0,
192 ADV_PCI_MAX_DMA_ADDR, BUS_SPACE_MAXADDR,
193 /*filter*/NULL, /*filterarg*/NULL,
194 ADV_OVERRUN_BSIZE, /*nsegments*/1,
195 BUS_SPACE_MAXSIZE_32BIT, /*flags*/0,
196 &overrun_dmat) != 0) {
197 bus_dma_tag_destroy(adv->parent_dmat);
198 adv_free(adv);
199 return;
200 }
201 if (bus_dmamem_alloc(overrun_dmat,
202 (void **)&overrun_buf,
203 BUS_DMA_NOWAIT,
204 &overrun_dmamap) != 0) {
205 bus_dma_tag_destroy(overrun_dmat);
206 bus_dma_tag_destroy(adv->parent_dmat);
207 adv_free(adv);
208 return;
209 }
210 /* And permanently map it in */
211 bus_dmamap_load(overrun_dmat, overrun_dmamap,
212 overrun_buf, ADV_OVERRUN_BSIZE,
213 adv_map, &overrun_physbase,
214 /*flags*/0);
215 }
216
217 adv->overrun_physbase = overrun_physbase;
218
219 /*
220 * Stop the chip.
221 */
222 ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_HALT);
223 ADV_OUTW(adv, ADV_CHIP_STATUS, 0);
224
225 adv->chip_version = ADV_INB(adv, ADV_NONEISA_CHIP_REVISION);
226 adv->type = ADV_PCI;
227
228 /*
229 * Setup active negation and signal filtering.
230 */
231 {
232 u_int8_t extra_cfg;
233
234 if (adv->chip_version >= ADV_CHIP_VER_PCI_ULTRA_3150)
235 adv->type |= ADV_ULTRA;
236 if (adv->chip_version == ADV_CHIP_VER_PCI_ULTRA_3150)
237 extra_cfg = ADV_IFC_ACT_NEG | ADV_IFC_SLEW_RATE;
238 else if (adv->chip_version == ADV_CHIP_VER_PCI_ULTRA_3050)
239 extra_cfg = ADV_IFC_ACT_NEG | ADV_IFC_WR_EN_FILTER;
240 else
241 extra_cfg = ADV_IFC_ACT_NEG | ADV_IFC_SLEW_RATE;
242 ADV_OUTB(adv, ADV_REG_IFC, extra_cfg);
243 }
244
245 if (adv_init(adv) != 0) {
246 adv_free(adv);
247 return;
248 }
249
250 adv->max_dma_count = ADV_PCI_MAX_DMA_COUNT;
251 adv->max_dma_addr = ADV_PCI_MAX_DMA_ADDR;
252
253#if CC_DISABLE_PCI_PARITY_INT
254 {
255 u_int16_t config_msw;
256
257 config_msw = ADV_INW(adv, ADV_CONFIG_MSW);
258 config_msw &= 0xFFC0;
259 ADV_OUTW(adv, ADV_CONFIG_MSW, config_msw);
260 }
261#endif
262
263 if (id == PCI_DEVICE_ID_ADVANSYS_1200A
264 || id == PCI_DEVICE_ID_ADVANSYS_1200B) {
265 adv->bug_fix_control |= ADV_BUG_FIX_IF_NOT_DWB;
266 adv->bug_fix_control |= ADV_BUG_FIX_ASYN_USE_SYN;
267 adv->fix_asyn_xfer = ~0;
268 }
269
270 if ((pci_map_int(config_id, adv_intr, (void *)adv, &cam_imask)) == 0) {
271 adv_free(adv);
272 return;
273 }
274
275 adv_attach(adv);
276}
277
278#endif /* NPCI > 0 */
2 * Device probe and attach routines for the following
3 * Advanced Systems Inc. SCSI controllers:
4 *
5 * Connectivity Products:
6 * ABP920 - Bus-Master PCI (16 CDB)
7 * ABP930 - Bus-Master PCI (16 CDB) *
8 * ABP930U - Bus-Master PCI Ultra (16 CDB)
9 * ABP930UA - Bus-Master PCI Ultra (16 CDB)
10 * ABP960 - Bus-Master PCI MAC/PC (16 CDB) **
11 * ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB)
12 *
13 * Single Channel Products:
14 * ABP940 - Bus-Master PCI (240 CDB)
15 * ABP940U - Bus-Master PCI Ultra (240 CDB)
16 * ABP970 - Bus-Master PCI MAC/PC (240 CDB)
17 * ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
18 *
19 * Dual Channel Products:
20 * ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
21 *
22 * Footnotes:
23 * * This board has been sold by SIIG as the Fast SCSI Pro PCI.
24 * ** This board has been sold by Iomega as a Jaz Jet PCI adapter.
25 *
26 * Copyright (c) 1997 Justin Gibbs.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions, and the following disclaimer,
34 * without modification, immediately at the beginning of the file.
35 * 2. The name of the author may not be used to endorse or promote products
36 * derived from this software without specific prior written permission.
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
39 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
42 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
44 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
46 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
47 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * SUCH DAMAGE.
49 *
50 * $Id: adv_pci.c,v 1.2 1998/12/07 21:58:45 archie Exp $
51 */
52
53#include <pci.h>
54#if NPCI > 0
55#include <sys/param.h>
56#include <sys/systm.h>
57#include <sys/kernel.h>
58
59#include <machine/bus_pio.h>
60#include <machine/bus.h>
61
62#include <pci/pcireg.h>
63#include <pci/pcivar.h>
64
65#include <dev/advansys/advansys.h>
66
67#define PCI_BASEADR0 PCI_MAP_REG_START /* I/O Address */
68#define PCI_BASEADR1 PCI_MAP_REG_START + 4 /* Mem I/O Address */
69
70#define PCI_DEVICE_ID_ADVANSYS_1200A 0x110010CD
71#define PCI_DEVICE_ID_ADVANSYS_1200B 0x120010CD
72#define PCI_DEVICE_ID_ADVANSYS_ULTRA 0x130010CD
73#define PCI_DEVICE_REV_ADVANSYS_3150 0x02
74#define PCI_DEVICE_REV_ADVANSYS_3050 0x03
75
76#define ADV_PCI_MAX_DMA_ADDR (0xFFFFFFFFL)
77#define ADV_PCI_MAX_DMA_COUNT (0xFFFFFFFFL)
78
79static const char* advpciprobe(pcici_t tag, pcidi_t type);
80static void advpciattach(pcici_t config_id, int unit);
81
82/*
83 * The overrun buffer shared amongst all PCI adapters.
84 */
85static u_int8_t* overrun_buf;
86bus_dma_tag_t overrun_dmat;
87bus_dmamap_t overrun_dmamap;
88bus_addr_t overrun_physbase;
89
90static struct pci_device adv_pci_driver = {
91 "adv",
92 advpciprobe,
93 advpciattach,
94 &adv_unit,
95 NULL
96};
97
98DATA_SET (pcidevice_set, adv_pci_driver);
99
100static const char*
101advpciprobe(pcici_t tag, pcidi_t type)
102{
103 int rev = pci_conf_read(tag, PCI_CLASS_REG) & 0xff;
104 switch (type) {
105 case PCI_DEVICE_ID_ADVANSYS_1200A:
106 return ("AdvanSys ASC1200A SCSI controller");
107 case PCI_DEVICE_ID_ADVANSYS_1200B:
108 return ("AdvanSys ASC1200B SCSI controller");
109 case PCI_DEVICE_ID_ADVANSYS_ULTRA:
110 if (rev == PCI_DEVICE_REV_ADVANSYS_3150)
111 return ("AdvanSys ASC3150 Ultra SCSI controller");
112 else
113 return ("AdvanSys ASC3050 Ultra SCSI controller");
114 break;
115 default:
116 break;
117 }
118 return (NULL);
119}
120
121static void
122advpciattach(pcici_t config_id, int unit)
123{
124 u_int16_t io_port;
125 struct adv_softc *adv;
126 u_int32_t id;
127 u_int32_t command;
128 int error;
129
130 /*
131 * Determine the chip version.
132 */
133 id = pci_cfgread(config_id, PCI_ID_REG, /*bytes*/4);
134 command = pci_cfgread(config_id, PCIR_COMMAND, /*bytes*/1);
135
136 /*
137 * These cards do not allow memory mapped accesses, so we must
138 * ensure that I/O accesses are available or we won't be able
139 * to talk to them.
140 */
141 if ((command & (PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN))
142 != (PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN)) {
143 command |= PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN;
144 pci_cfgwrite(config_id, PCIR_COMMAND, command, /*bytes*/1);
145 }
146
147 /*
148 * Early chips can't handle non-zero latency timer settings.
149 */
150 if (id == PCI_DEVICE_ID_ADVANSYS_1200A
151 || id == PCI_DEVICE_ID_ADVANSYS_1200B) {
152 pci_cfgwrite(config_id, PCIR_LATTIMER, /*value*/0, /*bytes*/1);
153 }
154
155
156 if (pci_map_port(config_id, PCI_BASEADR0, &io_port) == 0)
157 return;
158
159 if (adv_find_signature(I386_BUS_SPACE_IO, io_port) == 0)
160 return;
161
162 adv = adv_alloc(unit, I386_BUS_SPACE_IO, io_port);
163 if (adv == NULL)
164 return;
165
166 /* Allocate a dmatag for our transfer DMA maps */
167 /* XXX Should be a child of the PCI bus dma tag */
168 error = bus_dma_tag_create(/*parent*/NULL, /*alignment*/0,
169 /*boundary*/0,
170 /*lowaddr*/ADV_PCI_MAX_DMA_ADDR,
171 /*highaddr*/BUS_SPACE_MAXADDR,
172 /*filter*/NULL, /*filterarg*/NULL,
173 /*maxsize*/BUS_SPACE_MAXSIZE_32BIT,
174 /*nsegments*/BUS_SPACE_UNRESTRICTED,
175 /*maxsegsz*/ADV_PCI_MAX_DMA_COUNT,
176 /*flags*/0,
177 &adv->parent_dmat);
178
179 if (error != 0) {
180 printf("%s: Could not allocate DMA tag - error %d\n",
181 adv_name(adv), error);
182 adv_free(adv);
183 return;
184 }
185
186 adv->init_level++;
187
188 if (overrun_buf == NULL) {
189 /* Need to allocate our overrun buffer */
190 if (bus_dma_tag_create(adv->parent_dmat,
191 /*alignment*/8, /*boundary*/0,
192 ADV_PCI_MAX_DMA_ADDR, BUS_SPACE_MAXADDR,
193 /*filter*/NULL, /*filterarg*/NULL,
194 ADV_OVERRUN_BSIZE, /*nsegments*/1,
195 BUS_SPACE_MAXSIZE_32BIT, /*flags*/0,
196 &overrun_dmat) != 0) {
197 bus_dma_tag_destroy(adv->parent_dmat);
198 adv_free(adv);
199 return;
200 }
201 if (bus_dmamem_alloc(overrun_dmat,
202 (void **)&overrun_buf,
203 BUS_DMA_NOWAIT,
204 &overrun_dmamap) != 0) {
205 bus_dma_tag_destroy(overrun_dmat);
206 bus_dma_tag_destroy(adv->parent_dmat);
207 adv_free(adv);
208 return;
209 }
210 /* And permanently map it in */
211 bus_dmamap_load(overrun_dmat, overrun_dmamap,
212 overrun_buf, ADV_OVERRUN_BSIZE,
213 adv_map, &overrun_physbase,
214 /*flags*/0);
215 }
216
217 adv->overrun_physbase = overrun_physbase;
218
219 /*
220 * Stop the chip.
221 */
222 ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_HALT);
223 ADV_OUTW(adv, ADV_CHIP_STATUS, 0);
224
225 adv->chip_version = ADV_INB(adv, ADV_NONEISA_CHIP_REVISION);
226 adv->type = ADV_PCI;
227
228 /*
229 * Setup active negation and signal filtering.
230 */
231 {
232 u_int8_t extra_cfg;
233
234 if (adv->chip_version >= ADV_CHIP_VER_PCI_ULTRA_3150)
235 adv->type |= ADV_ULTRA;
236 if (adv->chip_version == ADV_CHIP_VER_PCI_ULTRA_3150)
237 extra_cfg = ADV_IFC_ACT_NEG | ADV_IFC_SLEW_RATE;
238 else if (adv->chip_version == ADV_CHIP_VER_PCI_ULTRA_3050)
239 extra_cfg = ADV_IFC_ACT_NEG | ADV_IFC_WR_EN_FILTER;
240 else
241 extra_cfg = ADV_IFC_ACT_NEG | ADV_IFC_SLEW_RATE;
242 ADV_OUTB(adv, ADV_REG_IFC, extra_cfg);
243 }
244
245 if (adv_init(adv) != 0) {
246 adv_free(adv);
247 return;
248 }
249
250 adv->max_dma_count = ADV_PCI_MAX_DMA_COUNT;
251 adv->max_dma_addr = ADV_PCI_MAX_DMA_ADDR;
252
253#if CC_DISABLE_PCI_PARITY_INT
254 {
255 u_int16_t config_msw;
256
257 config_msw = ADV_INW(adv, ADV_CONFIG_MSW);
258 config_msw &= 0xFFC0;
259 ADV_OUTW(adv, ADV_CONFIG_MSW, config_msw);
260 }
261#endif
262
263 if (id == PCI_DEVICE_ID_ADVANSYS_1200A
264 || id == PCI_DEVICE_ID_ADVANSYS_1200B) {
265 adv->bug_fix_control |= ADV_BUG_FIX_IF_NOT_DWB;
266 adv->bug_fix_control |= ADV_BUG_FIX_ASYN_USE_SYN;
267 adv->fix_asyn_xfer = ~0;
268 }
269
270 if ((pci_map_int(config_id, adv_intr, (void *)adv, &cam_imask)) == 0) {
271 adv_free(adv);
272 return;
273 }
274
275 adv_attach(adv);
276}
277
278#endif /* NPCI > 0 */