1 /* $OpenBSD: isp_pci.c,v 1.35 2003/12/06 14:40:33 grange Exp $ */
2 /*
3 * PCI specific probe and attach routines for Qlogic ISP SCSI adapters.
4 *
5 *---------------------------------------
6 * Copyright (c) 1997, 1998, 1999 by Matthew Jacob
7 * NASA/Ames Research Center
8 * All rights reserved.
9 *---------------------------------------
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice immediately at the beginning of the file, without modification,
16 * this list of conditions, and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
27 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 */
36
37 #include <dev/ic/isp_openbsd.h>
38
39 #include <dev/pci/pcireg.h>
40 #include <dev/pci/pcivar.h>
41 #include <dev/pci/pcidevs.h>
42
43 static u_int16_t isp_pci_rd_reg(struct ispsoftc *, int);
44 static void isp_pci_wr_reg(struct ispsoftc *, int, u_int16_t);
45 #if !(defined(ISP_DISABLE_1080_SUPPORT) && defined(ISP_DISABLE_12160_SUPPORT))
46 static u_int16_t isp_pci_rd_reg_1080(struct ispsoftc *, int);
47 static void isp_pci_wr_reg_1080(struct ispsoftc *, int, u_int16_t);
48 #endif
49 static int
50 isp_pci_rd_isr(struct ispsoftc *, u_int16_t *, u_int16_t *, u_int16_t *);
51 #ifndef ISP_DISABLE_2300_SUPPORT
52 static int
53 isp_pci_rd_isr_2300(struct ispsoftc *, u_int16_t *, u_int16_t *, u_int16_t *);
54 #endif
55 static int isp_pci_mbxdma(struct ispsoftc *);
56 static int isp_pci_dmasetup(struct ispsoftc *, struct scsi_xfer *,
57 ispreq_t *, u_int16_t *, u_int16_t);
58 static void
59 isp_pci_dmateardown (struct ispsoftc *, struct scsi_xfer *, u_int16_t);
60 static void isp_pci_reset1 (struct ispsoftc *);
61 static void isp_pci_dumpregs (struct ispsoftc *, const char *);
62 static int isp_pci_intr (void *);
63
64 #ifdef ISP_COMPILE_FW
65 #define ISP_COMPILE_1040_FW 1
66 #define ISP_COMPILE_1080_FW 1
67 #define ISP_COMPILE_12160_FW 1
68 #define ISP_COMPILE_2100_FW 1
69 #define ISP_COMPILE_2200_FW 1
70 #define ISP_COMPILE_2300_FW 1
71 #endif
72
73 #if defined(ISP_DISABLE_1040_SUPPORT) || !defined(ISP_COMPILE_1040_FW)
74 #define ISP_1040_RISC_CODE NULL
75 #else
76 #define ISP_1040_RISC_CODE (u_int16_t *) isp_1040_risc_code
77 #include <dev/microcode/isp/asm_1040.h>
78 #endif
79
80 #if defined(ISP_DISABLE_1080_SUPPORT) || !defined(ISP_COMPILE_1080_FW)
81 #define ISP_1080_RISC_CODE NULL
82 #else
83 #define ISP_1080_RISC_CODE (u_int16_t *) isp_1080_risc_code
84 #include <dev/microcode/isp/asm_1080.h>
85 #endif
86
87 #if defined(ISP_DISABLE_12160_SUPPORT) || !defined(ISP_COMPILE_12160_FW)
88 #define ISP_12160_RISC_CODE (u_int16_t *) NULL
89 #else
90 #define ISP_12160_RISC_CODE (u_int16_t *) isp_12160_risc_code
91 #include <dev/microcode/isp/asm_12160.h>
92 #endif
93
94 #if defined(ISP_DISABLE_2100_SUPPORT) || !defined(ISP_COMPILE_2100_FW)
95 #define ISP_2100_RISC_CODE NULL
96 #else
97 #define ISP_2100_RISC_CODE (u_int16_t *) isp_2100_risc_code
98 #include <dev/microcode/isp/asm_2100.h>
99 #endif
100
101 #if defined(ISP_DISABLE_2200_SUPPORT) || !defined(ISP_COMPILE_2200_FW)
102 #define ISP_2200_RISC_CODE NULL
103 #else
104 #define ISP_2200_RISC_CODE (u_int16_t *) isp_2200_risc_code
105 #include <dev/microcode/isp/asm_2200.h>
106 #endif
107
108 #if defined(ISP_DISABLE_2300_SUPPORT) || !defined(ISP_COMPILE_2300_FW)
109 #define ISP_2300_RISC_CODE NULL
110 #else
111 #define ISP_2300_RISC_CODE (u_int16_t *) isp_2300_risc_code
112 #include <dev/microcode/isp/asm_2300.h>
113 #endif
114
115 #ifndef ISP_DISABLE_1020_SUPPORT
116 static struct ispmdvec mdvec = {
117 isp_pci_rd_isr,
118 isp_pci_rd_reg,
119 isp_pci_wr_reg,
120 isp_pci_mbxdma,
121 isp_pci_dmasetup,
122 isp_pci_dmateardown,
123 NULL,
124 isp_pci_reset1,
125 isp_pci_dumpregs,
126 ISP_1040_RISC_CODE,
127 BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64
128 };
129 #endif
130
131 #ifndef ISP_DISABLE_1080_SUPPORT
132 static struct ispmdvec mdvec_1080 = {
133 isp_pci_rd_isr,
134 isp_pci_rd_reg_1080,
135 isp_pci_wr_reg_1080,
136 isp_pci_mbxdma,
137 isp_pci_dmasetup,
138 isp_pci_dmateardown,
139 NULL,
140 isp_pci_reset1,
141 isp_pci_dumpregs,
142 ISP_1080_RISC_CODE,
143 BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64
144 };
145 #endif
146
147 #ifndef ISP_DISABLE_12160_SUPPORT
148 static struct ispmdvec mdvec_12160 = {
149 isp_pci_rd_isr,
150 isp_pci_rd_reg_1080,
151 isp_pci_wr_reg_1080,
152 isp_pci_mbxdma,
153 isp_pci_dmasetup,
154 isp_pci_dmateardown,
155 NULL,
156 isp_pci_reset1,
157 isp_pci_dumpregs,
158 ISP_12160_RISC_CODE,
159 BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64
160 };
161 #endif
162
163 #ifndef ISP_DISABLE_2100_SUPPORT
164 static struct ispmdvec mdvec_2100 = {
165 isp_pci_rd_isr,
166 isp_pci_rd_reg,
167 isp_pci_wr_reg,
168 isp_pci_mbxdma,
169 isp_pci_dmasetup,
170 isp_pci_dmateardown,
171 NULL,
172 isp_pci_reset1,
173 isp_pci_dumpregs,
174 ISP_2100_RISC_CODE
175 };
176 #endif
177
178 #ifndef ISP_DISABLE_2200_SUPPORT
179 static struct ispmdvec mdvec_2200 = {
180 isp_pci_rd_isr,
181 isp_pci_rd_reg,
182 isp_pci_wr_reg,
183 isp_pci_mbxdma,
184 isp_pci_dmasetup,
185 isp_pci_dmateardown,
186 NULL,
187 isp_pci_reset1,
188 isp_pci_dumpregs,
189 ISP_2200_RISC_CODE
190 };
191 #endif
192
193 #ifndef ISP_DISABLE_2300_SUPPORT
194 static struct ispmdvec mdvec_2300 = {
195 isp_pci_rd_isr_2300,
196 isp_pci_rd_reg,
197 isp_pci_wr_reg,
198 isp_pci_mbxdma,
199 isp_pci_dmasetup,
200 isp_pci_dmateardown,
201 NULL,
202 isp_pci_reset1,
203 isp_pci_dumpregs,
204 ISP_2300_RISC_CODE
205 };
206 #endif
207
208 #ifndef PCI_VENDOR_QLOGIC
209 #define PCI_VENDOR_QLOGIC 0x1077
210 #endif
211
212 #ifndef PCI_PRODUCT_QLOGIC_ISP1020
213 #define PCI_PRODUCT_QLOGIC_ISP1020 0x1020
214 #endif
215
216 #ifndef PCI_PRODUCT_QLOGIC_ISP1080
217 #define PCI_PRODUCT_QLOGIC_ISP1080 0x1080
218 #endif
219
220 #ifndef PCI_PRODUCT_QLOGIC_ISP1240
221 #define PCI_PRODUCT_QLOGIC_ISP1240 0x1240
222 #endif
223
224 #ifndef PCI_PRODUCT_QLOGIC_ISP1280
225 #define PCI_PRODUCT_QLOGIC_ISP1280 0x1280
226 #endif
227
228 #ifndef PCI_PRODUCT_QLOGIC_ISP10160
229 #define PCI_PRODUCT_QLOGIC_ISP10160 0x1016
230 #endif
231
232 #ifndef PCI_PRODUCT_QLOGIC_ISP12160
233 #define PCI_PRODUCT_QLOGIC_ISP12160 0x1216
234 #endif
235
236 #ifndef PCI_PRODUCT_QLOGIC_ISP2100
237 #define PCI_PRODUCT_QLOGIC_ISP2100 0x2100
238 #endif
239
240 #ifndef PCI_PRODUCT_QLOGIC_ISP2200
241 #define PCI_PRODUCT_QLOGIC_ISP2200 0x2200
242 #endif
243
244 #ifndef PCI_PRODUCT_QLOGIC_ISP2300
245 #define PCI_PRODUCT_QLOGIC_ISP2300 0x2300
246 #endif
247
248 #ifndef PCI_PRODUCT_QLOGIC_ISP2312
249 #define PCI_PRODUCT_QLOGIC_ISP2312 0x2312
250 #endif
251
252 #define PCI_QLOGIC_ISP ((PCI_PRODUCT_QLOGIC_ISP1020 << 16) | PCI_VENDOR_QLOGIC)
253
254 #define PCI_QLOGIC_ISP1080 \
255 ((PCI_PRODUCT_QLOGIC_ISP1080 << 16) | PCI_VENDOR_QLOGIC)
256
257 #define PCI_QLOGIC_ISP1240 \
258 ((PCI_PRODUCT_QLOGIC_ISP1240 << 16) | PCI_VENDOR_QLOGIC)
259
260 #define PCI_QLOGIC_ISP1280 \
261 ((PCI_PRODUCT_QLOGIC_ISP1280 << 16) | PCI_VENDOR_QLOGIC)
262
263 #define PCI_QLOGIC_ISP10160 \
264 ((PCI_PRODUCT_QLOGIC_ISP10160 << 16) | PCI_VENDOR_QLOGIC)
265
266 #define PCI_QLOGIC_ISP12160 \
267 ((PCI_PRODUCT_QLOGIC_ISP12160 << 16) | PCI_VENDOR_QLOGIC)
268
269 #define PCI_QLOGIC_ISP2100 \
270 ((PCI_PRODUCT_QLOGIC_ISP2100 << 16) | PCI_VENDOR_QLOGIC)
271
272 #define PCI_QLOGIC_ISP2200 \
273 ((PCI_PRODUCT_QLOGIC_ISP2200 << 16) | PCI_VENDOR_QLOGIC)
274
275 #define PCI_QLOGIC_ISP2300 \
276 ((PCI_PRODUCT_QLOGIC_ISP2300 << 16) | PCI_VENDOR_QLOGIC)
277
278 #define PCI_QLOGIC_ISP2312 \
279 ((PCI_PRODUCT_QLOGIC_ISP2312 << 16) | PCI_VENDOR_QLOGIC)
280 /*
281 * Odd case for some AMI raid cards... We need to *not* attach to this.
282 */
283 #define AMI_RAID_SUBVENDOR_ID 0x101e
284
285
286 #define IO_MAP_REG 0x10
287 #define MEM_MAP_REG 0x14
288 #define PCIR_ROMADDR 0x30
289
290 #define PCI_DFLT_LTNCY 0x40
291 #define PCI_DFLT_LNSZ 0x10
292
293 #ifndef SCSI_ISP_PREFER_MEM_MAP
294 #ifdef __alpha__
295 #define SCSI_ISP_PREFER_MEM_MAP 1
296 #else
297 #define SCSI_ISP_PREFER_MEM_MAP 0
298 #endif
299 #endif
300
301 #ifndef BUS_DMA_COHERENT
302 #define BUS_DMA_COHERENT BUS_DMAMEM_NOSYNC
303 #endif
304
305 static int isp_pci_probe (struct device *, void *, void *);
306 static void isp_pci_attach (struct device *, struct device *, void *);
307
308 struct isp_pcisoftc {
309 struct ispsoftc pci_isp;
310 pci_chipset_tag_t pci_pc;
311 pcitag_t pci_tag;
312 bus_space_tag_t pci_st;
313 bus_space_handle_t pci_sh;
314 bus_dmamap_t *pci_xfer_dmap;
315 void * pci_ih;
316 int16_t pci_poff[_NREG_BLKS];
317 };
318
319 struct cfattach isp_pci_ca = {
320 sizeof (struct isp_pcisoftc), isp_pci_probe, isp_pci_attach
321 };
322
323 #ifdef DEBUG
324 const char vstring[] =
325 "Qlogic ISP Driver, NetBSD (pci) Platform Version %d.%d Core Version %d.%d";
326 #endif
327
328 const struct pci_matchid ispdev[] = {
329 #ifndef ISP_DISABLE_1020_SUPPORT
330 { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1020 },
331 #endif
332 #ifndef ISP_DISABLE_1080_SUPPORT
333 { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1080 },
334 { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1240 },
335 { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1280 },
336 #endif
337 #ifndef ISP_DISABLE_12160_SUPPORT
338 { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP10160 },
339 { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP12160 },
340 #endif
341 #ifndef ISP_DISABLE_2100_SUPPORT
342 { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP2100 },
343 #endif
344 #ifndef ISP_DISABLE_2200_SUPPORT
345 { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP2200 },
346 #endif
347 #ifndef ISP_DISABLE_2300_SUPPORT
348 { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP2300 },
349 { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP2312 },
350 #endif
351 { 0, 0 }
352 };
353
354 static int
isp_pci_probe(struct device * parent,void * match,void * aux)355 isp_pci_probe(struct device *parent, void *match, void *aux)
356 {
357 struct pci_attach_args *pa = aux;
358
359 #ifndef ISP_DISABLE_12160_SUPPORT
360 /*
361 * Sigh. Check for subvendor id match here. Too bad we
362 * can't give an exclude mask in matchbyid.
363 */
364 if (pa->pa_id == PCI_QLOGIC_ISP12160) {
365 pcireg_t subvid =
366 pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBVEND_0);
367 if (PCI_VENDOR(subvid) == AMI_RAID_SUBVENDOR_ID) {
368 return (0);
369 }
370 }
371 #endif
372 return (pci_matchbyid(pa, ispdev, sizeof(ispdev)/sizeof(ispdev[0])));
373 }
374
375
376 static void
isp_pci_attach(struct device * parent,struct device * self,void * aux)377 isp_pci_attach(struct device *parent, struct device *self, void *aux)
378 {
379 #ifdef DEBUG
380 static char oneshot = 1;
381 #endif
382 static const char nomem[] = ": no mem for sdparam table\n";
383 u_int32_t data, rev, linesz = PCI_DFLT_LNSZ;
384 struct pci_attach_args *pa = aux;
385 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) self;
386 struct ispsoftc *isp = &pcs->pci_isp;
387 bus_space_tag_t st, iot, memt;
388 bus_space_handle_t sh, ioh, memh;
389 pci_intr_handle_t ih;
390 const char *intrstr;
391 int ioh_valid, memh_valid;
392 bus_addr_t iobase, mbase;
393 bus_size_t iosize, msize;
394
395 ioh_valid = memh_valid = 0;
396
397 #if SCSI_ISP_PREFER_MEM_MAP == 1
398 if (pci_mem_find(pa->pa_pc, pa->pa_tag, MEM_MAP_REG, &mbase, &msize,
399 NULL)) {
400 printf(": can't find mem space\n");
401 } else if (bus_space_map(pa->pa_memt, mbase, msize, 0, &memh)) {
402 printf(": can't map mem space\n");
403 } else {
404 memt = pa->pa_memt;
405 st = memt;
406 sh = memh;
407 memh_valid = 1;
408 }
409 if (memh_valid == 0) {
410 if (pci_io_find(pa->pa_pc, pa->pa_tag, IO_MAP_REG, &iobase,
411 &iosize)) {
412 printf(": can't find i/o space\n");
413 } else if (bus_space_map(pa->pa_iot, iobase, iosize, 0, &ioh)) {
414 printf(": can't map i/o space\n");
415 } else {
416 iot = pa->pa_iot;
417 st = iot;
418 sh = ioh;
419 ioh_valid = 1;
420 }
421 }
422 #else
423 if (pci_io_find(pa->pa_pc, pa->pa_tag, IO_MAP_REG, &iobase, &iosize)) {
424 printf(": can't find i/o space\n");
425 } else if (bus_space_map(pa->pa_iot, iobase, iosize, 0, &ioh)) {
426 printf(": can't map i/o space\n");
427 } else {
428 iot = pa->pa_iot;
429 st = iot;
430 sh = ioh;
431 ioh_valid = 1;
432 }
433 if (ioh_valid == 0) {
434 if (pci_mem_find(pa->pa_pc, pa->pa_tag, MEM_MAP_REG, &mbase,
435 &msize, NULL)) {
436 printf(": can't find mem space\n");
437 } else if (bus_space_map(pa->pa_memt, mbase, msize, 0, &memh)) {
438 printf(": can't map mem space\n");
439 } else {
440 memt = pa->pa_memt;
441 st = memt;
442 sh = memh;
443 memh_valid = 1;
444 }
445 }
446 #endif
447 if (ioh_valid == 0 && memh_valid == 0) {
448 printf(": unable to map device registers\n");
449 return;
450 }
451 #if 0
452 printf("\n");
453 #endif
454
455 pcs->pci_st = st;
456 pcs->pci_sh = sh;
457 pcs->pci_pc = pa->pa_pc;
458 pcs->pci_tag = pa->pa_tag;
459 pcs->pci_poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF;
460 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS_OFF;
461 pcs->pci_poff[SXP_BLOCK >> _BLK_REG_SHFT] = PCI_SXP_REGS_OFF;
462 pcs->pci_poff[RISC_BLOCK >> _BLK_REG_SHFT] = PCI_RISC_REGS_OFF;
463 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = DMA_REGS_OFF;
464 rev = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG) & 0xff;
465 #ifndef ISP_DISABLE_1020_SUPPORT
466 if (pa->pa_id == PCI_QLOGIC_ISP) {
467 isp->isp_mdvec = &mdvec;
468 isp->isp_type = ISP_HA_SCSI_UNKNOWN;
469 isp->isp_param = malloc(sizeof (sdparam), M_DEVBUF, M_NOWAIT);
470 if (isp->isp_param == NULL) {
471 printf(nomem);
472 return;
473 }
474 bzero(isp->isp_param, sizeof (sdparam));
475 }
476 #endif
477 #ifndef ISP_DISABLE_1080_SUPPORT
478 if (pa->pa_id == PCI_QLOGIC_ISP1080) {
479 isp->isp_mdvec = &mdvec_1080;
480 isp->isp_type = ISP_HA_SCSI_1080;
481 isp->isp_param = malloc(sizeof (sdparam), M_DEVBUF, M_NOWAIT);
482 if (isp->isp_param == NULL) {
483 printf(nomem);
484 return;
485 }
486 bzero(isp->isp_param, sizeof (sdparam));
487 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
488 ISP1080_DMA_REGS_OFF;
489 }
490 if (pa->pa_id == PCI_QLOGIC_ISP1240) {
491 isp->isp_mdvec = &mdvec_1080;
492 isp->isp_type = ISP_HA_SCSI_1240;
493 isp->isp_param = malloc(2 * sizeof (sdparam),
494 M_DEVBUF, M_NOWAIT);
495 if (isp->isp_param == NULL) {
496 printf(nomem);
497 return;
498 }
499 bzero(isp->isp_param, sizeof (sdparam));
500 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
501 ISP1080_DMA_REGS_OFF;
502 }
503 if (pa->pa_id == PCI_QLOGIC_ISP1280) {
504 isp->isp_mdvec = &mdvec_1080;
505 isp->isp_type = ISP_HA_SCSI_1280;
506 isp->isp_param = malloc(2 * sizeof (sdparam),
507 M_DEVBUF, M_NOWAIT);
508 if (isp->isp_param == NULL) {
509 printf(nomem);
510 return;
511 }
512 bzero(isp->isp_param, sizeof (sdparam));
513 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
514 ISP1080_DMA_REGS_OFF;
515 }
516 #endif
517 #ifndef ISP_DISABLE_12160_SUPPORT
518 if (pa->pa_id == PCI_QLOGIC_ISP10160) {
519 isp->isp_mdvec = &mdvec_12160;
520 isp->isp_type = ISP_HA_SCSI_10160;
521 isp->isp_param = malloc(sizeof (sdparam), M_DEVBUF, M_NOWAIT);
522 if (isp->isp_param == NULL) {
523 printf(nomem);
524 return;
525 }
526 bzero(isp->isp_param, sizeof (sdparam));
527 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
528 ISP1080_DMA_REGS_OFF;
529 }
530 if (pa->pa_id == PCI_QLOGIC_ISP12160) {
531 isp->isp_mdvec = &mdvec_12160;
532 isp->isp_type = ISP_HA_SCSI_12160;
533 isp->isp_param = malloc(2 * sizeof (sdparam),
534 M_DEVBUF, M_NOWAIT);
535 if (isp->isp_param == NULL) {
536 printf(nomem);
537 return;
538 }
539 bzero(isp->isp_param, 2 * sizeof (sdparam));
540 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
541 ISP1080_DMA_REGS_OFF;
542 }
543 #endif
544 #ifndef ISP_DISABLE_2100_SUPPORT
545 if (pa->pa_id == PCI_QLOGIC_ISP2100) {
546 isp->isp_mdvec = &mdvec_2100;
547 isp->isp_type = ISP_HA_FC_2100;
548 isp->isp_param = malloc(sizeof (fcparam), M_DEVBUF, M_NOWAIT);
549 if (isp->isp_param == NULL) {
550 printf(nomem);
551 return;
552 }
553 bzero(isp->isp_param, sizeof (fcparam));
554 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
555 PCI_MBOX_REGS2100_OFF;
556 if (rev < 3) {
557 /*
558 * XXX: Need to get the actual revision
559 * XXX: number of the 2100 FB. At any rate,
560 * XXX: lower cache line size for early revision
561 * XXX; boards.
562 */
563 linesz = 1;
564 }
565 }
566 #endif
567 #ifndef ISP_DISABLE_2200_SUPPORT
568 if (pa->pa_id == PCI_QLOGIC_ISP2200) {
569 isp->isp_mdvec = &mdvec_2200;
570 isp->isp_type = ISP_HA_FC_2200;
571 isp->isp_param = malloc(sizeof (fcparam), M_DEVBUF, M_NOWAIT);
572 if (isp->isp_param == NULL) {
573 printf(nomem);
574 return;
575 }
576 bzero(isp->isp_param, sizeof (fcparam));
577 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
578 PCI_MBOX_REGS2100_OFF;
579 data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG);
580 }
581 #endif
582 #ifndef ISP_DISABLE_2300_SUPPORT
583 if (pa->pa_id == PCI_QLOGIC_ISP2300 ||
584 pa->pa_id == PCI_QLOGIC_ISP2312) {
585 isp->isp_mdvec = &mdvec_2300;
586 if (pa->pa_id == PCI_QLOGIC_ISP2300) {
587 isp->isp_type = ISP_HA_FC_2300;
588 } else {
589 isp->isp_type = ISP_HA_FC_2312;
590 isp->isp_port = pa->pa_function;
591 }
592 isp->isp_param = malloc(sizeof (fcparam), M_DEVBUF, M_NOWAIT);
593 if (isp->isp_param == NULL) {
594 printf(nomem);
595 return;
596 }
597 bzero(isp->isp_param, sizeof (fcparam));
598 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
599 PCI_MBOX_REGS2300_OFF;
600 data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG);
601 }
602 #endif
603 /*
604 * Set up logging levels.
605 */
606 #ifdef ISP_LOGDEFAULT
607 isp->isp_dblev = ISP_LOGDEFAULT;
608 #else
609 isp->isp_dblev = ISP_LOGWARN|ISP_LOGERR;
610 #ifdef SCSIDEBUG
611 isp->isp_dblev |= ISP_LOGDEBUG1|ISP_LOGDEBUG2;
612 #endif
613 #ifdef DEBUG
614 isp->isp_dblev |= ISP_LOGDEBUG0|ISP_LOGCONFIG|ISP_LOGINFO;
615 #endif
616 #endif
617
618 #ifdef DEBUG
619 if (oneshot) {
620 oneshot = 0;
621 isp_prt(isp, ISP_LOGCONFIG, vstring,
622 ISP_PLATFORM_VERSION_MAJOR, ISP_PLATFORM_VERSION_MINOR,
623 ISP_CORE_VERSION_MAJOR, ISP_CORE_VERSION_MINOR);
624 }
625 #endif
626
627 isp->isp_dmatag = pa->pa_dmat;
628 isp->isp_revision = rev;
629
630 /*
631 * Make sure that command register set sanely.
632 */
633 data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
634 if (IS_2300(isp)) { /* per QLogic errata */
635 data &= ~PCI_COMMAND_PARITY_ENABLE;
636 }
637 if (IS_23XX(isp)) {
638 isp->isp_touched = 1;
639 }
640 data |= PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_INVALIDATE_ENABLE;
641
642 /*
643 * Not so sure about these- but I think it's important that they get
644 * enabled......
645 */
646 data |= PCI_COMMAND_PARITY_ENABLE | PCI_COMMAND_SERR_ENABLE;
647 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, data);
648
649 /*
650 * Make sure that the latency timer, cache line size,
651 * and ROM is disabled.
652 */
653 data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
654 data &= ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT);
655 data &= ~(PCI_CACHELINE_MASK << PCI_CACHELINE_SHIFT);
656 data |= (0x40 << PCI_LATTIMER_SHIFT);
657 data |= (0x10 << PCI_CACHELINE_SHIFT);
658 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG, data);
659
660 data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCIR_ROMADDR);
661 data &= ~1;
662 pci_conf_write(pa->pa_pc, pa->pa_tag, PCIR_ROMADDR, data);
663
664 if (pci_intr_map(pa, &ih)) {
665 printf(": couldn't map interrupt\n");
666 free(isp->isp_param, M_DEVBUF);
667 return;
668 }
669 intrstr = pci_intr_string(pa->pa_pc, ih);
670 if (intrstr == NULL)
671 intrstr = "<I dunno>";
672 pcs->pci_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, isp_pci_intr,
673 isp, isp->isp_name);
674 if (pcs->pci_ih == NULL) {
675 printf(": couldn't establish interrupt at %s\n",
676 intrstr);
677 free(isp->isp_param, M_DEVBUF);
678 return;
679 }
680
681 printf(": %s\n", intrstr);
682
683 if (IS_FC(isp)) {
684 DEFAULT_NODEWWN(isp) = 0x400000007F000003ULL;
685 DEFAULT_PORTWWN(isp) = 0x400000007F000003ULL;
686 }
687
688 isp->isp_confopts = self->dv_cfdata->cf_flags;
689 isp->isp_role = ISP_DEFAULT_ROLES;
690 ISP_LOCK(isp);
691 isp->isp_osinfo.no_mbox_ints = 1;
692 isp_reset(isp);
693 if (isp->isp_state != ISP_RESETSTATE) {
694 ISP_UNLOCK(isp);
695 free(isp->isp_param, M_DEVBUF);
696 return;
697 }
698 ENABLE_INTS(isp);
699 isp_init(isp);
700 if (isp->isp_state != ISP_INITSTATE) {
701 isp_uninit(isp);
702 ISP_UNLOCK(isp);
703 free(isp->isp_param, M_DEVBUF);
704 return;
705 }
706 /*
707 * Do Generic attach now.
708 */
709 isp_attach(isp);
710 if (isp->isp_state != ISP_RUNSTATE) {
711 isp_uninit(isp);
712 ISP_UNLOCK(isp);
713 free(isp->isp_param, M_DEVBUF);
714 } else {
715 ISP_UNLOCK(isp);
716 }
717 }
718
719 #define IspVirt2Off(a, x) \
720 (((struct isp_pcisoftc *)a)->pci_poff[((x) & _BLK_REG_MASK) >> \
721 _BLK_REG_SHFT] + ((x) & 0xff))
722
723 #define BXR2(pcs, off) \
724 bus_space_read_2(pcs->pci_st, pcs->pci_sh, off)
725 #define BXW2(pcs, off, v) \
726 bus_space_write_2(pcs->pci_st, pcs->pci_sh, off, v)
727
728
729 static INLINE int
isp_pci_rd_debounced(struct ispsoftc * isp,int off,u_int16_t * rp)730 isp_pci_rd_debounced(struct ispsoftc *isp, int off, u_int16_t *rp)
731 {
732 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
733 u_int16_t val0, val1;
734 int i = 0;
735
736 do {
737 val0 = BXR2(pcs, IspVirt2Off(isp, off));
738 val1 = BXR2(pcs, IspVirt2Off(isp, off));
739 } while (val0 != val1 && ++i < 1000);
740 if (val0 != val1) {
741 return (1);
742 }
743 *rp = val0;
744 return (0);
745 }
746
747 static int
isp_pci_rd_isr(struct ispsoftc * isp,u_int16_t * isrp,u_int16_t * semap,u_int16_t * mbp)748 isp_pci_rd_isr(struct ispsoftc *isp, u_int16_t *isrp,
749 u_int16_t *semap, u_int16_t *mbp)
750 {
751 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
752 u_int16_t isr, sema;
753
754 if (IS_2100(isp)) {
755 if (isp_pci_rd_debounced(isp, BIU_ISR, &isr)) {
756 return (0);
757 }
758 if (isp_pci_rd_debounced(isp, BIU_SEMA, &sema)) {
759 return (0);
760 }
761 } else {
762 isr = BXR2(pcs, IspVirt2Off(isp, BIU_ISR));
763 sema = BXR2(pcs, IspVirt2Off(isp, BIU_SEMA));
764 }
765 isp_prt(isp, ISP_LOGDEBUG3, "ISR 0x%x SEMA 0x%x", isr, sema);
766 isr &= INT_PENDING_MASK(isp);
767 sema &= BIU_SEMA_LOCK;
768 if (isr == 0 && sema == 0) {
769 return (0);
770 }
771 *isrp = isr;
772 if ((*semap = sema) != 0) {
773 if (IS_2100(isp)) {
774 if (isp_pci_rd_debounced(isp, OUTMAILBOX0, mbp)) {
775 return (0);
776 }
777 } else {
778 *mbp = BXR2(pcs, IspVirt2Off(isp, OUTMAILBOX0));
779 }
780 }
781 return (1);
782 }
783
784 #ifndef ISP_DISABLE_2300_SUPPORT
785 static int
isp_pci_rd_isr_2300(struct ispsoftc * isp,u_int16_t * isrp,u_int16_t * semap,u_int16_t * mbox0p)786 isp_pci_rd_isr_2300(struct ispsoftc *isp, u_int16_t *isrp,
787 u_int16_t *semap, u_int16_t *mbox0p)
788 {
789 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
790 u_int32_t r2hisr;
791
792 if (!(BXR2(pcs, IspVirt2Off(isp, BIU_ISR)) & BIU2100_ISR_RISC_INT)) {
793 *isrp = 0;
794 return (0);
795 }
796 r2hisr = bus_space_read_4(pcs->pci_st, pcs->pci_sh,
797 IspVirt2Off(pcs, BIU_R2HSTSLO));
798 isp_prt(isp, ISP_LOGDEBUG3, "RISC2HOST ISR 0x%x", r2hisr);
799 if ((r2hisr & BIU_R2HST_INTR) == 0) {
800 *isrp = 0;
801 return (0);
802 }
803 switch (r2hisr & BIU_R2HST_ISTAT_MASK) {
804 case ISPR2HST_ROM_MBX_OK:
805 case ISPR2HST_ROM_MBX_FAIL:
806 case ISPR2HST_MBX_OK:
807 case ISPR2HST_MBX_FAIL:
808 case ISPR2HST_ASYNC_EVENT:
809 *isrp = r2hisr & 0xffff;
810 *mbox0p = (r2hisr >> 16);
811 *semap = 1;
812 return (1);
813 case ISPR2HST_RIO_16:
814 *isrp = r2hisr & 0xffff;
815 *mbox0p = ASYNC_RIO1;
816 *semap = 1;
817 return (1);
818 case ISPR2HST_FPOST:
819 *isrp = r2hisr & 0xffff;
820 *mbox0p = ASYNC_CMD_CMPLT;
821 *semap = 1;
822 return (1);
823 case ISPR2HST_FPOST_CTIO:
824 *isrp = r2hisr & 0xffff;
825 *mbox0p = ASYNC_CTIO_DONE;
826 *semap = 1;
827 return (1);
828 case ISPR2HST_RSPQ_UPDATE:
829 *isrp = r2hisr & 0xffff;
830 *mbox0p = 0;
831 *semap = 0;
832 return (1);
833 default:
834 return (0);
835 }
836 }
837 #endif
838
839 static u_int16_t
isp_pci_rd_reg(struct ispsoftc * isp,int regoff)840 isp_pci_rd_reg(struct ispsoftc *isp, int regoff)
841 {
842 u_int16_t rv;
843 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
844 int oldconf = 0;
845
846 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
847 /*
848 * We will assume that someone has paused the RISC processor.
849 */
850 oldconf = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
851 BXW2(pcs, IspVirt2Off(isp, BIU_CONF1),
852 oldconf | BIU_PCI_CONF1_SXP);
853 }
854 rv = BXR2(pcs, IspVirt2Off(isp, regoff));
855 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
856 BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), oldconf);
857 }
858 return (rv);
859 }
860
861 static void
isp_pci_wr_reg(struct ispsoftc * isp,int regoff,u_int16_t val)862 isp_pci_wr_reg(struct ispsoftc *isp, int regoff, u_int16_t val)
863 {
864 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
865 int oldconf = 0;
866
867 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
868 /*
869 * We will assume that someone has paused the RISC processor.
870 */
871 oldconf = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
872 BXW2(pcs, IspVirt2Off(isp, BIU_CONF1),
873 oldconf | BIU_PCI_CONF1_SXP);
874 }
875 BXW2(pcs, IspVirt2Off(isp, regoff), val);
876 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
877 BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), oldconf);
878 }
879 }
880
881 #if !(defined(ISP_DISABLE_1080_SUPPORT) && defined(ISP_DISABLE_12160_SUPPORT))
882 static u_int16_t
isp_pci_rd_reg_1080(struct ispsoftc * isp,int regoff)883 isp_pci_rd_reg_1080(struct ispsoftc *isp, int regoff)
884 {
885 u_int16_t rv, oc = 0;
886 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
887
888 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||
889 (regoff & _BLK_REG_MASK) == (SXP_BLOCK|SXP_BANK1_SELECT)) {
890 u_int16_t tc;
891 /*
892 * We will assume that someone has paused the RISC processor.
893 */
894 oc = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
895 tc = oc & ~BIU_PCI1080_CONF1_DMA;
896 if (regoff & SXP_BANK1_SELECT)
897 tc |= BIU_PCI1080_CONF1_SXP1;
898 else
899 tc |= BIU_PCI1080_CONF1_SXP0;
900 BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), tc);
901 } else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {
902 oc = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
903 BXW2(pcs, IspVirt2Off(isp, BIU_CONF1),
904 oc | BIU_PCI1080_CONF1_DMA);
905 }
906 rv = BXR2(pcs, IspVirt2Off(isp, regoff));
907 if (oc) {
908 BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), oc);
909 }
910 return (rv);
911 }
912
913 static void
isp_pci_wr_reg_1080(struct ispsoftc * isp,int regoff,u_int16_t val)914 isp_pci_wr_reg_1080(struct ispsoftc *isp, int regoff, u_int16_t val)
915 {
916 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
917 int oc = 0;
918
919 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||
920 (regoff & _BLK_REG_MASK) == (SXP_BLOCK|SXP_BANK1_SELECT)) {
921 u_int16_t tc;
922 /*
923 * We will assume that someone has paused the RISC processor.
924 */
925 oc = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
926 tc = oc & ~BIU_PCI1080_CONF1_DMA;
927 if (regoff & SXP_BANK1_SELECT)
928 tc |= BIU_PCI1080_CONF1_SXP1;
929 else
930 tc |= BIU_PCI1080_CONF1_SXP0;
931 BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), tc);
932 } else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {
933 oc = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
934 BXW2(pcs, IspVirt2Off(isp, BIU_CONF1),
935 oc | BIU_PCI1080_CONF1_DMA);
936 }
937 BXW2(pcs, IspVirt2Off(isp, regoff), val);
938 if (oc) {
939 BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), oc);
940 }
941 }
942 #endif
943
944 static int
isp_pci_mbxdma(struct ispsoftc * isp)945 isp_pci_mbxdma(struct ispsoftc *isp)
946 {
947 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
948 bus_dma_tag_t dmat = isp->isp_dmatag;
949 bus_dma_segment_t sg;
950 bus_size_t len;
951 fcparam *fcp;
952 int rs, i;
953
954 if (isp->isp_rquest_dma) /* been here before? */
955 return (0);
956
957 len = isp->isp_maxcmds * sizeof (XS_T *);
958 isp->isp_xflist = (XS_T **) malloc(len, M_DEVBUF, M_WAITOK);
959 if (isp->isp_xflist == NULL) {
960 isp_prt(isp, ISP_LOGERR, "cannot malloc xflist array");
961 return (1);
962 }
963 bzero(isp->isp_xflist, len);
964 len = isp->isp_maxcmds * sizeof (bus_dmamap_t);
965 pcs->pci_xfer_dmap = (bus_dmamap_t *) malloc(len, M_DEVBUF, M_WAITOK);
966 if (pcs->pci_xfer_dmap == NULL) {
967 free(isp->isp_xflist, M_DEVBUF);
968 isp->isp_xflist = NULL;
969 isp_prt(isp, ISP_LOGERR, "cannot malloc dma map array");
970 return (1);
971 }
972
973 for (i = 0; i < isp->isp_maxcmds; i++) {
974 if (bus_dmamap_create(dmat, MAXPHYS, (MAXPHYS / NBPG) + 1,
975 MAXPHYS, 0, BUS_DMA_NOWAIT, &pcs->pci_xfer_dmap[i])) {
976 isp_prt(isp, ISP_LOGERR, "cannot create dma maps");
977 break;
978 }
979 }
980
981 if (i < isp->isp_maxcmds) {
982 while (--i >= 0) {
983 bus_dmamap_destroy(dmat, pcs->pci_xfer_dmap[i]);
984 }
985 free(isp->isp_xflist, M_DEVBUF);
986 free(pcs->pci_xfer_dmap, M_DEVBUF);
987 isp->isp_xflist = NULL;
988 pcs->pci_xfer_dmap = NULL;
989 return (1);
990 }
991
992 /*
993 * Allocate and map the request queue.
994 */
995 len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp));
996 if (bus_dmamem_alloc(dmat, len, PAGE_SIZE, 0, &sg, 1, &rs,
997 BUS_DMA_NOWAIT) ||
998 bus_dmamem_map(isp->isp_dmatag, &sg, rs, len,
999 (caddr_t *)&isp->isp_rquest, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
1000 goto dmafail;
1001 }
1002
1003 if (bus_dmamap_create(dmat, len, 1, len, 0, BUS_DMA_NOWAIT,
1004 &isp->isp_rqdmap) || bus_dmamap_load(dmat, isp->isp_rqdmap,
1005 (caddr_t)isp->isp_rquest, len, NULL,
1006 BUS_DMA_NOWAIT)) {
1007 goto dmafail;
1008 }
1009 isp->isp_rquest_dma = isp->isp_rqdmap->dm_segs[0].ds_addr;
1010
1011 /*
1012 * Allocate and map the result queue.
1013 */
1014 len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp));
1015 if (bus_dmamem_alloc(dmat, len, PAGE_SIZE, 0, &sg, 1, &rs,
1016 BUS_DMA_NOWAIT) ||
1017 bus_dmamem_map(dmat, &sg, rs, len, (caddr_t *)&isp->isp_result,
1018 BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
1019 goto dmafail;
1020 }
1021 if (bus_dmamap_create(dmat, len, 1, len, 0, BUS_DMA_NOWAIT,
1022 &isp->isp_rsdmap) || bus_dmamap_load(isp->isp_dmatag,
1023 isp->isp_rsdmap, (caddr_t)isp->isp_result, len, NULL,
1024 BUS_DMA_NOWAIT)) {
1025 goto dmafail;
1026 }
1027 isp->isp_result_dma = isp->isp_rsdmap->dm_segs[0].ds_addr;
1028
1029 if (IS_SCSI(isp)) {
1030 return (0);
1031 }
1032
1033 fcp = isp->isp_param;
1034 len = ISP2100_SCRLEN;
1035 if (bus_dmamem_alloc(dmat, len, PAGE_SIZE, 0, &sg, 1, &rs,
1036 BUS_DMA_NOWAIT) ||
1037 bus_dmamem_map(dmat, &sg, rs, len, (caddr_t *)&fcp->isp_scratch,
1038 BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
1039 goto dmafail;
1040 }
1041 if (bus_dmamap_create(dmat, len, 1, len, 0, BUS_DMA_NOWAIT,
1042 &isp->isp_scdmap) || bus_dmamap_load(dmat,
1043 isp->isp_scdmap, (caddr_t)fcp->isp_scratch, len, NULL,
1044 BUS_DMA_NOWAIT)) {
1045 goto dmafail;
1046 }
1047 fcp->isp_scdma = isp->isp_scdmap->dm_segs[0].ds_addr;
1048 return (0);
1049 dmafail:
1050 isp_prt(isp, ISP_LOGERR, "mailbox dma setup failure");
1051 for (i = 0; i < isp->isp_maxcmds; i++) {
1052 bus_dmamap_destroy(dmat, pcs->pci_xfer_dmap[i]);
1053 }
1054 free(isp->isp_xflist, M_DEVBUF);
1055 free(pcs->pci_xfer_dmap, M_DEVBUF);
1056 isp->isp_xflist = NULL;
1057 pcs->pci_xfer_dmap = NULL;
1058 return (1);
1059 }
1060
1061 static int
isp_pci_dmasetup(struct ispsoftc * isp,XS_T * xs,ispreq_t * rq,u_int16_t * nxtip,u_int16_t optr)1062 isp_pci_dmasetup(struct ispsoftc *isp, XS_T *xs, ispreq_t *rq,
1063 u_int16_t *nxtip, u_int16_t optr)
1064 {
1065 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
1066 bus_dmamap_t dmap;
1067 u_int16_t starti = isp->isp_reqidx, nxti = *nxtip;
1068 ispreq_t *qep;
1069 int segcnt, seg, error, ovseg, seglim, drq;
1070
1071 qep = (ispreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, starti);
1072 dmap = pcs->pci_xfer_dmap[isp_handle_index(rq->req_handle)];
1073 if (xs->datalen == 0) {
1074 rq->req_seg_count = 1;
1075 goto mbxsync;
1076 }
1077
1078 if (xs->flags & SCSI_DATA_IN) {
1079 drq = REQFLAG_DATA_IN;
1080 } else {
1081 drq = REQFLAG_DATA_OUT;
1082 }
1083
1084 if (IS_FC(isp)) {
1085 seglim = ISP_RQDSEG_T2;
1086 ((ispreqt2_t *)rq)->req_totalcnt = xs->datalen;
1087 ((ispreqt2_t *)rq)->req_flags |= drq;
1088 } else {
1089 rq->req_flags |= drq;
1090 if (XS_CDBLEN(xs) > 12)
1091 seglim = 0;
1092 else
1093 seglim = ISP_RQDSEG;
1094 }
1095 error = bus_dmamap_load(isp->isp_dmatag, dmap, xs->data, xs->datalen,
1096 NULL, (xs->flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
1097 if (error) {
1098 XS_SETERR(xs, HBA_BOTCH);
1099 return (CMD_COMPLETE);
1100 }
1101
1102 segcnt = dmap->dm_nsegs;
1103
1104 isp_prt(isp, ISP_LOGDEBUG2, "%d byte %s %p in %d segs",
1105 xs->datalen, (xs->flags & SCSI_DATA_IN)? "read to" :
1106 "write from", xs->data, segcnt);
1107
1108 for (seg = 0, rq->req_seg_count = 0;
1109 seg < segcnt && rq->req_seg_count < seglim;
1110 seg++, rq->req_seg_count++) {
1111 if (isp->isp_type & ISP_HA_FC) {
1112 ispreqt2_t *rq2 = (ispreqt2_t *)rq;
1113 rq2->req_dataseg[rq2->req_seg_count].ds_count =
1114 dmap->dm_segs[seg].ds_len;
1115 rq2->req_dataseg[rq2->req_seg_count].ds_base =
1116 dmap->dm_segs[seg].ds_addr;
1117 } else {
1118 rq->req_dataseg[rq->req_seg_count].ds_count =
1119 dmap->dm_segs[seg].ds_len;
1120 rq->req_dataseg[rq->req_seg_count].ds_base =
1121 dmap->dm_segs[seg].ds_addr;
1122 }
1123 isp_prt(isp, ISP_LOGDEBUG2, "seg0.[%d]={0x%lx,%lu}",
1124 rq->req_seg_count, (long) dmap->dm_segs[seg].ds_addr,
1125 (unsigned long) dmap->dm_segs[seg].ds_len);
1126 }
1127
1128 if (seg == segcnt) {
1129 goto dmasync;
1130 }
1131
1132 do {
1133 u_int16_t onxti;
1134 ispcontreq_t *crq, *cqe, local;
1135
1136 crq = &local;
1137
1138 cqe = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, nxti);
1139 onxti = nxti;
1140 nxti = ISP_NXT_QENTRY(onxti, RQUEST_QUEUE_LEN(isp));
1141 if (nxti == optr) {
1142 isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow++");
1143 bus_dmamap_unload(isp->isp_dmatag, dmap);
1144 XS_SETERR(xs, HBA_BOTCH);
1145 return (CMD_EAGAIN);
1146 }
1147 rq->req_header.rqs_entry_count++;
1148 bzero((void *)crq, sizeof (*crq));
1149 crq->req_header.rqs_entry_count = 1;
1150 crq->req_header.rqs_entry_type = RQSTYPE_DATASEG;
1151
1152 for (ovseg = 0; seg < segcnt && ovseg < ISP_CDSEG;
1153 rq->req_seg_count++, seg++, ovseg++) {
1154 crq->req_dataseg[ovseg].ds_count =
1155 dmap->dm_segs[seg].ds_len;
1156 crq->req_dataseg[ovseg].ds_base =
1157 dmap->dm_segs[seg].ds_addr;
1158 isp_prt(isp, ISP_LOGDEBUG2, "seg%d.[%d]={0x%lx,%lu}",
1159 rq->req_header.rqs_entry_count - 1,
1160 rq->req_seg_count, (long)dmap->dm_segs[seg].ds_addr,
1161 (unsigned long) dmap->dm_segs[seg].ds_len);
1162 }
1163 isp_put_cont_req(isp, crq, cqe);
1164 MEMORYBARRIER(isp, SYNC_REQUEST, onxti, QENTRY_LEN);
1165 } while (seg < segcnt);
1166
1167 dmasync:
1168 bus_dmamap_sync(isp->isp_dmatag, dmap, 0, dmap->dm_mapsize,
1169 (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
1170 BUS_DMASYNC_PREWRITE);
1171
1172 mbxsync:
1173 switch (rq->req_header.rqs_entry_type) {
1174 case RQSTYPE_REQUEST:
1175 isp_put_request(isp, rq, qep);
1176 break;
1177 case RQSTYPE_CMDONLY:
1178 isp_put_extended_request(isp, (ispextreq_t *)rq,
1179 (ispextreq_t *)qep);
1180 break;
1181 case RQSTYPE_T2RQS:
1182 isp_put_request_t2(isp, (ispreqt2_t *) rq, (ispreqt2_t *) qep);
1183 break;
1184 }
1185 *nxtip = nxti;
1186 return (CMD_QUEUED);
1187 }
1188
1189 static int
isp_pci_intr(void * arg)1190 isp_pci_intr(void *arg)
1191 {
1192 u_int16_t isr, sema, mbox;
1193 struct ispsoftc *isp = (struct ispsoftc *)arg;
1194
1195 isp->isp_intcnt++;
1196 if (ISP_READ_ISR(isp, &isr, &sema, &mbox) == 0) {
1197 isp->isp_intbogus++;
1198 return (0);
1199 } else {
1200 isp->isp_osinfo.onintstack = 1;
1201 isp_intr(isp, isr, sema, mbox);
1202 isp->isp_osinfo.onintstack = 0;
1203 return (1);
1204 }
1205 }
1206
1207 static void
isp_pci_dmateardown(struct ispsoftc * isp,XS_T * xs,u_int16_t handle)1208 isp_pci_dmateardown(struct ispsoftc *isp, XS_T *xs, u_int16_t handle)
1209 {
1210 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
1211 bus_dmamap_t dmap = pcs->pci_xfer_dmap[isp_handle_index(handle)];
1212 bus_dmamap_sync(isp->isp_dmatag, dmap, 0, dmap->dm_mapsize,
1213 (xs->flags & SCSI_DATA_IN)?
1214 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
1215 bus_dmamap_unload(isp->isp_dmatag, dmap);
1216 }
1217
1218 static void
isp_pci_reset1(struct ispsoftc * isp)1219 isp_pci_reset1(struct ispsoftc *isp)
1220 {
1221 /* Make sure the BIOS is disabled */
1222 isp_pci_wr_reg(isp, HCCR, PCI_HCCR_CMD_BIOS);
1223 if (isp->isp_osinfo.no_mbox_ints == 0) {
1224 ENABLE_INTS(isp);
1225 }
1226 }
1227
1228 static void
isp_pci_dumpregs(struct ispsoftc * isp,const char * msg)1229 isp_pci_dumpregs(struct ispsoftc *isp, const char *msg)
1230 {
1231 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
1232 if (msg)
1233 isp_prt(isp, ISP_LOGERR, "%s", msg);
1234 isp_prt(isp, ISP_LOGERR, "PCI Status Command/Status=%x\n",
1235 pci_conf_read(pcs->pci_pc, pcs->pci_tag, PCI_COMMAND_STATUS_REG));
1236 }
1237