isp_pci.c revision 1.54 1 /* $NetBSD: isp_pci.c,v 1.54 2000/08/02 17:39:50 mjacob Exp $ */
2 /*
3 * PCI specific probe and attach routines for Qlogic ISP SCSI adapters.
4 * Matthew Jacob (mjacob (at) nas.nasa.gov)
5 */
6 /*
7 * Copyright (C) 1997, 1998, 1999 National Aeronautics & Space Administration
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <dev/ic/isp_netbsd.h>
34 #include <dev/pci/pcireg.h>
35 #include <dev/pci/pcivar.h>
36 #include <dev/pci/pcidevs.h>
37
38 static u_int16_t isp_pci_rd_reg __P((struct ispsoftc *, int));
39 static void isp_pci_wr_reg __P((struct ispsoftc *, int, u_int16_t));
40 #if !(defined(ISP_DISABLE_1080_SUPPORT) && defined(ISP_DISABLE_12160_SUPPORT))
41 static u_int16_t isp_pci_rd_reg_1080 __P((struct ispsoftc *, int));
42 static void isp_pci_wr_reg_1080 __P((struct ispsoftc *, int, u_int16_t));
43 #endif
44 static int isp_pci_mbxdma __P((struct ispsoftc *));
45 static int isp_pci_dmasetup __P((struct ispsoftc *, struct scsipi_xfer *,
46 ispreq_t *, u_int16_t *, u_int16_t));
47 static void isp_pci_dmateardown __P((struct ispsoftc *, struct scsipi_xfer *,
48 u_int32_t));
49 static void isp_pci_reset1 __P((struct ispsoftc *));
50 static void isp_pci_dumpregs __P((struct ispsoftc *, const char *));
51 static int isp_pci_intr __P((void *));
52
53 #if defined(ISP_DISABLE_1020_SUPPORT)
54 #define ISP_1040_RISC_CODE NULL
55 #else
56 #define ISP_1040_RISC_CODE isp_1040_risc_code
57 #include <dev/microcode/isp/asm_1040.h>
58 #endif
59
60 #if defined(ISP_DISABLE_1080_SUPPORT)
61 #define ISP_1080_RISC_CODE NULL
62 #else
63 #define ISP_1080_RISC_CODE isp_1080_risc_code
64 #include <dev/microcode/isp/asm_1080.h>
65 #endif
66
67 #if defined(ISP_DISABLE_12160_SUPPORT)
68 #define ISP_12160_RISC_CODE NULL
69 #else
70 #define ISP_12160_RISC_CODE isp_12160_risc_code
71 #include <dev/microcode/isp/asm_12160.h>
72 #endif
73
74 #if defined(ISP_DISABLE_2100_SUPPORT)
75 #define ISP_2100_RISC_CODE NULL
76 #else
77 #define ISP_2100_RISC_CODE isp_2100_risc_code
78 #include <dev/microcode/isp/asm_2100.h>
79 #endif
80
81 #if defined(ISP_DISABLE_2200_SUPPORT)
82 #define ISP_2200_RISC_CODE NULL
83 #else
84 #define ISP_2200_RISC_CODE isp_2200_risc_code
85 #include <dev/microcode/isp/asm_2200.h>
86 #endif
87
88 #ifndef ISP_DISABLE_1020_SUPPORT
89 static struct ispmdvec mdvec = {
90 isp_pci_rd_reg,
91 isp_pci_wr_reg,
92 isp_pci_mbxdma,
93 isp_pci_dmasetup,
94 isp_pci_dmateardown,
95 NULL,
96 isp_pci_reset1,
97 isp_pci_dumpregs,
98 ISP_1040_RISC_CODE,
99 BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64
100 };
101 #endif
102
103 #ifndef ISP_DISABLE_1080_SUPPORT
104 static struct ispmdvec mdvec_1080 = {
105 isp_pci_rd_reg_1080,
106 isp_pci_wr_reg_1080,
107 isp_pci_mbxdma,
108 isp_pci_dmasetup,
109 isp_pci_dmateardown,
110 NULL,
111 isp_pci_reset1,
112 isp_pci_dumpregs,
113 ISP_1080_RISC_CODE,
114 BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64
115 };
116 #endif
117
118 #ifndef ISP_DISABLE_12160_SUPPORT
119 static struct ispmdvec mdvec_12160 = {
120 isp_pci_rd_reg_1080,
121 isp_pci_wr_reg_1080,
122 isp_pci_mbxdma,
123 isp_pci_dmasetup,
124 isp_pci_dmateardown,
125 NULL,
126 isp_pci_reset1,
127 isp_pci_dumpregs,
128 ISP_12160_RISC_CODE,
129 BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64
130 };
131 #endif
132
133 #ifndef ISP_DISABLE_2100_SUPPORT
134 static struct ispmdvec mdvec_2100 = {
135 isp_pci_rd_reg,
136 isp_pci_wr_reg,
137 isp_pci_mbxdma,
138 isp_pci_dmasetup,
139 isp_pci_dmateardown,
140 NULL,
141 isp_pci_reset1,
142 isp_pci_dumpregs,
143 ISP_2100_RISC_CODE
144 };
145 #endif
146
147 #ifndef ISP_DISABLE_2200_SUPPORT
148 static struct ispmdvec mdvec_2200 = {
149 isp_pci_rd_reg,
150 isp_pci_wr_reg,
151 isp_pci_mbxdma,
152 isp_pci_dmasetup,
153 isp_pci_dmateardown,
154 NULL,
155 isp_pci_reset1,
156 isp_pci_dumpregs,
157 ISP_2200_RISC_CODE
158 };
159 #endif
160
161 #ifndef PCI_VENDOR_QLOGIC
162 #define PCI_VENDOR_QLOGIC 0x1077
163 #endif
164
165 #ifndef PCI_PRODUCT_QLOGIC_ISP1020
166 #define PCI_PRODUCT_QLOGIC_ISP1020 0x1020
167 #endif
168
169 #ifndef PCI_PRODUCT_QLOGIC_ISP1080
170 #define PCI_PRODUCT_QLOGIC_ISP1080 0x1080
171 #endif
172
173 #ifndef PCI_PRODUCT_QLOGIC_ISP1240
174 #define PCI_PRODUCT_QLOGIC_ISP1240 0x1240
175 #endif
176
177 #ifndef PCI_PRODUCT_QLOGIC_ISP1280
178 #define PCI_PRODUCT_QLOGIC_ISP1280 0x1280
179 #endif
180
181 #ifndef PCI_PRODUCT_QLOGIC_ISP12160
182 #define PCI_PRODUCT_QLOGIC_ISP12160 0x1216
183 #endif
184
185 #ifndef PCI_PRODUCT_QLOGIC_ISP2100
186 #define PCI_PRODUCT_QLOGIC_ISP2100 0x2100
187 #endif
188
189 #ifndef PCI_PRODUCT_QLOGIC_ISP2200
190 #define PCI_PRODUCT_QLOGIC_ISP2200 0x2200
191 #endif
192
193 #define PCI_QLOGIC_ISP ((PCI_PRODUCT_QLOGIC_ISP1020 << 16) | PCI_VENDOR_QLOGIC)
194
195 #define PCI_QLOGIC_ISP1080 \
196 ((PCI_PRODUCT_QLOGIC_ISP1080 << 16) | PCI_VENDOR_QLOGIC)
197
198 #define PCI_QLOGIC_ISP1240 \
199 ((PCI_PRODUCT_QLOGIC_ISP1240 << 16) | PCI_VENDOR_QLOGIC)
200
201 #define PCI_QLOGIC_ISP1280 \
202 ((PCI_PRODUCT_QLOGIC_ISP1280 << 16) | PCI_VENDOR_QLOGIC)
203
204 #define PCI_QLOGIC_ISP12160 \
205 ((PCI_PRODUCT_QLOGIC_ISP12160 << 16) | PCI_VENDOR_QLOGIC)
206
207 #define PCI_QLOGIC_ISP2100 \
208 ((PCI_PRODUCT_QLOGIC_ISP2100 << 16) | PCI_VENDOR_QLOGIC)
209
210 #define PCI_QLOGIC_ISP2200 \
211 ((PCI_PRODUCT_QLOGIC_ISP2200 << 16) | PCI_VENDOR_QLOGIC)
212
213 #define IO_MAP_REG 0x10
214 #define MEM_MAP_REG 0x14
215 #define PCIR_ROMADDR 0x30
216
217 #define PCI_DFLT_LTNCY 0x40
218 #define PCI_DFLT_LNSZ 0x10
219
220
221 static int isp_pci_probe __P((struct device *, struct cfdata *, void *));
222 static void isp_pci_attach __P((struct device *, struct device *, void *));
223
224 struct isp_pcisoftc {
225 struct ispsoftc pci_isp;
226 pci_chipset_tag_t pci_pc;
227 pcitag_t pci_tag;
228 bus_space_tag_t pci_st;
229 bus_space_handle_t pci_sh;
230 bus_dma_tag_t pci_dmat;
231 bus_dmamap_t pci_scratch_dmap; /* for fcp only */
232 bus_dmamap_t pci_rquest_dmap;
233 bus_dmamap_t pci_result_dmap;
234 bus_dmamap_t *pci_xfer_dmap;
235 void * pci_ih;
236 int16_t pci_poff[_NREG_BLKS];
237 };
238
239 struct cfattach isp_pci_ca = {
240 sizeof (struct isp_pcisoftc), isp_pci_probe, isp_pci_attach
241 };
242
243 static char *vstring =
244 "Qlogic ISP Driver, NetBSD (pci) Platform Version %d.%d Core Version %d.%d";
245
246 static int
247 isp_pci_probe(parent, match, aux)
248 struct device *parent;
249 struct cfdata *match;
250 void *aux;
251 {
252 struct pci_attach_args *pa = aux;
253 switch (pa->pa_id) {
254 #ifndef ISP_DISABLE_1020_SUPPORT
255 case PCI_QLOGIC_ISP:
256 return (1);
257 #endif
258 #ifndef ISP_DISABLE_1080_SUPPORT
259 case PCI_QLOGIC_ISP1080:
260 case PCI_QLOGIC_ISP1240:
261 case PCI_QLOGIC_ISP1280:
262 return (1);
263 #endif
264 #ifndef ISP_DISABLE_12160_SUPPORT
265 case PCI_QLOGIC_ISP12160:
266 return (1);
267 #endif
268 #ifndef ISP_DISABLE_2100_SUPPORT
269 case PCI_QLOGIC_ISP2100:
270 return (1);
271 #endif
272 #ifndef ISP_DISABLE_2200_SUPPORT
273 case PCI_QLOGIC_ISP2200:
274 return (1);
275 #endif
276 default:
277 return (0);
278 }
279 }
280
281
282 static void
283 isp_pci_attach(parent, self, aux)
284 struct device *parent, *self;
285 void *aux;
286 {
287 #ifdef DEBUG
288 static char oneshot = 1;
289 #endif
290 static char *nomem = "%s: no mem for sdparam table\n";
291 u_int32_t data, rev, linesz = PCI_DFLT_LNSZ;
292 struct pci_attach_args *pa = aux;
293 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) self;
294 struct ispsoftc *isp = &pcs->pci_isp;
295 bus_space_tag_t st, iot, memt;
296 bus_space_handle_t sh, ioh, memh;
297 pci_intr_handle_t ih;
298 const char *intrstr;
299 int ioh_valid, memh_valid;
300
301 ioh_valid = (pci_mapreg_map(pa, IO_MAP_REG,
302 PCI_MAPREG_TYPE_IO, 0,
303 &iot, &ioh, NULL, NULL) == 0);
304 memh_valid = (pci_mapreg_map(pa, MEM_MAP_REG,
305 PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0,
306 &memt, &memh, NULL, NULL) == 0);
307
308 if (memh_valid) {
309 st = memt;
310 sh = memh;
311 } else if (ioh_valid) {
312 st = iot;
313 sh = ioh;
314 } else {
315 printf(": unable to map device registers\n");
316 return;
317 }
318 printf("\n");
319
320 pcs->pci_st = st;
321 pcs->pci_sh = sh;
322 pcs->pci_dmat = pa->pa_dmat;
323 pcs->pci_pc = pa->pa_pc;
324 pcs->pci_tag = pa->pa_tag;
325 pcs->pci_poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF;
326 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS_OFF;
327 pcs->pci_poff[SXP_BLOCK >> _BLK_REG_SHFT] = PCI_SXP_REGS_OFF;
328 pcs->pci_poff[RISC_BLOCK >> _BLK_REG_SHFT] = PCI_RISC_REGS_OFF;
329 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = DMA_REGS_OFF;
330 rev = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG) & 0xff;
331
332 #ifndef ISP_DISABLE_1020_SUPPORT
333 if (pa->pa_id == PCI_QLOGIC_ISP) {
334 isp->isp_mdvec = &mdvec;
335 isp->isp_type = ISP_HA_SCSI_UNKNOWN;
336 isp->isp_param = malloc(sizeof (sdparam), M_DEVBUF, M_NOWAIT);
337 if (isp->isp_param == NULL) {
338 printf(nomem, isp->isp_name);
339 return;
340 }
341 bzero(isp->isp_param, sizeof (sdparam));
342 }
343 #endif
344 #ifndef ISP_DISABLE_1080_SUPPORT
345 if (pa->pa_id == PCI_QLOGIC_ISP1080) {
346 isp->isp_mdvec = &mdvec_1080;
347 isp->isp_type = ISP_HA_SCSI_1080;
348 isp->isp_param = malloc(sizeof (sdparam), M_DEVBUF, M_NOWAIT);
349 if (isp->isp_param == NULL) {
350 printf(nomem, isp->isp_name);
351 return;
352 }
353 bzero(isp->isp_param, sizeof (sdparam));
354 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
355 ISP1080_DMA_REGS_OFF;
356 }
357 if (pa->pa_id == PCI_QLOGIC_ISP1240) {
358 isp->isp_mdvec = &mdvec_1080;
359 isp->isp_type = ISP_HA_SCSI_1240;
360 isp->isp_param =
361 malloc(2 * sizeof (sdparam), M_DEVBUF, M_NOWAIT);
362 if (isp->isp_param == NULL) {
363 printf(nomem, isp->isp_name);
364 return;
365 }
366 bzero(isp->isp_param, 2 * sizeof (sdparam));
367 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
368 ISP1080_DMA_REGS_OFF;
369 }
370 if (pa->pa_id == PCI_QLOGIC_ISP1280) {
371 isp->isp_mdvec = &mdvec_1080;
372 isp->isp_type = ISP_HA_SCSI_1280;
373 isp->isp_param =
374 malloc(2 * sizeof (sdparam), M_DEVBUF, M_NOWAIT);
375 if (isp->isp_param == NULL) {
376 printf(nomem, isp->isp_name);
377 return;
378 }
379 bzero(isp->isp_param, 2 * sizeof (sdparam));
380 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
381 ISP1080_DMA_REGS_OFF;
382 }
383 #endif
384 #ifndef ISP_DISABLE_12160_SUPPORT
385 if (pa->pa_id == PCI_QLOGIC_ISP12160) {
386 isp->isp_mdvec = &mdvec_12160;
387 isp->isp_type = ISP_HA_SCSI_12160;
388 isp->isp_param =
389 malloc(2 * sizeof (sdparam), M_DEVBUF, M_NOWAIT);
390 if (isp->isp_param == NULL) {
391 printf(nomem, isp->isp_name);
392 return;
393 }
394 bzero(isp->isp_param, 2 * sizeof (sdparam));
395 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
396 ISP1080_DMA_REGS_OFF;
397 }
398 #endif
399 #ifndef ISP_DISABLE_2100_SUPPORT
400 if (pa->pa_id == PCI_QLOGIC_ISP2100) {
401 isp->isp_mdvec = &mdvec_2100;
402 isp->isp_type = ISP_HA_FC_2100;
403 isp->isp_param = malloc(sizeof (fcparam), M_DEVBUF, M_NOWAIT);
404 if (isp->isp_param == NULL) {
405 printf(nomem, isp->isp_name);
406 return;
407 }
408 bzero(isp->isp_param, sizeof (fcparam));
409 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
410 PCI_MBOX_REGS2100_OFF;
411 if (rev < 3) {
412 /*
413 * XXX: Need to get the actual revision
414 * XXX: number of the 2100 FB. At any rate,
415 * XXX: lower cache line size for early revision
416 * XXX; boards.
417 */
418 linesz = 1;
419 }
420 }
421 #endif
422 #ifndef ISP_DISABLE_2200_SUPPORT
423 if (pa->pa_id == PCI_QLOGIC_ISP2200) {
424 isp->isp_mdvec = &mdvec_2200;
425 isp->isp_type = ISP_HA_FC_2200;
426 isp->isp_param = malloc(sizeof (fcparam), M_DEVBUF, M_NOWAIT);
427 if (isp->isp_param == NULL) {
428 printf(nomem, isp->isp_name);
429 return;
430 }
431 bzero(isp->isp_param, sizeof (fcparam));
432 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
433 PCI_MBOX_REGS2100_OFF;
434 data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG);
435 }
436 #endif
437 /*
438 * Set up logging levels.
439 */
440 #ifdef ISP_LOGDEFAULT
441 isp->isp_dblev = ISP_LOGDEFAULT;
442 #else
443 isp->isp_dblev = ISP_LOGCONFIG|ISP_LOGWARN|ISP_LOGERR;
444 #ifdef SCSIDEBUG
445 isp->isp_dblev |= ISP_LOGDEBUG1|ISP_LOGDEBUG2;
446 #endif
447 #ifdef DEBUG
448 isp->isp_dblev |= ISP_LOGDEBUG0;
449 #endif
450 #ifdef DIAGNOSTIC
451 isp->isp_dblev |= ISP_LOGINFO;
452 #endif
453 #endif
454 #ifdef DEBUG
455 if (oneshot) {
456 oneshot = 0;
457 isp_prt(isp, ISP_LOGCONFIG, vstring,
458 ISP_PLATFORM_VERSION_MAJOR, ISP_PLATFORM_VERSION_MINOR,
459 ISP_CORE_VERSION_MAJOR, ISP_CORE_VERSION_MINOR);
460 }
461 #endif
462
463 isp->isp_revision = rev;
464
465 /*
466 * Make sure that command register set sanely.
467 */
468 data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
469 data |= PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_INVALIDATE_ENABLE;
470
471 /*
472 * Not so sure about these- but I think it's important that they get
473 * enabled......
474 */
475 data |= PCI_COMMAND_PARITY_ENABLE | PCI_COMMAND_SERR_ENABLE;
476 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, data);
477
478 /*
479 * Make sure that the latency timer, cache line size,
480 * and ROM is disabled.
481 */
482 data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
483 data &= ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT);
484 data &= ~(PCI_CACHELINE_MASK << PCI_CACHELINE_SHIFT);
485 data |= (PCI_DFLT_LTNCY << PCI_LATTIMER_SHIFT);
486 data |= (linesz << PCI_CACHELINE_SHIFT);
487 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG, data);
488
489 data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCIR_ROMADDR);
490 data &= ~1;
491 pci_conf_write(pa->pa_pc, pa->pa_tag, PCIR_ROMADDR, data);
492
493 if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
494 pa->pa_intrline, &ih)) {
495 printf("%s: couldn't map interrupt\n", isp->isp_name);
496 free(isp->isp_param, M_DEVBUF);
497 return;
498 }
499 intrstr = pci_intr_string(pa->pa_pc, ih);
500 if (intrstr == NULL)
501 intrstr = "<I dunno>";
502 pcs->pci_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO,
503 isp_pci_intr, isp);
504 if (pcs->pci_ih == NULL) {
505 printf("%s: couldn't establish interrupt at %s\n",
506 isp->isp_name, intrstr);
507 free(isp->isp_param, M_DEVBUF);
508 return;
509 }
510
511 printf("%s: interrupting at %s\n", isp->isp_name, intrstr);
512
513 if (IS_FC(isp)) {
514 DEFAULT_NODEWWN(isp) = 0x400000007F000002;
515 }
516
517 isp->isp_confopts = self->dv_cfdata->cf_flags;
518 ISP_LOCK(isp);
519 isp->isp_osinfo.no_mbox_ints = 1;
520 isp_reset(isp);
521 if (isp->isp_state != ISP_RESETSTATE) {
522 ISP_UNLOCK(isp);
523 free(isp->isp_param, M_DEVBUF);
524 return;
525 }
526 ENABLE_INTS(isp);
527 isp_init(isp);
528 if (isp->isp_state != ISP_INITSTATE) {
529 isp_uninit(isp);
530 ISP_UNLOCK(isp);
531 free(isp->isp_param, M_DEVBUF);
532 return;
533 }
534 /*
535 * Do platform attach.
536 */
537 ISP_UNLOCK(isp);
538 isp_attach(isp);
539 if (isp->isp_state != ISP_RUNSTATE) {
540 ISP_LOCK(isp);
541 isp_uninit(isp);
542 free(isp->isp_param, M_DEVBUF);
543 ISP_UNLOCK(isp);
544 }
545 }
546
547 static u_int16_t
548 isp_pci_rd_reg(isp, regoff)
549 struct ispsoftc *isp;
550 int regoff;
551 {
552 u_int16_t rv;
553 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
554 int offset, oldconf = 0;
555
556 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
557 /*
558 * We will assume that someone has paused the RISC processor.
559 */
560 oldconf = isp_pci_rd_reg(isp, BIU_CONF1);
561 isp_pci_wr_reg(isp, BIU_CONF1, oldconf | BIU_PCI_CONF1_SXP);
562 delay(250);
563 }
564 offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
565 offset += (regoff & 0xff);
566 rv = bus_space_read_2(pcs->pci_st, pcs->pci_sh, offset);
567 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
568 isp_pci_wr_reg(isp, BIU_CONF1, oldconf);
569 delay(250);
570 }
571 return (rv);
572 }
573
574 static void
575 isp_pci_wr_reg(isp, regoff, val)
576 struct ispsoftc *isp;
577 int regoff;
578 u_int16_t val;
579 {
580 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
581 int offset, oldconf = 0;
582
583 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
584 /*
585 * We will assume that someone has paused the RISC processor.
586 */
587 oldconf = isp_pci_rd_reg(isp, BIU_CONF1);
588 isp_pci_wr_reg(isp, BIU_CONF1, oldconf | BIU_PCI_CONF1_SXP);
589 delay(250);
590 }
591 offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
592 offset += (regoff & 0xff);
593 bus_space_write_2(pcs->pci_st, pcs->pci_sh, offset, val);
594 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
595 isp_pci_wr_reg(isp, BIU_CONF1, oldconf);
596 delay(250);
597 }
598 }
599
600 #if !(defined(ISP_DISABLE_1080_SUPPORT) && defined(ISP_DISABLE_12160_SUPPORT))
601 static u_int16_t
602 isp_pci_rd_reg_1080(isp, regoff)
603 struct ispsoftc *isp;
604 int regoff;
605 {
606 u_int16_t rv, oc = 0;
607 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
608 int offset;
609
610 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
611 u_int16_t tc;
612 /*
613 * We will assume that someone has paused the RISC processor.
614 */
615 oc = isp_pci_rd_reg(isp, BIU_CONF1);
616 tc = oc & ~BIU_PCI1080_CONF1_DMA;
617 if (IS_1280(isp)) {
618 if (regoff & SXP_BANK1_SELECT)
619 tc |= BIU_PCI1080_CONF1_SXP0;
620 else
621 tc |= BIU_PCI1080_CONF1_SXP1;
622 } else {
623 tc |= BIU_PCI1080_CONF1_SXP0;
624 }
625 isp_pci_wr_reg(isp, BIU_CONF1, tc);
626 delay(250);
627 } else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {
628 oc = isp_pci_rd_reg(isp, BIU_CONF1);
629 isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_DMA);
630 delay(250);
631 }
632 offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
633 offset += (regoff & 0xff);
634 rv = bus_space_read_2(pcs->pci_st, pcs->pci_sh, offset);
635 /*
636 * Okay, because BIU_CONF1 is always nonzero
637 */
638 if (oc) {
639 isp_pci_wr_reg(isp, BIU_CONF1, oc);
640 delay(250);
641 }
642 return (rv);
643 }
644
645 static void
646 isp_pci_wr_reg_1080(isp, regoff, val)
647 struct ispsoftc *isp;
648 int regoff;
649 u_int16_t val;
650 {
651 u_int16_t oc = 0;
652 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
653 int offset;
654
655 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
656 u_int16_t tc;
657 /*
658 * We will assume that someone has paused the RISC processor.
659 */
660 oc = isp_pci_rd_reg(isp, BIU_CONF1);
661 tc = oc & ~BIU_PCI1080_CONF1_DMA;
662 if (IS_1280(isp)) {
663 if (regoff & SXP_BANK1_SELECT)
664 tc |= BIU_PCI1080_CONF1_SXP0;
665 else
666 tc |= BIU_PCI1080_CONF1_SXP1;
667 } else {
668 tc |= BIU_PCI1080_CONF1_SXP0;
669 }
670 isp_pci_wr_reg(isp, BIU_CONF1, tc);
671 delay(250);
672 } else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {
673 oc = isp_pci_rd_reg(isp, BIU_CONF1);
674 isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_DMA);
675 delay(250);
676 }
677 offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
678 offset += (regoff & 0xff);
679 bus_space_write_2(pcs->pci_st, pcs->pci_sh, offset, val);
680 /*
681 * Okay, because BIU_CONF1 is always nonzero
682 */
683 if (oc) {
684 isp_pci_wr_reg(isp, BIU_CONF1, oc);
685 delay(250);
686 }
687 }
688 #endif
689
690 static int
691 isp_pci_mbxdma(isp)
692 struct ispsoftc *isp;
693 {
694 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
695 bus_dma_tag_t dmat = pcs->pci_dmat;
696 bus_dma_segment_t sg;
697 bus_size_t len;
698 fcparam *fcp;
699 int rs, i;
700
701 if (isp->isp_rquest_dma) /* been here before? */
702 return (0);
703
704 len = isp->isp_maxcmds * sizeof (XS_T);
705 isp->isp_xflist = (XS_T **) malloc(len, M_DEVBUF, M_WAITOK);
706 if (isp->isp_xflist == NULL) {
707 isp_prt(isp, ISP_LOGERR, "cannot malloc xflist array");
708 return (1);
709 }
710 bzero(isp->isp_xflist, len);
711 len = isp->isp_maxcmds * sizeof (bus_dmamap_t);
712 pcs->pci_xfer_dmap = (bus_dmamap_t *) malloc(len, M_DEVBUF, M_WAITOK);
713 if (pcs->pci_xfer_dmap == NULL) {
714 free(isp->isp_xflist, M_DEVBUF);
715 isp->isp_xflist = NULL;
716 isp_prt(isp, ISP_LOGERR, "cannot malloc dma map array");
717 return (1);
718 }
719 for (i = 0; i < isp->isp_maxcmds; i++) {
720 if (bus_dmamap_create(dmat, MAXPHYS, (MAXPHYS / NBPG) + 1,
721 MAXPHYS, 0, BUS_DMA_NOWAIT, &pcs->pci_xfer_dmap[i])) {
722 isp_prt(isp, ISP_LOGERR, "cannot create dma maps");
723 break;
724 }
725 }
726 if (i < isp->isp_maxcmds) {
727 while (--i >= 0) {
728 bus_dmamap_destroy(dmat, pcs->pci_xfer_dmap[i]);
729 }
730 free(isp->isp_xflist, M_DEVBUF);
731 free(pcs->pci_xfer_dmap, M_DEVBUF);
732 isp->isp_xflist = NULL;
733 pcs->pci_xfer_dmap = NULL;
734 return (1);
735 }
736
737 /*
738 * Allocate and map the request queue.
739 */
740 len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp));
741 if (bus_dmamem_alloc(dmat, len, NBPG, 0, &sg, 1, &rs, BUS_DMA_NOWAIT) ||
742 bus_dmamem_map(pcs->pci_dmat, &sg, rs, len,
743 (caddr_t *)&isp->isp_rquest, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
744 goto dmafail;
745 }
746
747 if (bus_dmamap_create(dmat, len, 1, len, 0, BUS_DMA_NOWAIT,
748 &pcs->pci_rquest_dmap) || bus_dmamap_load(dmat,
749 pcs->pci_rquest_dmap, (caddr_t)isp->isp_rquest, len, NULL,
750 BUS_DMA_NOWAIT)) {
751 goto dmafail;
752 }
753
754 isp->isp_rquest_dma = pcs->pci_rquest_dmap->dm_segs[0].ds_addr;
755
756 /*
757 * Allocate and map the result queue.
758 */
759 len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp));
760 if (bus_dmamem_alloc(dmat, len, NBPG, 0, &sg, 1, &rs, BUS_DMA_NOWAIT) ||
761 bus_dmamem_map(dmat, &sg, rs, len, (caddr_t *)&isp->isp_result,
762 BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
763 goto dmafail;
764 }
765 if (bus_dmamap_create(dmat, len, 1, len, 0, BUS_DMA_NOWAIT,
766 &pcs->pci_result_dmap) || bus_dmamap_load(pcs->pci_dmat,
767 pcs->pci_result_dmap, (caddr_t)isp->isp_result, len, NULL,
768 BUS_DMA_NOWAIT)) {
769 goto dmafail;
770 }
771 isp->isp_result_dma = pcs->pci_result_dmap->dm_segs[0].ds_addr;
772
773 if (IS_SCSI(isp)) {
774 return (0);
775 }
776
777 fcp = isp->isp_param;
778 len = ISP2100_SCRLEN;
779 if (bus_dmamem_alloc(dmat, len, NBPG, 0, &sg, 1, &rs, BUS_DMA_NOWAIT) ||
780 bus_dmamem_map(dmat, &sg, rs, len, (caddr_t *)&fcp->isp_scratch,
781 BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
782 goto dmafail;
783 }
784 if (bus_dmamap_create(dmat, len, 1, len, 0, BUS_DMA_NOWAIT,
785 &pcs->pci_scratch_dmap) || bus_dmamap_load(dmat,
786 pcs->pci_scratch_dmap, (caddr_t)fcp->isp_scratch, len, NULL,
787 BUS_DMA_NOWAIT)) {
788 goto dmafail;
789 }
790 fcp->isp_scdma = pcs->pci_scratch_dmap->dm_segs[0].ds_addr;
791 return (0);
792 dmafail:
793 isp_prt(isp, ISP_LOGERR, "mailbox dma setup failure");
794 for (i = 0; i < isp->isp_maxcmds; i++) {
795 bus_dmamap_destroy(dmat, pcs->pci_xfer_dmap[i]);
796 }
797 free(isp->isp_xflist, M_DEVBUF);
798 free(pcs->pci_xfer_dmap, M_DEVBUF);
799 isp->isp_xflist = NULL;
800 pcs->pci_xfer_dmap = NULL;
801 return (1);
802 }
803
804 static int
805 isp_pci_dmasetup(isp, xs, rq, iptrp, optr)
806 struct ispsoftc *isp;
807 struct scsipi_xfer *xs;
808 ispreq_t *rq;
809 u_int16_t *iptrp;
810 u_int16_t optr;
811 {
812 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
813 bus_dmamap_t dmap;
814 ispcontreq_t *crq;
815 int segcnt, seg, error, ovseg, seglim, drq;
816
817 dmap = pcs->pci_xfer_dmap[isp_handle_index(rq->req_handle)];
818
819 if (xs->datalen == 0) {
820 rq->req_seg_count = 1;
821 goto mbxsync;
822 }
823 if (xs->xs_control & XS_CTL_DATA_IN) {
824 drq = REQFLAG_DATA_IN;
825 } else {
826 drq = REQFLAG_DATA_OUT;
827 }
828
829 if (IS_FC(isp)) {
830 seglim = ISP_RQDSEG_T2;
831 ((ispreqt2_t *)rq)->req_totalcnt = xs->datalen;
832 ((ispreqt2_t *)rq)->req_flags |= drq;
833 } else {
834 rq->req_flags |= drq;
835 if (XS_CDBLEN(xs) > 12) {
836 seglim = 0;
837 } else {
838 seglim = ISP_RQDSEG;
839 }
840 }
841 error = bus_dmamap_load(pcs->pci_dmat, dmap, xs->data, xs->datalen,
842 NULL, xs->xs_control & XS_CTL_NOSLEEP ?
843 BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
844 if (error) {
845 XS_SETERR(xs, HBA_BOTCH);
846 return (CMD_COMPLETE);
847 }
848
849 segcnt = dmap->dm_nsegs;
850
851 for (seg = 0, rq->req_seg_count = 0;
852 seg < segcnt && rq->req_seg_count < seglim;
853 seg++, rq->req_seg_count++) {
854 if (IS_FC(isp)) {
855 ispreqt2_t *rq2 = (ispreqt2_t *)rq;
856 rq2->req_dataseg[rq2->req_seg_count].ds_count =
857 dmap->dm_segs[seg].ds_len;
858 rq2->req_dataseg[rq2->req_seg_count].ds_base =
859 dmap->dm_segs[seg].ds_addr;
860 } else {
861 rq->req_dataseg[rq->req_seg_count].ds_count =
862 dmap->dm_segs[seg].ds_len;
863 rq->req_dataseg[rq->req_seg_count].ds_base =
864 dmap->dm_segs[seg].ds_addr;
865 }
866 }
867
868 if (seg == segcnt)
869 goto dmasync;
870
871 do {
872 crq = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, *iptrp);
873 *iptrp = ISP_NXT_QENTRY(*iptrp, RQUEST_QUEUE_LEN(isp));
874 if (*iptrp == optr) {
875 isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow++");
876 bus_dmamap_unload(pcs->pci_dmat, dmap);
877 XS_SETERR(xs, HBA_BOTCH);
878 return (CMD_EAGAIN);
879 }
880 rq->req_header.rqs_entry_count++;
881 bzero((void *)crq, sizeof (*crq));
882 crq->req_header.rqs_entry_count = 1;
883 crq->req_header.rqs_entry_type = RQSTYPE_DATASEG;
884
885 for (ovseg = 0; seg < segcnt && ovseg < ISP_CDSEG;
886 rq->req_seg_count++, seg++, ovseg++) {
887 crq->req_dataseg[ovseg].ds_count =
888 dmap->dm_segs[seg].ds_len;
889 crq->req_dataseg[ovseg].ds_base =
890 dmap->dm_segs[seg].ds_addr;
891 }
892 } while (seg < segcnt);
893
894 dmasync:
895 bus_dmamap_sync(pcs->pci_dmat, dmap, 0, dmap->dm_mapsize,
896 (xs->xs_control & XS_CTL_DATA_IN) ? BUS_DMASYNC_PREREAD :
897 BUS_DMASYNC_PREWRITE);
898
899 mbxsync:
900 ISP_SWIZZLE_REQUEST(isp, rq);
901 bus_dmamap_sync(pcs->pci_dmat, pcs->pci_rquest_dmap, 0,
902 pcs->pci_rquest_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
903 return (CMD_QUEUED);
904 }
905
906 static int
907 isp_pci_intr(arg)
908 void *arg;
909 {
910 int rv;
911 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)arg;
912 bus_dmamap_sync(pcs->pci_dmat, pcs->pci_result_dmap, 0,
913 pcs->pci_result_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD);
914 pcs->pci_isp.isp_osinfo.onintstack = 1;
915 rv = isp_intr(arg);
916 pcs->pci_isp.isp_osinfo.onintstack = 0;
917 return (rv);
918 }
919
920 static void
921 isp_pci_dmateardown(isp, xs, handle)
922 struct ispsoftc *isp;
923 struct scsipi_xfer *xs;
924 u_int32_t handle;
925 {
926 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
927 bus_dmamap_t dmap = pcs->pci_xfer_dmap[isp_handle_index(handle)];
928 bus_dmamap_sync(pcs->pci_dmat, dmap, 0, dmap->dm_mapsize,
929 xs->xs_control & XS_CTL_DATA_IN ?
930 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
931 bus_dmamap_unload(pcs->pci_dmat, dmap);
932 }
933
934 static void
935 isp_pci_reset1(isp)
936 struct ispsoftc *isp;
937 {
938 /* Make sure the BIOS is disabled */
939 isp_pci_wr_reg(isp, HCCR, PCI_HCCR_CMD_BIOS);
940 }
941
942 static void
943 isp_pci_dumpregs(isp, msg)
944 struct ispsoftc *isp;
945 const char *msg;
946 {
947 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
948 if (msg)
949 printf("%s: %s\n", isp->isp_name, msg);
950 if (IS_SCSI(isp))
951 printf(" biu_conf1=%x", ISP_READ(isp, BIU_CONF1));
952 else
953 printf(" biu_csr=%x", ISP_READ(isp, BIU2100_CSR));
954 printf(" biu_icr=%x biu_isr=%x biu_sema=%x ", ISP_READ(isp, BIU_ICR),
955 ISP_READ(isp, BIU_ISR), ISP_READ(isp, BIU_SEMA));
956 printf("risc_hccr=%x\n", ISP_READ(isp, HCCR));
957
958
959 if (IS_SCSI(isp)) {
960 ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
961 printf(" cdma_conf=%x cdma_sts=%x cdma_fifostat=%x\n",
962 ISP_READ(isp, CDMA_CONF), ISP_READ(isp, CDMA_STATUS),
963 ISP_READ(isp, CDMA_FIFO_STS));
964 printf(" ddma_conf=%x ddma_sts=%x ddma_fifostat=%x\n",
965 ISP_READ(isp, DDMA_CONF), ISP_READ(isp, DDMA_STATUS),
966 ISP_READ(isp, DDMA_FIFO_STS));
967 printf(" sxp_int=%x sxp_gross=%x sxp(scsi_ctrl)=%x\n",
968 ISP_READ(isp, SXP_INTERRUPT),
969 ISP_READ(isp, SXP_GROSS_ERR),
970 ISP_READ(isp, SXP_PINS_CTRL));
971 ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
972 }
973 printf(" mbox regs: %x %x %x %x %x\n",
974 ISP_READ(isp, OUTMAILBOX0), ISP_READ(isp, OUTMAILBOX1),
975 ISP_READ(isp, OUTMAILBOX2), ISP_READ(isp, OUTMAILBOX3),
976 ISP_READ(isp, OUTMAILBOX4));
977 printf(" PCI Status Command/Status=%x\n",
978 pci_conf_read(pcs->pci_pc, pcs->pci_tag, PCI_COMMAND_STATUS_REG));
979 }
980