Deleted Added
sdiff udiff text old ( 57679 ) new ( 59082 )
full compact
1/*
2 * Device probe and attach routines for the following
3 * Advanced Systems Inc. SCSI controllers:
4 *
5 * Connectivity Products:
6 * ABP902/3902 - Bus-Master PCI (16 CDB)
7 * ABP3905 - Bus-Master PCI (16 CDB)
8 * ABP915 - Bus-Master PCI (16 CDB)

--- 43 unchanged lines hidden (view full) ---

52 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 *
60 * $FreeBSD: head/sys/dev/advansys/adv_pci.c 57679 2000-03-02 00:08:35Z gibbs $
61 */
62
63#include <sys/param.h>
64#include <sys/systm.h>
65#include <sys/kernel.h>
66
67#include <machine/bus_pio.h>
68#include <machine/bus.h>
69
70#include <pci/pcireg.h>
71#include <pci/pcivar.h>
72
73#include <dev/advansys/advansys.h>
74
75#define PCI_BASEADR0 PCI_MAP_REG_START /* I/O Address */
76#define PCI_BASEADR1 PCI_MAP_REG_START + 4 /* Mem I/O Address */
77
78#define PCI_DEVICE_ID_ADVANSYS_1200A 0x110010CD
79#define PCI_DEVICE_ID_ADVANSYS_1200B 0x120010CD
80#define PCI_DEVICE_ID_ADVANSYS_3000 0x130010CD
81#define PCI_DEVICE_REV_ADVANSYS_3150 0x02
82#define PCI_DEVICE_REV_ADVANSYS_3050 0x03
83
84#define ADV_PCI_MAX_DMA_ADDR (0xFFFFFFFFL)
85#define ADV_PCI_MAX_DMA_COUNT (0xFFFFFFFFL)
86
87static const char* advpciprobe(pcici_t tag, pcidi_t type);
88static void advpciattach(pcici_t config_id, int unit);
89
90/*
91 * The overrun buffer shared amongst all PCI adapters.
92 */
93static u_int8_t* overrun_buf;
94static bus_dma_tag_t overrun_dmat;
95static bus_dmamap_t overrun_dmamap;
96static bus_addr_t overrun_physbase;
97
98static struct pci_device adv_pci_driver = {
99 "adv",
100 advpciprobe,
101 advpciattach,
102 &adv_unit,
103 NULL
104};
105
106COMPAT_PCI_DRIVER (adv_pci, adv_pci_driver);
107
108static const char*
109advpciprobe(pcici_t tag, pcidi_t type)
110{
111 int rev;
112
113 rev = pci_conf_read(tag, PCI_CLASS_REG) & PCI_REVISION_MASK;
114 switch (type) {
115 case PCI_DEVICE_ID_ADVANSYS_1200A:
116 return ("AdvanSys ASC1200A SCSI controller");
117 case PCI_DEVICE_ID_ADVANSYS_1200B:
118 return ("AdvanSys ASC1200B SCSI controller");
119 case PCI_DEVICE_ID_ADVANSYS_3000:
120 if (rev == PCI_DEVICE_REV_ADVANSYS_3150)
121 return ("AdvanSys ASC3150 SCSI controller");
122 else if (rev == PCI_DEVICE_REV_ADVANSYS_3050)
123 return ("AdvanSys ASC3030/50 SCSI controller");
124 else if (rev >= PCI_DEVICE_REV_ADVANSYS_3150)
125 return ("Unknown AdvanSys controller");
126 break;
127 default:
128 break;
129 }
130 return (NULL);
131}
132
133static void
134advpciattach(pcici_t config_id, int unit)
135{
136 u_int16_t io_port;
137 struct adv_softc *adv;
138 u_int32_t id;
139 u_int32_t command;
140 int error;
141
142 /*
143 * Determine the chip version.
144 */
145 id = pci_cfgread(config_id, PCI_ID_REG, /*bytes*/4);
146 command = pci_cfgread(config_id, PCIR_COMMAND, /*bytes*/1);
147
148 /*
149 * These cards do not allow memory mapped accesses, so we must
150 * ensure that I/O accesses are available or we won't be able
151 * to talk to them.
152 */
153 if ((command & (PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN))
154 != (PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN)) {
155 command |= PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN;
156 pci_cfgwrite(config_id, PCIR_COMMAND, command, /*bytes*/1);
157 }
158
159 /*
160 * Early chips can't handle non-zero latency timer settings.
161 */
162 if (id == PCI_DEVICE_ID_ADVANSYS_1200A
163 || id == PCI_DEVICE_ID_ADVANSYS_1200B) {
164 pci_cfgwrite(config_id, PCIR_LATTIMER, /*value*/0, /*bytes*/1);
165 }
166
167
168 if (pci_map_port(config_id, PCI_BASEADR0, &io_port) == 0)
169 return;
170
171 if (adv_find_signature(I386_BUS_SPACE_IO, io_port) == 0)
172 return;
173
174 adv = adv_alloc(unit, I386_BUS_SPACE_IO, io_port);
175 if (adv == NULL)
176 return;
177
178 /* Allocate a dmatag for our transfer DMA maps */
179 /* XXX Should be a child of the PCI bus dma tag */
180 error = bus_dma_tag_create(/*parent*/NULL, /*alignment*/1,
181 /*boundary*/0,
182 /*lowaddr*/ADV_PCI_MAX_DMA_ADDR,
183 /*highaddr*/BUS_SPACE_MAXADDR,
184 /*filter*/NULL, /*filterarg*/NULL,
185 /*maxsize*/BUS_SPACE_MAXSIZE_32BIT,
186 /*nsegments*/BUS_SPACE_UNRESTRICTED,
187 /*maxsegsz*/ADV_PCI_MAX_DMA_COUNT,
188 /*flags*/0,
189 &adv->parent_dmat);
190
191 if (error != 0) {
192 printf("%s: Could not allocate DMA tag - error %d\n",
193 adv_name(adv), error);
194 adv_free(adv);
195 return;
196 }
197
198 adv->init_level++;
199
200 if (overrun_buf == NULL) {
201 /* Need to allocate our overrun buffer */
202 if (bus_dma_tag_create(adv->parent_dmat,
203 /*alignment*/8, /*boundary*/0,
204 ADV_PCI_MAX_DMA_ADDR, BUS_SPACE_MAXADDR,
205 /*filter*/NULL, /*filterarg*/NULL,
206 ADV_OVERRUN_BSIZE, /*nsegments*/1,
207 BUS_SPACE_MAXSIZE_32BIT, /*flags*/0,
208 &overrun_dmat) != 0) {
209 bus_dma_tag_destroy(adv->parent_dmat);
210 adv_free(adv);
211 return;
212 }
213 if (bus_dmamem_alloc(overrun_dmat,
214 (void **)&overrun_buf,
215 BUS_DMA_NOWAIT,
216 &overrun_dmamap) != 0) {
217 bus_dma_tag_destroy(overrun_dmat);
218 bus_dma_tag_destroy(adv->parent_dmat);
219 adv_free(adv);
220 return;
221 }
222 /* And permanently map it in */
223 bus_dmamap_load(overrun_dmat, overrun_dmamap,
224 overrun_buf, ADV_OVERRUN_BSIZE,
225 adv_map, &overrun_physbase,
226 /*flags*/0);
227 }
228

--- 20 unchanged lines hidden (view full) ---

249 extra_cfg = ADV_IFC_ACT_NEG | ADV_IFC_WR_EN_FILTER;
250 else
251 extra_cfg = ADV_IFC_ACT_NEG | ADV_IFC_SLEW_RATE;
252 ADV_OUTB(adv, ADV_REG_IFC, extra_cfg);
253 }
254
255 if (adv_init(adv) != 0) {
256 adv_free(adv);
257 return;
258 }
259
260 adv->max_dma_count = ADV_PCI_MAX_DMA_COUNT;
261 adv->max_dma_addr = ADV_PCI_MAX_DMA_ADDR;
262
263#if CC_DISABLE_PCI_PARITY_INT
264 {
265 u_int16_t config_msw;

--- 6 unchanged lines hidden (view full) ---

272
273 if (id == PCI_DEVICE_ID_ADVANSYS_1200A
274 || id == PCI_DEVICE_ID_ADVANSYS_1200B) {
275 adv->bug_fix_control |= ADV_BUG_FIX_IF_NOT_DWB;
276 adv->bug_fix_control |= ADV_BUG_FIX_ASYN_USE_SYN;
277 adv->fix_asyn_xfer = ~0;
278 }
279
280 if ((pci_map_int(config_id, adv_intr, (void *)adv, &cam_imask)) == 0) {
281 adv_free(adv);
282 return;
283 }
284
285 adv_attach(adv);
286}