isp_pci.c revision 1.53 1 /* $NetBSD: isp_pci.c,v 1.53 2000/08/01 23:55:14 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 if (oneshot) {
455 oneshot = 0;
456 isp_prt(isp, ISP_LOGCONFIG, vstring,
457 ISP_PLATFORM_VERSION_MAJOR, ISP_PLATFORM_VERSION_MINOR,
458 ISP_CORE_VERSION_MAJOR, ISP_CORE_VERSION_MINOR);
459 }
460
461 isp->isp_revision = rev;
462
463 /*
464 * Make sure that command register set sanely.
465 */
466 data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
467 data |= PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_INVALIDATE_ENABLE;
468
469 /*
470 * Not so sure about these- but I think it's important that they get
471 * enabled......
472 */
473 data |= PCI_COMMAND_PARITY_ENABLE | PCI_COMMAND_SERR_ENABLE;
474 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, data);
475
476 /*
477 * Make sure that the latency timer, cache line size,
478 * and ROM is disabled.
479 */
480 data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
481 data &= ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT);
482 data &= ~(PCI_CACHELINE_MASK << PCI_CACHELINE_SHIFT);
483 data |= (PCI_DFLT_LTNCY << PCI_LATTIMER_SHIFT);
484 data |= (linesz << PCI_CACHELINE_SHIFT);
485 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG, data);
486
487 data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCIR_ROMADDR);
488 data &= ~1;
489 pci_conf_write(pa->pa_pc, pa->pa_tag, PCIR_ROMADDR, data);
490
491 if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
492 pa->pa_intrline, &ih)) {
493 printf("%s: couldn't map interrupt\n", isp->isp_name);
494 free(isp->isp_param, M_DEVBUF);
495 return;
496 }
497 intrstr = pci_intr_string(pa->pa_pc, ih);
498 if (intrstr == NULL)
499 intrstr = "<I dunno>";
500 pcs->pci_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO,
501 isp_pci_intr, isp);
502 if (pcs->pci_ih == NULL) {
503 printf("%s: couldn't establish interrupt at %s\n",
504 isp->isp_name, intrstr);
505 free(isp->isp_param, M_DEVBUF);
506 return;
507 }
508
509 printf("%s: interrupting at %s\n", isp->isp_name, intrstr);
510
511 if (IS_FC(isp)) {
512 DEFAULT_NODEWWN(isp) = 0x400000007F000002;
513 }
514
515 isp->isp_confopts = self->dv_cfdata->cf_flags;
516 ISP_LOCK(isp);
517 isp->isp_osinfo.no_mbox_ints = 1;
518 isp_reset(isp);
519 if (isp->isp_state != ISP_RESETSTATE) {
520 ISP_UNLOCK(isp);
521 free(isp->isp_param, M_DEVBUF);
522 return;
523 }
524 ENABLE_INTS(isp);
525 isp_init(isp);
526 if (isp->isp_state != ISP_INITSTATE) {
527 isp_uninit(isp);
528 ISP_UNLOCK(isp);
529 free(isp->isp_param, M_DEVBUF);
530 return;
531 }
532 /*
533 * Do platform attach.
534 */
535 ISP_UNLOCK(isp);
536 isp_attach(isp);
537 if (isp->isp_state != ISP_RUNSTATE) {
538 ISP_LOCK(isp);
539 isp_uninit(isp);
540 free(isp->isp_param, M_DEVBUF);
541 ISP_UNLOCK(isp);
542 }
543 }
544
545 static u_int16_t
546 isp_pci_rd_reg(isp, regoff)
547 struct ispsoftc *isp;
548 int regoff;
549 {
550 u_int16_t rv;
551 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
552 int offset, oldconf = 0;
553
554 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
555 /*
556 * We will assume that someone has paused the RISC processor.
557 */
558 oldconf = isp_pci_rd_reg(isp, BIU_CONF1);
559 isp_pci_wr_reg(isp, BIU_CONF1, oldconf | BIU_PCI_CONF1_SXP);
560 delay(250);
561 }
562 offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
563 offset += (regoff & 0xff);
564 rv = bus_space_read_2(pcs->pci_st, pcs->pci_sh, offset);
565 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
566 isp_pci_wr_reg(isp, BIU_CONF1, oldconf);
567 delay(250);
568 }
569 return (rv);
570 }
571
572 static void
573 isp_pci_wr_reg(isp, regoff, val)
574 struct ispsoftc *isp;
575 int regoff;
576 u_int16_t val;
577 {
578 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
579 int offset, oldconf = 0;
580
581 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
582 /*
583 * We will assume that someone has paused the RISC processor.
584 */
585 oldconf = isp_pci_rd_reg(isp, BIU_CONF1);
586 isp_pci_wr_reg(isp, BIU_CONF1, oldconf | BIU_PCI_CONF1_SXP);
587 delay(250);
588 }
589 offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
590 offset += (regoff & 0xff);
591 bus_space_write_2(pcs->pci_st, pcs->pci_sh, offset, val);
592 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
593 isp_pci_wr_reg(isp, BIU_CONF1, oldconf);
594 delay(250);
595 }
596 }
597
598 #if !(defined(ISP_DISABLE_1080_SUPPORT) && defined(ISP_DISABLE_12160_SUPPORT))
599 static u_int16_t
600 isp_pci_rd_reg_1080(isp, regoff)
601 struct ispsoftc *isp;
602 int regoff;
603 {
604 u_int16_t rv, oc = 0;
605 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
606 int offset;
607
608 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
609 u_int16_t tc;
610 /*
611 * We will assume that someone has paused the RISC processor.
612 */
613 oc = isp_pci_rd_reg(isp, BIU_CONF1);
614 tc = oc & ~BIU_PCI1080_CONF1_DMA;
615 if (IS_1280(isp)) {
616 if (regoff & SXP_BANK1_SELECT)
617 tc |= BIU_PCI1080_CONF1_SXP0;
618 else
619 tc |= BIU_PCI1080_CONF1_SXP1;
620 } else {
621 tc |= BIU_PCI1080_CONF1_SXP0;
622 }
623 isp_pci_wr_reg(isp, BIU_CONF1, tc);
624 delay(250);
625 } else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {
626 oc = isp_pci_rd_reg(isp, BIU_CONF1);
627 isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_DMA);
628 delay(250);
629 }
630 offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
631 offset += (regoff & 0xff);
632 rv = bus_space_read_2(pcs->pci_st, pcs->pci_sh, offset);
633 /*
634 * Okay, because BIU_CONF1 is always nonzero
635 */
636 if (oc) {
637 isp_pci_wr_reg(isp, BIU_CONF1, oc);
638 delay(250);
639 }
640 return (rv);
641 }
642
643 static void
644 isp_pci_wr_reg_1080(isp, regoff, val)
645 struct ispsoftc *isp;
646 int regoff;
647 u_int16_t val;
648 {
649 u_int16_t oc = 0;
650 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
651 int offset;
652
653 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
654 u_int16_t tc;
655 /*
656 * We will assume that someone has paused the RISC processor.
657 */
658 oc = isp_pci_rd_reg(isp, BIU_CONF1);
659 tc = oc & ~BIU_PCI1080_CONF1_DMA;
660 if (IS_1280(isp)) {
661 if (regoff & SXP_BANK1_SELECT)
662 tc |= BIU_PCI1080_CONF1_SXP0;
663 else
664 tc |= BIU_PCI1080_CONF1_SXP1;
665 } else {
666 tc |= BIU_PCI1080_CONF1_SXP0;
667 }
668 isp_pci_wr_reg(isp, BIU_CONF1, tc);
669 delay(250);
670 } else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {
671 oc = isp_pci_rd_reg(isp, BIU_CONF1);
672 isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_DMA);
673 delay(250);
674 }
675 offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
676 offset += (regoff & 0xff);
677 bus_space_write_2(pcs->pci_st, pcs->pci_sh, offset, val);
678 /*
679 * Okay, because BIU_CONF1 is always nonzero
680 */
681 if (oc) {
682 isp_pci_wr_reg(isp, BIU_CONF1, oc);
683 delay(250);
684 }
685 }
686 #endif
687
688 static int
689 isp_pci_mbxdma(isp)
690 struct ispsoftc *isp;
691 {
692 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
693 bus_dma_tag_t dmat = pcs->pci_dmat;
694 bus_dma_segment_t sg;
695 bus_size_t len;
696 fcparam *fcp;
697 int rs, i;
698
699 if (isp->isp_rquest_dma) /* been here before? */
700 return (0);
701
702 len = isp->isp_maxcmds * sizeof (XS_T);
703 isp->isp_xflist = (XS_T **) malloc(len, M_DEVBUF, M_WAITOK);
704 if (isp->isp_xflist == NULL) {
705 isp_prt(isp, ISP_LOGERR, "cannot malloc xflist array");
706 return (1);
707 }
708 bzero(isp->isp_xflist, len);
709 len = isp->isp_maxcmds * sizeof (bus_dmamap_t);
710 pcs->pci_xfer_dmap = (bus_dmamap_t *) malloc(len, M_DEVBUF, M_WAITOK);
711 if (pcs->pci_xfer_dmap == NULL) {
712 free(isp->isp_xflist, M_DEVBUF);
713 isp->isp_xflist = NULL;
714 isp_prt(isp, ISP_LOGERR, "cannot malloc dma map array");
715 return (1);
716 }
717 for (i = 0; i < isp->isp_maxcmds; i++) {
718 if (bus_dmamap_create(dmat, MAXPHYS, (MAXPHYS / NBPG) + 1,
719 MAXPHYS, 0, BUS_DMA_NOWAIT, &pcs->pci_xfer_dmap[i])) {
720 isp_prt(isp, ISP_LOGERR, "cannot create dma maps");
721 break;
722 }
723 }
724 if (i < isp->isp_maxcmds) {
725 while (--i >= 0) {
726 bus_dmamap_destroy(dmat, pcs->pci_xfer_dmap[i]);
727 }
728 free(isp->isp_xflist, M_DEVBUF);
729 free(pcs->pci_xfer_dmap, M_DEVBUF);
730 isp->isp_xflist = NULL;
731 pcs->pci_xfer_dmap = NULL;
732 return (1);
733 }
734
735 /*
736 * Allocate and map the request queue.
737 */
738 len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp));
739 if (bus_dmamem_alloc(dmat, len, NBPG, 0, &sg, 1, &rs, BUS_DMA_NOWAIT) ||
740 bus_dmamem_map(pcs->pci_dmat, &sg, rs, len,
741 (caddr_t *)&isp->isp_rquest, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
742 goto dmafail;
743 }
744
745 if (bus_dmamap_create(dmat, len, 1, len, 0, BUS_DMA_NOWAIT,
746 &pcs->pci_rquest_dmap) || bus_dmamap_load(dmat,
747 pcs->pci_rquest_dmap, (caddr_t)isp->isp_rquest, len, NULL,
748 BUS_DMA_NOWAIT)) {
749 goto dmafail;
750 }
751
752 isp->isp_rquest_dma = pcs->pci_rquest_dmap->dm_segs[0].ds_addr;
753
754 /*
755 * Allocate and map the result queue.
756 */
757 len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp));
758 if (bus_dmamem_alloc(dmat, len, NBPG, 0, &sg, 1, &rs, BUS_DMA_NOWAIT) ||
759 bus_dmamem_map(dmat, &sg, rs, len, (caddr_t *)&isp->isp_result,
760 BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
761 goto dmafail;
762 }
763 if (bus_dmamap_create(dmat, len, 1, len, 0, BUS_DMA_NOWAIT,
764 &pcs->pci_result_dmap) || bus_dmamap_load(pcs->pci_dmat,
765 pcs->pci_result_dmap, (caddr_t)isp->isp_result, len, NULL,
766 BUS_DMA_NOWAIT)) {
767 goto dmafail;
768 }
769 isp->isp_result_dma = pcs->pci_result_dmap->dm_segs[0].ds_addr;
770
771 if (IS_SCSI(isp)) {
772 return (0);
773 }
774
775 fcp = isp->isp_param;
776 len = ISP2100_SCRLEN;
777 if (bus_dmamem_alloc(dmat, len, NBPG, 0, &sg, 1, &rs, BUS_DMA_NOWAIT) ||
778 bus_dmamem_map(dmat, &sg, rs, len, (caddr_t *)&fcp->isp_scratch,
779 BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
780 goto dmafail;
781 }
782 if (bus_dmamap_create(dmat, len, 1, len, 0, BUS_DMA_NOWAIT,
783 &pcs->pci_scratch_dmap) || bus_dmamap_load(dmat,
784 pcs->pci_scratch_dmap, (caddr_t)fcp->isp_scratch, len, NULL,
785 BUS_DMA_NOWAIT)) {
786 goto dmafail;
787 }
788 fcp->isp_scdma = pcs->pci_scratch_dmap->dm_segs[0].ds_addr;
789 return (0);
790 dmafail:
791 isp_prt(isp, ISP_LOGERR, "mailbox dma setup failure");
792 for (i = 0; i < isp->isp_maxcmds; i++) {
793 bus_dmamap_destroy(dmat, pcs->pci_xfer_dmap[i]);
794 }
795 free(isp->isp_xflist, M_DEVBUF);
796 free(pcs->pci_xfer_dmap, M_DEVBUF);
797 isp->isp_xflist = NULL;
798 pcs->pci_xfer_dmap = NULL;
799 return (1);
800 }
801
802 static int
803 isp_pci_dmasetup(isp, xs, rq, iptrp, optr)
804 struct ispsoftc *isp;
805 struct scsipi_xfer *xs;
806 ispreq_t *rq;
807 u_int16_t *iptrp;
808 u_int16_t optr;
809 {
810 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
811 bus_dmamap_t dmap;
812 ispcontreq_t *crq;
813 int segcnt, seg, error, ovseg, seglim, drq;
814
815 dmap = pcs->pci_xfer_dmap[isp_handle_index(rq->req_handle)];
816
817 if (xs->datalen == 0) {
818 rq->req_seg_count = 1;
819 goto mbxsync;
820 }
821 if (xs->xs_control & XS_CTL_DATA_IN) {
822 drq = REQFLAG_DATA_IN;
823 } else {
824 drq = REQFLAG_DATA_OUT;
825 }
826
827 if (IS_FC(isp)) {
828 seglim = ISP_RQDSEG_T2;
829 ((ispreqt2_t *)rq)->req_totalcnt = xs->datalen;
830 ((ispreqt2_t *)rq)->req_flags |= drq;
831 } else {
832 rq->req_flags |= drq;
833 if (XS_CDBLEN(xs) > 12) {
834 seglim = 0;
835 } else {
836 seglim = ISP_RQDSEG;
837 }
838 }
839 error = bus_dmamap_load(pcs->pci_dmat, dmap, xs->data, xs->datalen,
840 NULL, xs->xs_control & XS_CTL_NOSLEEP ?
841 BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
842 if (error) {
843 XS_SETERR(xs, HBA_BOTCH);
844 return (CMD_COMPLETE);
845 }
846
847 segcnt = dmap->dm_nsegs;
848
849 for (seg = 0, rq->req_seg_count = 0;
850 seg < segcnt && rq->req_seg_count < seglim;
851 seg++, rq->req_seg_count++) {
852 if (IS_FC(isp)) {
853 ispreqt2_t *rq2 = (ispreqt2_t *)rq;
854 rq2->req_dataseg[rq2->req_seg_count].ds_count =
855 dmap->dm_segs[seg].ds_len;
856 rq2->req_dataseg[rq2->req_seg_count].ds_base =
857 dmap->dm_segs[seg].ds_addr;
858 } else {
859 rq->req_dataseg[rq->req_seg_count].ds_count =
860 dmap->dm_segs[seg].ds_len;
861 rq->req_dataseg[rq->req_seg_count].ds_base =
862 dmap->dm_segs[seg].ds_addr;
863 }
864 }
865
866 if (seg == segcnt)
867 goto dmasync;
868
869 do {
870 crq = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, *iptrp);
871 *iptrp = ISP_NXT_QENTRY(*iptrp, RQUEST_QUEUE_LEN(isp));
872 if (*iptrp == optr) {
873 isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow++");
874 bus_dmamap_unload(pcs->pci_dmat, dmap);
875 XS_SETERR(xs, HBA_BOTCH);
876 return (CMD_EAGAIN);
877 }
878 rq->req_header.rqs_entry_count++;
879 bzero((void *)crq, sizeof (*crq));
880 crq->req_header.rqs_entry_count = 1;
881 crq->req_header.rqs_entry_type = RQSTYPE_DATASEG;
882
883 for (ovseg = 0; seg < segcnt && ovseg < ISP_CDSEG;
884 rq->req_seg_count++, seg++, ovseg++) {
885 crq->req_dataseg[ovseg].ds_count =
886 dmap->dm_segs[seg].ds_len;
887 crq->req_dataseg[ovseg].ds_base =
888 dmap->dm_segs[seg].ds_addr;
889 }
890 } while (seg < segcnt);
891
892 dmasync:
893 bus_dmamap_sync(pcs->pci_dmat, dmap, 0, dmap->dm_mapsize,
894 (xs->xs_control & XS_CTL_DATA_IN) ? BUS_DMASYNC_PREREAD :
895 BUS_DMASYNC_PREWRITE);
896
897 mbxsync:
898 ISP_SWIZZLE_REQUEST(isp, rq);
899 bus_dmamap_sync(pcs->pci_dmat, pcs->pci_rquest_dmap, 0,
900 pcs->pci_rquest_dmap->dm_mapsize, BUS_DMASYNC_PREWRITE);
901 return (CMD_QUEUED);
902 }
903
904 static int
905 isp_pci_intr(arg)
906 void *arg;
907 {
908 int rv;
909 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)arg;
910 bus_dmamap_sync(pcs->pci_dmat, pcs->pci_result_dmap, 0,
911 pcs->pci_result_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD);
912 pcs->pci_isp.isp_osinfo.onintstack = 1;
913 rv = isp_intr(arg);
914 pcs->pci_isp.isp_osinfo.onintstack = 0;
915 return (rv);
916 }
917
918 static void
919 isp_pci_dmateardown(isp, xs, handle)
920 struct ispsoftc *isp;
921 struct scsipi_xfer *xs;
922 u_int32_t handle;
923 {
924 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
925 bus_dmamap_t dmap = pcs->pci_xfer_dmap[isp_handle_index(handle)];
926 bus_dmamap_sync(pcs->pci_dmat, dmap, 0, dmap->dm_mapsize,
927 xs->xs_control & XS_CTL_DATA_IN ?
928 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
929 bus_dmamap_unload(pcs->pci_dmat, dmap);
930 }
931
932 static void
933 isp_pci_reset1(isp)
934 struct ispsoftc *isp;
935 {
936 /* Make sure the BIOS is disabled */
937 isp_pci_wr_reg(isp, HCCR, PCI_HCCR_CMD_BIOS);
938 }
939
940 static void
941 isp_pci_dumpregs(isp, msg)
942 struct ispsoftc *isp;
943 const char *msg;
944 {
945 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
946 if (msg)
947 printf("%s: %s\n", isp->isp_name, msg);
948 if (IS_SCSI(isp))
949 printf(" biu_conf1=%x", ISP_READ(isp, BIU_CONF1));
950 else
951 printf(" biu_csr=%x", ISP_READ(isp, BIU2100_CSR));
952 printf(" biu_icr=%x biu_isr=%x biu_sema=%x ", ISP_READ(isp, BIU_ICR),
953 ISP_READ(isp, BIU_ISR), ISP_READ(isp, BIU_SEMA));
954 printf("risc_hccr=%x\n", ISP_READ(isp, HCCR));
955
956
957 if (IS_SCSI(isp)) {
958 ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
959 printf(" cdma_conf=%x cdma_sts=%x cdma_fifostat=%x\n",
960 ISP_READ(isp, CDMA_CONF), ISP_READ(isp, CDMA_STATUS),
961 ISP_READ(isp, CDMA_FIFO_STS));
962 printf(" ddma_conf=%x ddma_sts=%x ddma_fifostat=%x\n",
963 ISP_READ(isp, DDMA_CONF), ISP_READ(isp, DDMA_STATUS),
964 ISP_READ(isp, DDMA_FIFO_STS));
965 printf(" sxp_int=%x sxp_gross=%x sxp(scsi_ctrl)=%x\n",
966 ISP_READ(isp, SXP_INTERRUPT),
967 ISP_READ(isp, SXP_GROSS_ERR),
968 ISP_READ(isp, SXP_PINS_CTRL));
969 ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
970 }
971 printf(" mbox regs: %x %x %x %x %x\n",
972 ISP_READ(isp, OUTMAILBOX0), ISP_READ(isp, OUTMAILBOX1),
973 ISP_READ(isp, OUTMAILBOX2), ISP_READ(isp, OUTMAILBOX3),
974 ISP_READ(isp, OUTMAILBOX4));
975 printf(" PCI Status Command/Status=%x\n",
976 pci_conf_read(pcs->pci_pc, pcs->pci_tag, PCI_COMMAND_STATUS_REG));
977 }
978