xref: /freebsd/sys/dev/isp/isp_pci.c (revision 6e8394b8baa7d5d9153ab90de6824bcd19b3b4e1)
1 /* $Id: isp_pci.c,v 1.21 1999/05/09 17:07:07 peter Exp $ */
2 /* release_5_11_99 */
3 /*
4  * PCI specific probe and attach routines for Qlogic ISP SCSI adapters.
5  * FreeBSD Version.
6  *
7  *---------------------------------------
8  * Copyright (c) 1997, 1998 by Matthew Jacob
9  * NASA/Ames Research Center
10  * All rights reserved.
11  *---------------------------------------
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice immediately at the beginning of the file, without modification,
18  *    this list of conditions, and the following disclaimer.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the
21  *    documentation and/or other materials provided with the distribution.
22  * 3. The name of the author may not be used to endorse or promote products
23  *    derived from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
29  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  */
37 #include <dev/isp/isp_freebsd.h>
38 #include <dev/isp/asm_pci.h>
39 #include <sys/malloc.h>
40 #include <vm/vm.h>
41 #include <vm/pmap.h>
42 #include <vm/vm_extern.h>
43 
44 
45 #include <pci/pcireg.h>
46 #include <pci/pcivar.h>
47 
48 #if	__FreeBSD_version >= 300004
49 #include <machine/bus_memio.h>
50 #include <machine/bus_pio.h>
51 #include <machine/bus.h>
52 #endif
53 
54 #include "opt_isp.h"
55 
56 static u_int16_t isp_pci_rd_reg __P((struct ispsoftc *, int));
57 static void isp_pci_wr_reg __P((struct ispsoftc *, int, u_int16_t));
58 #ifndef ISP_DISABLE_1080_SUPPORT
59 static u_int16_t isp_pci_rd_reg_1080 __P((struct ispsoftc *, int));
60 static void isp_pci_wr_reg_1080 __P((struct ispsoftc *, int, u_int16_t));
61 #endif
62 static int isp_pci_mbxdma __P((struct ispsoftc *));
63 static int isp_pci_dmasetup __P((struct ispsoftc *, ISP_SCSI_XFER_T *,
64 	ispreq_t *, u_int8_t *, u_int8_t));
65 #if	__FreeBSD_version >= 300004
66 static void
67 isp_pci_dmateardown __P((struct ispsoftc *, ISP_SCSI_XFER_T *, u_int32_t));
68 #define	PROBETYPE	const char *
69 #else
70 typedef u_int16_t pci_port_t;
71 #define	isp_pci_dmateardown	NULL
72 #define	PROBETYPE	char *
73 #endif
74 
75 static void isp_pci_reset1 __P((struct ispsoftc *));
76 static void isp_pci_dumpregs __P((struct ispsoftc *));
77 
78 #ifndef ISP_DISABLE_1020_SUPPORT
79 static struct ispmdvec mdvec = {
80 	isp_pci_rd_reg,
81 	isp_pci_wr_reg,
82 	isp_pci_mbxdma,
83 	isp_pci_dmasetup,
84 	isp_pci_dmateardown,
85 	NULL,
86 	isp_pci_reset1,
87 	isp_pci_dumpregs,
88 	ISP_RISC_CODE,
89 	ISP_CODE_LENGTH,
90 	ISP_CODE_ORG,
91 	ISP_CODE_VERSION,
92 	BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64,
93 	0
94 };
95 #endif
96 
97 #ifndef ISP_DISABLE_1080_SUPPORT
98 static struct ispmdvec mdvec_1080 = {
99 	isp_pci_rd_reg_1080,
100 	isp_pci_wr_reg_1080,
101 	isp_pci_mbxdma,
102 	isp_pci_dmasetup,
103 	isp_pci_dmateardown,
104 	NULL,
105 	isp_pci_reset1,
106 	isp_pci_dumpregs,
107 	ISP1080_RISC_CODE,
108 	ISP1080_CODE_LENGTH,
109 	ISP1080_CODE_ORG,
110 	ISP1080_CODE_VERSION,
111 	BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64,
112 	0
113 };
114 #endif
115 
116 #ifndef ISP_DISABLE_2100_SUPPORT
117 static struct ispmdvec mdvec_2100 = {
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 	ISP2100_RISC_CODE,
127 	ISP2100_CODE_LENGTH,
128 	ISP2100_CODE_ORG,
129 	ISP2100_CODE_VERSION,
130 	0,			/* Irrelevant to the 2100 */
131 	0
132 };
133 #endif
134 
135 #ifndef	SCSI_ISP_PREFER_MEM_MAP
136 #ifdef	__alpha__
137 #define	SCSI_ISP_PREFER_MEM_MAP	0
138 #else
139 #define	SCSI_ISP_PREFER_MEM_MAP	1
140 #endif
141 #endif
142 
143 #ifndef	PCIM_CMD_INVEN
144 #define	PCIM_CMD_INVEN			0x10
145 #endif
146 #ifndef	PCIM_CMD_BUSMASTEREN
147 #define	PCIM_CMD_BUSMASTEREN		0x0004
148 #endif
149 #ifndef	PCIM_CMD_PERRESPEN
150 #define	PCIM_CMD_PERRESPEN		0x0040
151 #endif
152 #ifndef	PCIM_CMD_SEREN
153 #define	PCIM_CMD_SEREN			0x0100
154 #endif
155 
156 #ifndef	PCIR_COMMAND
157 #define	PCIR_COMMAND			0x04
158 #endif
159 
160 #ifndef	PCIR_CACHELNSZ
161 #define	PCIR_CACHELNSZ			0x0c
162 #endif
163 
164 #ifndef	PCIR_LATTIMER
165 #define	PCIR_LATTIMER			0x0d
166 #endif
167 
168 #ifndef	PCIR_ROMADDR
169 #define	PCIR_ROMADDR			0x30
170 #endif
171 
172 #ifndef	PCI_VENDOR_QLOGIC
173 #define	PCI_VENDOR_QLOGIC	0x1077
174 #endif
175 
176 #ifndef	PCI_PRODUCT_QLOGIC_ISP1020
177 #define	PCI_PRODUCT_QLOGIC_ISP1020	0x1020
178 #endif
179 
180 #ifndef	PCI_PRODUCT_QLOGIC_ISP1080
181 #define	PCI_PRODUCT_QLOGIC_ISP1080	0x1080
182 #endif
183 
184 #ifndef	PCI_PRODUCT_QLOGIC_ISP1240
185 #define	PCI_PRODUCT_QLOGIC_ISP1240	0x1240
186 #endif
187 
188 #ifndef	PCI_PRODUCT_QLOGIC_ISP2100
189 #define	PCI_PRODUCT_QLOGIC_ISP2100	0x2100
190 #endif
191 
192 #define	PCI_QLOGIC_ISP	((PCI_PRODUCT_QLOGIC_ISP1020 << 16) | PCI_VENDOR_QLOGIC)
193 
194 #define	PCI_QLOGIC_ISP1080	\
195 	((PCI_PRODUCT_QLOGIC_ISP1080 << 16) | PCI_VENDOR_QLOGIC)
196 
197 #define	PCI_QLOGIC_ISP1240	\
198 	((PCI_PRODUCT_QLOGIC_ISP1240 << 16) | PCI_VENDOR_QLOGIC)
199 
200 #define	PCI_QLOGIC_ISP2100	\
201 	((PCI_PRODUCT_QLOGIC_ISP2100 << 16) | PCI_VENDOR_QLOGIC)
202 
203 #define	IO_MAP_REG	0x10
204 #define	MEM_MAP_REG	0x14
205 
206 #define	PCI_DFLT_LTNCY	0x40
207 #define	PCI_DFLT_LNSZ	0x10
208 
209 static PROBETYPE isp_pci_probe __P((pcici_t tag, pcidi_t type));
210 static void isp_pci_attach __P((pcici_t config_d, int unit));
211 
212 /* This distinguishing define is not right, but it does work */
213 
214 #if	__FreeBSD_version < 300004
215 #define	IO_SPACE_MAPPING	0
216 #define	MEM_SPACE_MAPPING	1
217 typedef int bus_space_tag_t;
218 typedef u_long bus_space_handle_t;
219 typedef unsigned int            __uintptr_t;
220 typedef __uintptr_t     uintptr_t;
221 #ifdef __alpha__
222 #define	bus_space_read_2(st, sh, offset)	\
223 	alpha_mb(),
224 	(st == IO_SPACE_MAPPING)? \
225 		inw((pci_port_t)sh + offset) : readw((pci_port_t)sh + offset)
226 #define	bus_space_write_2(st, sh, offset, val)	\
227 	((st == IO_SPACE_MAPPING)? outw((pci_port_t)sh + offset, val) : \
228                 writew((pci_port_t)sh + offset, val)), alpha_mb()
229 #else
230 #define	bus_space_read_2(st, sh, offset)	\
231 	(st == IO_SPACE_MAPPING)? \
232 		inw((pci_port_t)sh + offset) : *((u_int16_t *)(uintptr_t)sh)
233 #define	bus_space_write_2(st, sh, offset, val)	\
234 	if (st == IO_SPACE_MAPPING) outw((pci_port_t)sh + offset, val); else \
235 		*((u_int16_t *)(uintptr_t)sh) = val
236 #endif
237 #else
238 #ifdef __alpha__
239 #define IO_SPACE_MAPPING	ALPHA_BUS_SPACE_IO
240 #define MEM_SPACE_MAPPING	ALPHA_BUS_SPACE_MEM
241 #else
242 #define IO_SPACE_MAPPING	I386_BUS_SPACE_IO
243 #define MEM_SPACE_MAPPING	I386_BUS_SPACE_MEM
244 #endif
245 #endif
246 
247 struct isp_pcisoftc {
248 	struct ispsoftc			pci_isp;
249         pcici_t				pci_id;
250 	bus_space_tag_t			pci_st;
251 	bus_space_handle_t		pci_sh;
252 	int16_t				pci_poff[_NREG_BLKS];
253 #if	__FreeBSD_version >= 300004
254 	bus_dma_tag_t			parent_dmat;
255 	bus_dma_tag_t			cntrol_dmat;
256 	bus_dmamap_t			cntrol_dmap;
257 	bus_dmamap_t			dmaps[MAXISPREQUEST];
258 #endif
259 };
260 
261 static u_long ispunit;
262 
263 static struct pci_device isp_pci_driver = {
264 	"isp",
265 	isp_pci_probe,
266 	isp_pci_attach,
267 	&ispunit,
268 	NULL
269 };
270 COMPAT_PCI_DRIVER (isp_pci, isp_pci_driver);
271 
272 
273 static PROBETYPE
274 isp_pci_probe(pcici_t tag, pcidi_t type)
275 {
276 	static int oneshot = 1;
277 	char *x;
278 
279         switch (type) {
280 #ifndef	ISP_DISABLE_1020_SUPPORT
281 	case PCI_QLOGIC_ISP:
282 		x = "Qlogic ISP 1020/1040 PCI SCSI Adapter";
283 		break;
284 #endif
285 #ifndef	ISP_DISABLE_1080_SUPPORT
286 	case PCI_QLOGIC_ISP1080:
287 		x = "Qlogic ISP 1080 PCI SCSI Adapter";
288 		break;
289 	case PCI_QLOGIC_ISP1240:
290 		x = "Qlogic ISP 1240 PCI SCSI Adapter";
291 		break;
292 #endif
293 #ifndef	ISP_DISABLE_2100_SUPPORT
294 	case PCI_QLOGIC_ISP2100:
295 		x = "Qlogic ISP 2100 PCI FC-AL Adapter";
296 		break;
297 #endif
298 	default:
299 		return (NULL);
300 	}
301 	if (oneshot) {
302 		oneshot = 0;
303 		printf("%s Version %d.%d, Core Version %d.%d\n", PVS,
304 		    ISP_PLATFORM_VERSION_MAJOR, ISP_PLATFORM_VERSION_MINOR,
305 		    ISP_CORE_VERSION_MAJOR, ISP_CORE_VERSION_MINOR);
306 	}
307 	return (x);
308 }
309 
310 
311 static void
312 isp_pci_attach(pcici_t config_id, int unit)
313 {
314 	int mapped;
315 	pci_port_t io_port;
316 	u_int32_t data, linesz, psize, basetype;
317 	struct isp_pcisoftc *pcs;
318 	struct ispsoftc *isp;
319 	vm_offset_t vaddr, paddr;
320 	struct ispmdvec *mdvp;
321 	ISP_LOCKVAL_DECL;
322 
323 
324 	pcs = malloc(sizeof (struct isp_pcisoftc), M_DEVBUF, M_NOWAIT);
325 	if (pcs == NULL) {
326 		printf("isp%d: cannot allocate softc\n", unit);
327 		return;
328 	}
329 	bzero(pcs, sizeof (struct isp_pcisoftc));
330 
331 	vaddr = paddr = NULL;
332 	mapped = 0;
333 	linesz = PCI_DFLT_LNSZ;
334 	/*
335 	 * Note that pci_conf_read is a 32 bit word aligned function.
336 	 */
337 	data = pci_conf_read(config_id, PCIR_COMMAND);
338 #if	SCSI_ISP_PREFER_MEM_MAP == 1
339 	if (mapped == 0 && (data & PCI_COMMAND_MEM_ENABLE)) {
340 		if (pci_map_mem(config_id, MEM_MAP_REG, &vaddr, &paddr)) {
341 			pcs->pci_st = MEM_SPACE_MAPPING;
342 			pcs->pci_sh = vaddr;
343 			mapped++;
344 		}
345 	}
346 	if (mapped == 0 && (data & PCI_COMMAND_IO_ENABLE)) {
347 		if (pci_map_port(config_id, PCI_MAP_REG_START, &io_port)) {
348 			pcs->pci_st = IO_SPACE_MAPPING;
349 			pcs->pci_sh = io_port;
350 			mapped++;
351 		}
352 	}
353 #else
354 	if (mapped == 0 && (data & PCI_COMMAND_IO_ENABLE)) {
355 		if (pci_map_port(config_id, PCI_MAP_REG_START, &io_port)) {
356 			pcs->pci_st = IO_SPACE_MAPPING;
357 			pcs->pci_sh = io_port;
358 			mapped++;
359 		}
360 	}
361 	if (mapped == 0 && (data & PCI_COMMAND_MEM_ENABLE)) {
362 		if (pci_map_mem(config_id, MEM_MAP_REG, &vaddr, &paddr)) {
363 			pcs->pci_st = MEM_SPACE_MAPPING;
364 			pcs->pci_sh = vaddr;
365 			mapped++;
366 		}
367 	}
368 #endif
369 	if (mapped == 0) {
370 		printf("isp%d: unable to map any ports!\n", unit);
371 		free(pcs, M_DEVBUF);
372 		return;
373 	}
374 	printf("isp%d: using %s space register mapping\n", unit,
375 	    pcs->pci_st == IO_SPACE_MAPPING? "I/O" : "Memory");
376 
377 	data = pci_conf_read(config_id, PCI_ID_REG);
378 	pcs->pci_poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF;
379 	pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS_OFF;
380 	pcs->pci_poff[SXP_BLOCK >> _BLK_REG_SHFT] = PCI_SXP_REGS_OFF;
381 	pcs->pci_poff[RISC_BLOCK >> _BLK_REG_SHFT] = PCI_RISC_REGS_OFF;
382 	pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = DMA_REGS_OFF;
383 	/*
384  	 * GCC!
385 	 */
386 	mdvp = &mdvec;
387 	basetype = ISP_HA_SCSI_UNKNOWN;
388 	psize = sizeof (sdparam);
389 #ifndef	ISP_DISABLE_1020_SUPPORT
390 	if (data == PCI_QLOGIC_ISP) {
391 		mdvp = &mdvec;
392 		basetype = ISP_HA_SCSI_UNKNOWN;
393 		psize = sizeof (sdparam);
394 	}
395 #endif
396 #ifndef	ISP_DISABLE_1080_SUPPORT
397 	if (data == PCI_QLOGIC_ISP1080) {
398 		mdvp = &mdvec_1080;
399 		basetype = ISP_HA_SCSI_1080;
400 		psize = sizeof (sdparam);
401 		pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
402 		    ISP1080_DMA_REGS_OFF;
403 	}
404 	if (data == PCI_QLOGIC_ISP1240) {
405 		mdvp = &mdvec_1080;
406 		basetype = ISP_HA_SCSI_12X0;
407 		psize = 2 * sizeof (sdparam);
408 		pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
409 		    ISP1080_DMA_REGS_OFF;
410 	}
411 #endif
412 #ifndef	ISP_DISABLE_2100_SUPPORT
413 	if (data == PCI_QLOGIC_ISP2100) {
414 		mdvp = &mdvec_2100;
415 		basetype = ISP_HA_FC_2100;
416 		psize = sizeof (fcparam);
417 		pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
418 		    PCI_MBOX_REGS2100_OFF;
419 		data = pci_conf_read(config_id, PCI_CLASS_REG);
420 		if ((data & 0xff) < 3) {
421 			/*
422 			 * XXX: Need to get the actual revision
423 			 * XXX: number of the 2100 FB. At any rate,
424 			 * XXX: lower cache line size for early revision
425 			 * XXX; boards.
426 			 */
427 			linesz = 1;
428 		}
429 	}
430 #endif
431 	isp = &pcs->pci_isp;
432 	isp->isp_param = malloc(psize, M_DEVBUF, M_NOWAIT);
433 	if (isp->isp_param == NULL) {
434 		printf("isp%d: cannot allocate parameter data\n", unit);
435 		return;
436 	}
437 	bzero(isp->isp_param, psize);
438 	isp->isp_mdvec = mdvp;
439 	isp->isp_type = basetype;
440 #if	__FreeBSD_version >= 300006
441 	(void) snprintf(isp->isp_name, sizeof (isp->isp_name), "isp%d", unit);
442 #else
443 	(void) sprintf(isp->isp_name, "isp%d", unit);
444 #endif
445 	isp->isp_osinfo.unit = unit;
446 
447 #if	__FreeBSD_version >= 300004
448 	ISP_LOCK(isp);
449 
450 	/*
451 	 * Make sure that SERR, PERR, WRITE INVALIDATE and BUSMASTER
452 	 * are set.
453 	 */
454 	data = pci_cfgread(config_id, PCIR_COMMAND, 2);
455 	data |=	PCIM_CMD_SEREN		|
456 		PCIM_CMD_PERRESPEN	|
457 		PCIM_CMD_BUSMASTEREN	|
458 		PCIM_CMD_INVEN;
459 	pci_cfgwrite(config_id, PCIR_COMMAND, 2, data);
460 
461 	/*
462 	 * Make sure the CACHE Line Size register is set sensibly.
463 	 */
464 	data = pci_cfgread(config_id, PCIR_CACHELNSZ, 1);
465 	if (data != linesz) {
466 		data = PCI_DFLT_LNSZ;
467 		printf("%s: set PCI line size to %d\n", isp->isp_name, data);
468 		pci_cfgwrite(config_id, PCIR_CACHELNSZ, data, 1);
469 	}
470 
471 	/*
472 	 * Make sure the Latency Timer is sane.
473 	 */
474 	data = pci_cfgread(config_id, PCIR_LATTIMER, 1);
475 	if (data < PCI_DFLT_LTNCY) {
476 		data = PCI_DFLT_LTNCY;
477 		printf("%s: set PCI latency to %d\n", isp->isp_name, data);
478 		pci_cfgwrite(config_id, PCIR_LATTIMER, data, 1);
479 	}
480 
481 	/*
482 	 * Make sure we've disabled the ROM.
483 	 */
484 	data = pci_cfgread(config_id, PCIR_ROMADDR, 4);
485 	data &= ~1;
486 	pci_cfgwrite(config_id, PCIR_ROMADDR, data, 4);
487 
488 	ISP_UNLOCK(isp);
489 
490 	if (bus_dma_tag_create(NULL, 0, 0, BUS_SPACE_MAXADDR_32BIT,
491 	    BUS_SPACE_MAXADDR, NULL, NULL, 1<<24,
492 	    255, 1<<24, 0, &pcs->parent_dmat) != 0) {
493 		printf("%s: could not create master dma tag\n", isp->isp_name);
494 		free(pcs, M_DEVBUF);
495 		return;
496 	}
497 #else
498 	ISP_LOCK(isp);
499 	data = pci_conf_read(config_id, PCIR_COMMAND);
500 	data |=	PCIM_CMD_SEREN		|
501 		PCIM_CMD_PERRESPEN	|
502 		PCIM_CMD_BUSMASTEREN	|
503 		PCIM_CMD_INVEN;
504 	pci_conf_write(config_id, PCIR_COMMAND, data);
505 	data = pci_conf_read(config_id, PCIR_CACHELNSZ);
506 	if ((data & ~0xffff) != ((PCI_DFLT_LTNCY << 8) | linesz)) {
507 		data &= ~0xffff;
508 		data |= (PCI_DFLT_LTNCY << 8) | linesz;
509 		pci_conf_write(config_id, PCIR_CACHELNSZ, data);
510 		printf("%s: set PCI line size to %d\n", isp->isp_name, linesz);
511 		printf("%s: set PCI latency to %d\n", isp->isp_name,
512 		    PCI_DFLT_LTNCY);
513 	}
514 
515 	/*
516 	 * Make sure we've disabled the ROM.
517 	 */
518 	data = pci_conf_read(config_id, PCIR_ROMADDR);
519 	data &= ~1;
520 	pci_conf_write(config_id, PCIR_ROMADDR, data);
521 	ISP_UNLOCK(isp);
522 #endif
523 	if (pci_map_int(config_id, (void (*)(void *))isp_intr,
524 	    (void *)isp, &IMASK) == 0) {
525 		printf("%s: could not map interrupt\n", isp->isp_name);
526 		free(pcs, M_DEVBUF);
527 		return;
528 	}
529 
530 	pcs->pci_id = config_id;
531 #ifdef	SCSI_ISP_NO_FWLOAD_MASK
532 	if (SCSI_ISP_NO_FWLOAD_MASK && (SCSI_ISP_NO_FWLOAD_MASK & (1 << unit)))
533 		isp->isp_confopts |= ISP_CFG_NORELOAD;
534 #endif
535 #ifdef	SCSI_ISP_NO_NVRAM_MASK
536 	if (SCSI_ISP_NO_NVRAM_MASK && (SCSI_ISP_NO_NVRAM_MASK & (1 << unit))) {
537 		printf("%s: ignoring NVRAM\n", isp->isp_name);
538 		isp->isp_confopts |= ISP_CFG_NONVRAM;
539 	}
540 #endif
541 	ISP_LOCK(isp);
542 	isp_reset(isp);
543 	if (isp->isp_state != ISP_RESETSTATE) {
544 		(void) pci_unmap_int(config_id);
545 		ISP_UNLOCK(isp);
546 		free(pcs, M_DEVBUF);
547 		return;
548 	}
549 	isp_init(isp);
550 	if (isp->isp_state != ISP_INITSTATE) {
551 		/* If we're a Fibre Channel Card, we allow deferred attach */
552 		if (isp->isp_type & ISP_HA_SCSI) {
553 			isp_uninit(isp);
554 			(void) pci_unmap_int(config_id); /* Does nothing */
555 			ISP_UNLOCK(isp);
556 			free(pcs, M_DEVBUF);
557 			return;
558 		}
559 	}
560 	isp_attach(isp);
561 	if (isp->isp_state != ISP_RUNSTATE) {
562 		/* If we're a Fibre Channel Card, we allow deferred attach */
563 		if (IS_SCSI(isp)) {
564 			isp_uninit(isp);
565 			(void) pci_unmap_int(config_id); /* Does nothing */
566 			ISP_UNLOCK(isp);
567 			free(pcs, M_DEVBUF);
568 			return;
569 		}
570 	}
571 	ISP_UNLOCK(isp);
572 #ifdef __alpha__
573 	/*
574 	 * THIS SHOULD NOT HAVE TO BE HERE
575 	 */
576 	alpha_register_pci_scsi(config_id->bus, config_id->slot, isp->isp_sim);
577 #endif
578 }
579 
580 static u_int16_t
581 isp_pci_rd_reg(isp, regoff)
582 	struct ispsoftc *isp;
583 	int regoff;
584 {
585 	u_int16_t rv;
586 	struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
587 	int offset, oldconf = 0;
588 
589 	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
590 		/*
591 		 * We will assume that someone has paused the RISC processor.
592 		 */
593 		oldconf = isp_pci_rd_reg(isp, BIU_CONF1);
594 		isp_pci_wr_reg(isp, BIU_CONF1, oldconf | BIU_PCI_CONF1_SXP);
595 	}
596 	offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
597 	offset += (regoff & 0xff);
598 	rv = bus_space_read_2(pcs->pci_st, pcs->pci_sh, offset);
599 	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
600 		isp_pci_wr_reg(isp, BIU_CONF1, oldconf);
601 	}
602 	return (rv);
603 }
604 
605 static void
606 isp_pci_wr_reg(isp, regoff, val)
607 	struct ispsoftc *isp;
608 	int regoff;
609 	u_int16_t val;
610 {
611 	struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
612 	int offset, oldconf = 0;
613 
614 	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
615 		/*
616 		 * We will assume that someone has paused the RISC processor.
617 		 */
618 		oldconf = isp_pci_rd_reg(isp, BIU_CONF1);
619 		isp_pci_wr_reg(isp, BIU_CONF1, oldconf | BIU_PCI_CONF1_SXP);
620 	}
621 	offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
622 	offset += (regoff & 0xff);
623 	bus_space_write_2(pcs->pci_st, pcs->pci_sh, offset, val);
624 	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
625 		isp_pci_wr_reg(isp, BIU_CONF1, oldconf);
626 	}
627 }
628 
629 #ifndef	ISP_DISABLE_1080_SUPPORT
630 static u_int16_t
631 isp_pci_rd_reg_1080(isp, regoff)
632 	struct ispsoftc *isp;
633 	int regoff;
634 {
635 	u_int16_t rv;
636 	struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
637 	int offset, oc = 0;
638 
639 	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
640 		/*
641 		 * We will assume that someone has paused the RISC processor.
642 		 */
643 		oc = isp_pci_rd_reg(isp, BIU_CONF1);
644 		isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_SXP);
645 	} else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {
646 		oc = isp_pci_rd_reg(isp, BIU_CONF1);
647 		isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_DMA);
648 	}
649 	offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
650 	offset += (regoff & 0xff);
651 	rv = bus_space_read_2(pcs->pci_st, pcs->pci_sh, offset);
652 	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||
653 	    ((regoff & _BLK_REG_MASK) == DMA_BLOCK)) {
654 		isp_pci_wr_reg(isp, BIU_CONF1, oc);
655 	}
656 	return (rv);
657 }
658 
659 static void
660 isp_pci_wr_reg_1080(isp, regoff, val)
661 	struct ispsoftc *isp;
662 	int regoff;
663 	u_int16_t val;
664 {
665 	struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
666 	int offset, oc = 0;
667 
668 	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
669 		/*
670 		 * We will assume that someone has paused the RISC processor.
671 		 */
672 		oc = isp_pci_rd_reg(isp, BIU_CONF1);
673 		isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_SXP);
674 	} else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {
675 		oc = isp_pci_rd_reg(isp, BIU_CONF1);
676 		isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_DMA);
677 	}
678 	offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
679 	offset += (regoff & 0xff);
680 	bus_space_write_2(pcs->pci_st, pcs->pci_sh, offset, val);
681 	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||
682 	    ((regoff & _BLK_REG_MASK) == DMA_BLOCK)) {
683 		isp_pci_wr_reg(isp, BIU_CONF1, oc);
684 	}
685 }
686 #endif
687 
688 
689 #if	__FreeBSD_version >= 300004
690 static void isp_map_rquest __P((void *, bus_dma_segment_t *, int, int));
691 static void isp_map_result __P((void *, bus_dma_segment_t *, int, int));
692 static void isp_map_fcscrt __P((void *, bus_dma_segment_t *, int, int));
693 
694 static void
695 isp_map_rquest(void *arg, bus_dma_segment_t *segs, int nseg, int error)
696 {
697 	struct ispsoftc *isp = (struct ispsoftc *) arg;
698 	isp->isp_rquest_dma = segs->ds_addr;
699 }
700 
701 static void
702 isp_map_result(void *arg, bus_dma_segment_t *segs, int nseg, int error)
703 {
704 	struct ispsoftc *isp = (struct ispsoftc *) arg;
705 	isp->isp_result_dma = segs->ds_addr;
706 }
707 
708 static void
709 isp_map_fcscrt(void *arg, bus_dma_segment_t *segs, int nseg, int error)
710 {
711 	struct ispsoftc *isp = (struct ispsoftc *) arg;
712 	fcparam *fcp = isp->isp_param;
713 	fcp->isp_scdma = segs->ds_addr;
714 }
715 
716 static int
717 isp_pci_mbxdma(struct ispsoftc *isp)
718 {
719 	struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp;
720 	caddr_t base;
721 	u_int32_t len;
722 	int i, error;
723 
724 	/*
725 	 * Allocate and map the request, result queues, plus FC scratch area.
726 	 */
727 	len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN);
728 	len += ISP_QUEUE_SIZE(RESULT_QUEUE_LEN);
729 	if (isp->isp_type & ISP_HA_FC) {
730 		len += ISP2100_SCRLEN;
731 	}
732 	if (bus_dma_tag_create(pci->parent_dmat, 0, 0, BUS_SPACE_MAXADDR,
733 	    BUS_SPACE_MAXADDR, NULL, NULL, len, 1, BUS_SPACE_MAXSIZE_32BIT,
734 	    0, &pci->cntrol_dmat) != 0) {
735 		printf("%s: cannot create a dma tag for control spaces\n",
736 		    isp->isp_name);
737 		return (1);
738 	}
739 	if (bus_dmamem_alloc(pci->cntrol_dmat, (void **)&base,
740 	    BUS_DMA_NOWAIT, &pci->cntrol_dmap) != 0) {
741 		printf("%s: cannot allocate %d bytes of CCB memory\n",
742 		    isp->isp_name, len);
743 		return (1);
744 	}
745 
746 	isp->isp_rquest = base;
747 	bus_dmamap_load(pci->cntrol_dmat, pci->cntrol_dmap, isp->isp_rquest,
748 	    ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN), isp_map_rquest, pci, 0);
749 
750 	isp->isp_result = base + ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN);
751 	bus_dmamap_load(pci->cntrol_dmat, pci->cntrol_dmap, isp->isp_result,
752 	    ISP_QUEUE_SIZE(RESULT_QUEUE_LEN), isp_map_result, pci, 0);
753 
754 	/*
755 	 * Use this opportunity to initialize/create data DMA maps.
756 	 */
757 	for (i = 0; i < MAXISPREQUEST; i++) {
758 		error = bus_dmamap_create(pci->parent_dmat, 0, &pci->dmaps[i]);
759 		if (error) {
760 			printf("%s: error %d creating mailbox DMA maps\n",
761 			    isp->isp_name, error);
762 			return (1);
763 		}
764 	}
765 
766 	if (isp->isp_type & ISP_HA_FC) {
767 		fcparam *fcp = (fcparam *) isp->isp_param;
768 		fcp->isp_scratch = base +
769 			ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN) +
770 			ISP_QUEUE_SIZE(RESULT_QUEUE_LEN);
771 		bus_dmamap_load(pci->cntrol_dmat, pci->cntrol_dmap,
772 		    fcp->isp_scratch, ISP2100_SCRLEN, isp_map_fcscrt, pci, 0);
773 	}
774 	return (0);
775 }
776 
777 static void dma2 __P((void *, bus_dma_segment_t *, int, int));
778 typedef struct {
779 	struct ispsoftc *isp;
780 	ISP_SCSI_XFER_T *ccb;
781 	ispreq_t *rq;
782 	u_int8_t *iptrp;
783 	u_int8_t optr;
784 	u_int error;
785 } mush_t;
786 
787 #define	MUSHERR_NOQENTRIES	-2
788 
789 static void
790 dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
791 {
792 	mush_t *mp;
793 	ISP_SCSI_XFER_T *ccb;
794 	struct ispsoftc *isp;
795 	struct isp_pcisoftc *pci;
796 	bus_dmamap_t *dp;
797 	bus_dma_segment_t *eseg;
798 	ispreq_t *rq;
799 	u_int8_t *iptrp;
800 	u_int8_t optr;
801 	ispcontreq_t *crq;
802 	int drq, seglim, datalen;
803 
804 	mp = (mush_t *) arg;
805 	if (error) {
806 		mp->error = error;
807 		return;
808 	}
809 
810 	isp = mp->isp;
811 	if (nseg < 1) {
812 		printf("%s: zero or negative segment count\n", isp->isp_name);
813 		mp->error = EFAULT;
814 		return;
815 	}
816 	ccb = mp->ccb;
817 	rq = mp->rq;
818 	iptrp = mp->iptrp;
819 	optr = mp->optr;
820 
821 	pci = (struct isp_pcisoftc *)isp;
822 	dp = &pci->dmaps[rq->req_handle - 1];
823 	if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
824 		bus_dmamap_sync(pci->parent_dmat, *dp, BUS_DMASYNC_PREREAD);
825 		drq = REQFLAG_DATA_IN;
826 	} else {
827 		bus_dmamap_sync(pci->parent_dmat, *dp, BUS_DMASYNC_PREWRITE);
828 		drq = REQFLAG_DATA_OUT;
829 	}
830 
831 	datalen = XS_XFRLEN(ccb);
832 	if (isp->isp_type & ISP_HA_FC) {
833 		seglim = ISP_RQDSEG_T2;
834 		((ispreqt2_t *)rq)->req_totalcnt = datalen;
835 		((ispreqt2_t *)rq)->req_flags |= drq;
836 	} else {
837 		seglim = ISP_RQDSEG;
838 		rq->req_flags |= drq;
839 	}
840 
841 	eseg = dm_segs + nseg;
842 
843 	while (datalen != 0 && rq->req_seg_count < seglim && dm_segs != eseg) {
844 		if (isp->isp_type & ISP_HA_FC) {
845 			ispreqt2_t *rq2 = (ispreqt2_t *)rq;
846 			rq2->req_dataseg[rq2->req_seg_count].ds_base =
847 			    dm_segs->ds_addr;
848 			rq2->req_dataseg[rq2->req_seg_count].ds_count =
849 			    dm_segs->ds_len;
850 		} else {
851 			rq->req_dataseg[rq->req_seg_count].ds_base =
852 				dm_segs->ds_addr;
853 			rq->req_dataseg[rq->req_seg_count].ds_count =
854 				dm_segs->ds_len;
855 		}
856 		datalen -= dm_segs->ds_len;
857 #if	0
858 		if (isp->isp_type & ISP_HA_FC) {
859 			ispreqt2_t *rq2 = (ispreqt2_t *)rq;
860 			printf("%s: seg0[%d] cnt 0x%x paddr 0x%08x\n",
861 			    isp->isp_name, rq->req_seg_count,
862 			    rq2->req_dataseg[rq2->req_seg_count].ds_count,
863 			    rq2->req_dataseg[rq2->req_seg_count].ds_base);
864 		} else {
865 			printf("%s: seg0[%d] cnt 0x%x paddr 0x%08x\n",
866 			    isp->isp_name, rq->req_seg_count,
867 			    rq->req_dataseg[rq->req_seg_count].ds_count,
868 			    rq->req_dataseg[rq->req_seg_count].ds_base);
869 		}
870 #endif
871 		rq->req_seg_count++;
872 		dm_segs++;
873 	}
874 
875 	while (datalen > 0 && dm_segs != eseg) {
876 		crq = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, *iptrp);
877 		*iptrp = ISP_NXT_QENTRY(*iptrp, RQUEST_QUEUE_LEN);
878 		if (*iptrp == optr) {
879 #if	0
880 			printf("%s: Request Queue Overflow++\n", isp->isp_name);
881 #endif
882 			mp->error = MUSHERR_NOQENTRIES;
883 			return;
884 		}
885 		rq->req_header.rqs_entry_count++;
886 		bzero((void *)crq, sizeof (*crq));
887 		crq->req_header.rqs_entry_count = 1;
888 		crq->req_header.rqs_entry_type = RQSTYPE_DATASEG;
889 
890 		seglim = 0;
891 		while (datalen > 0 && seglim < ISP_CDSEG && dm_segs != eseg) {
892 			crq->req_dataseg[seglim].ds_base =
893 			    dm_segs->ds_addr;
894 			crq->req_dataseg[seglim].ds_count =
895 			    dm_segs->ds_len;
896 #if	0
897 			printf("%s: seg%d[%d] cnt 0x%x paddr 0x%08x\n",
898 			    isp->isp_name, rq->req_header.rqs_entry_count-1,
899 			    seglim, crq->req_dataseg[seglim].ds_count,
900 			    crq->req_dataseg[seglim].ds_base);
901 #endif
902 			rq->req_seg_count++;
903 			dm_segs++;
904 			seglim++;
905 			datalen -= dm_segs->ds_len;
906 		}
907 	}
908 }
909 
910 static int
911 isp_pci_dmasetup(struct ispsoftc *isp, ISP_SCSI_XFER_T *ccb, ispreq_t *rq,
912 	u_int8_t *iptrp, u_int8_t optr)
913 {
914 	struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp;
915 	struct ccb_hdr *ccb_h;
916 	struct ccb_scsiio *csio;
917 	bus_dmamap_t *dp;
918 	mush_t mush, *mp;
919 
920 	csio = (struct ccb_scsiio *) ccb;
921 	ccb_h = &csio->ccb_h;
922 
923 	if ((ccb_h->flags & CAM_DIR_MASK) == CAM_DIR_NONE) {
924 		rq->req_seg_count = 1;
925 		return (CMD_QUEUED);
926 	}
927 	dp = &pci->dmaps[rq->req_handle - 1];
928 
929 	/*
930 	 * Do a virtual grapevine step to collect info for
931 	 * the callback dma allocation that we have to use...
932 	 */
933 	mp = &mush;
934 	mp->isp = isp;
935 	mp->ccb = ccb;
936 	mp->rq = rq;
937 	mp->iptrp = iptrp;
938 	mp->optr = optr;
939 	mp->error = 0;
940 
941 	if ((ccb_h->flags & CAM_SCATTER_VALID) == 0) {
942 		if ((ccb_h->flags & CAM_DATA_PHYS) == 0) {
943 			int error, s;
944 
945 			s = splsoftvm();
946 			error = bus_dmamap_load(pci->parent_dmat, *dp,
947 			    csio->data_ptr, csio->dxfer_len, dma2, mp, 0);
948 			if (error == EINPROGRESS) {
949 				bus_dmamap_unload(pci->parent_dmat, *dp);
950 				mp->error = EINVAL;
951 				printf("%s: deferred dma allocation not "
952 				    "supported\n", isp->isp_name);
953 			} else if (error && mp->error == 0) {
954 				mp->error = error;
955 			}
956 			splx(s);
957 		} else {
958 			/* Pointer to physical buffer */
959 			struct bus_dma_segment seg;
960 			seg.ds_addr = (bus_addr_t)csio->data_ptr;
961 			seg.ds_len = csio->dxfer_len;
962 			dma2(mp, &seg, 1, 0);
963 		}
964 	} else {
965 		struct bus_dma_segment *segs;
966 
967 		if ((ccb_h->flags & CAM_DATA_PHYS) != 0) {
968 			printf("%s: Physical segment pointers unsupported",
969 				isp->isp_name);
970 			mp->error = EINVAL;
971 		} else if ((ccb_h->flags & CAM_SG_LIST_PHYS) == 0) {
972 			printf("%s: Virtual segment addresses unsupported",
973 				isp->isp_name);
974 			mp->error = EINVAL;
975 		} else {
976 			/* Just use the segments provided */
977 			segs = (struct bus_dma_segment *) csio->data_ptr;
978 			dma2(mp, segs, csio->sglist_cnt, 0);
979 		}
980 	}
981 	if (mp->error) {
982 		int retval = CMD_COMPLETE;
983 		if (mp->error == MUSHERR_NOQENTRIES) {
984 			retval = CMD_EAGAIN;
985 			ccb_h->status = CAM_UNREC_HBA_ERROR;
986 		} else if (mp->error == EFBIG) {
987 			ccb_h->status = CAM_REQ_TOO_BIG;
988 		} else if (mp->error == EINVAL) {
989 			ccb_h->status = CAM_REQ_INVALID;
990 		} else {
991 			ccb_h->status = CAM_UNREC_HBA_ERROR;
992 		}
993 		return (retval);
994 	} else {
995 		return (CMD_QUEUED);
996 	}
997 }
998 
999 static void
1000 isp_pci_dmateardown(struct ispsoftc *isp, ISP_SCSI_XFER_T *ccb,
1001 	u_int32_t handle)
1002 {
1003 	struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp;
1004 	bus_dmamap_t *dp = &pci->dmaps[handle];
1005 
1006 	if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
1007 		bus_dmamap_sync(pci->parent_dmat, *dp, BUS_DMASYNC_POSTREAD);
1008 	} else {
1009 		bus_dmamap_sync(pci->parent_dmat, *dp, BUS_DMASYNC_POSTWRITE);
1010 	}
1011 	bus_dmamap_unload(pci->parent_dmat, *dp);
1012 }
1013 
1014 #else	/* __FreeBSD_version >= 300004 */
1015 
1016 
1017 static int
1018 isp_pci_mbxdma(struct ispsoftc *isp)
1019 {
1020 	struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp;
1021 	u_int32_t len;
1022 	int rseg;
1023 
1024 	/* XXXX CHECK FOR ALIGNMENT */
1025 	/*
1026 	 * Allocate and map the request queue.
1027 	 */
1028 	len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN);
1029 	isp->isp_rquest = malloc(len, M_DEVBUF, M_NOWAIT);
1030 	if (isp->isp_rquest == NULL) {
1031 		printf("%s: cannot malloc request queue\n", isp->isp_name);
1032 		return (1);
1033 	}
1034 	isp->isp_rquest_dma = vtophys(isp->isp_rquest);
1035 
1036 #if	0
1037 	printf("RQUEST=0x%x (0x%x)...", isp->isp_rquest, isp->isp_rquest_dma);
1038 #endif
1039 
1040 	/*
1041 	 * Allocate and map the result queue.
1042 	 */
1043 	len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN);
1044 	isp->isp_result = malloc(len, M_DEVBUF, M_NOWAIT);
1045 	if (isp->isp_result == NULL) {
1046 		free(isp->isp_rquest, M_DEVBUF);
1047 		printf("%s: cannot malloc result queue\n", isp->isp_name);
1048 		return (1);
1049 	}
1050 	isp->isp_result_dma = vtophys(isp->isp_result);
1051 #if	0
1052 	printf("RESULT=0x%x (0x%x)\n", isp->isp_result, isp->isp_result_dma);
1053 #endif
1054 	if (isp->isp_type & ISP_HA_FC) {
1055 		fcparam *fcp = isp->isp_param;
1056 		len = ISP2100_SCRLEN;
1057 		fcp->isp_scratch = (volatile caddr_t)
1058 		    malloc(ISP2100_SCRLEN, M_DEVBUF, M_NOWAIT);
1059 		if (fcp->isp_scratch == NULL) {
1060 			printf("%s: cannot alloc scratch\n", isp->isp_name);
1061 			return (1);
1062 		}
1063 		fcp->isp_scdma = vtophys(fcp->isp_scratch);
1064 	}
1065 	return (0);
1066 }
1067 
1068 static int
1069 isp_pci_dmasetup(struct ispsoftc *isp, ISP_SCSI_XFER_T *xs,
1070 	ispreq_t *rq, u_int8_t *iptrp, u_int8_t optr)
1071 {
1072 	struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp;
1073 	ispcontreq_t *crq;
1074 	vm_offset_t vaddr;
1075 	int drq, seglim;
1076 	u_int32_t paddr, nextpaddr, datalen, size, *ctrp;
1077 
1078 	if (xs->datalen == 0) {
1079 		rq->req_seg_count = 1;
1080 		return (CMD_QUEUED);
1081 	}
1082 
1083 	if (xs->flags & SCSI_DATA_IN) {
1084 		drq = REQFLAG_DATA_IN;
1085 	} else {
1086 		drq = REQFLAG_DATA_OUT;
1087 	}
1088 
1089 	if (isp->isp_type & ISP_HA_FC) {
1090 		seglim = ISP_RQDSEG_T2;
1091 		((ispreqt2_t *)rq)->req_totalcnt = XS_XFRLEN(xs);
1092 		((ispreqt2_t *)rq)->req_flags |= drq;
1093 	} else {
1094 		seglim = ISP_RQDSEG;
1095 		rq->req_flags |= drq;
1096 	}
1097 
1098 	datalen = XS_XFRLEN(xs);
1099 	vaddr = (vm_offset_t) xs->data;
1100 	paddr = vtophys(vaddr);
1101 
1102 	while (datalen != 0 && rq->req_seg_count < seglim) {
1103 		if (isp->isp_type & ISP_HA_FC) {
1104 			ispreqt2_t *rq2 = (ispreqt2_t *)rq;
1105 			rq2->req_dataseg[rq2->req_seg_count].ds_base = paddr;
1106 			ctrp = &rq2->req_dataseg[rq2->req_seg_count].ds_count;
1107 		} else {
1108 			rq->req_dataseg[rq->req_seg_count].ds_base = paddr;
1109 			ctrp = &rq->req_dataseg[rq->req_seg_count].ds_count;
1110 		}
1111 		nextpaddr = paddr;
1112 		*(ctrp) = 0;
1113 
1114 		while (datalen != 0 && paddr == nextpaddr) {
1115 			nextpaddr = (paddr & (~PAGE_MASK)) + PAGE_SIZE;
1116 			size = nextpaddr - paddr;
1117 			if (size > datalen)
1118 				size = datalen;
1119 			*(ctrp) += size;
1120 			vaddr += size;
1121 			datalen -= size;
1122 			if (datalen != 0)
1123 				paddr = vtophys(vaddr);
1124 
1125 		}
1126 #if	0
1127 		if (isp->isp_type & ISP_HA_FC) {
1128 			ispreqt2_t *rq2 = (ispreqt2_t *)rq;
1129 			printf("%s: seg0[%d] cnt 0x%x paddr 0x%08x\n",
1130 			    isp->isp_name, rq->req_seg_count,
1131 			    rq2->req_dataseg[rq2->req_seg_count].ds_count,
1132 			    rq2->req_dataseg[rq2->req_seg_count].ds_base);
1133 		} else {
1134 			printf("%s: seg0[%d] cnt 0x%x paddr 0x%08x\n",
1135 			    isp->isp_name, rq->req_seg_count,
1136 			    rq->req_dataseg[rq->req_seg_count].ds_count,
1137 			    rq->req_dataseg[rq->req_seg_count].ds_base);
1138 		}
1139 #endif
1140 		rq->req_seg_count++;
1141 	}
1142 
1143 
1144 
1145 	if (datalen == 0)
1146 		return (CMD_QUEUED);
1147 
1148 	paddr = vtophys(vaddr);
1149 	while (datalen > 0) {
1150 		crq = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, *iptrp);
1151 		*iptrp = ISP_NXT_QENTRY(*iptrp, RQUEST_QUEUE_LEN);
1152 		if (*iptrp == optr) {
1153 			printf("%s: Request Queue Overflow\n", isp->isp_name);
1154 			XS_SETERR(xs, HBA_BOTCH);
1155 			return (CMD_EAGAIN);
1156 		}
1157 		rq->req_header.rqs_entry_count++;
1158 		bzero((void *)crq, sizeof (*crq));
1159 		crq->req_header.rqs_entry_count = 1;
1160 		crq->req_header.rqs_entry_type = RQSTYPE_DATASEG;
1161 
1162 		for (seglim = 0; datalen != 0 && seglim < ISP_CDSEG; seglim++) {
1163 			crq->req_dataseg[seglim].ds_base = paddr;
1164 			ctrp = &crq->req_dataseg[seglim].ds_count;
1165 			*(ctrp) = 0;
1166 			nextpaddr = paddr;
1167 			while (datalen != 0 && paddr == nextpaddr) {
1168 				nextpaddr = (paddr & (~PAGE_MASK)) + PAGE_SIZE;
1169 				size = nextpaddr - paddr;
1170 				if (size > datalen)
1171 					size = datalen;
1172 				*(ctrp) += size;
1173 				vaddr += size;
1174 				datalen -= size;
1175 				if (datalen != 0)
1176 					paddr = vtophys(vaddr);
1177 			}
1178 #if	0
1179 			printf("%s: seg%d[%d] cnt 0x%x paddr 0x%08x\n",
1180 			    isp->isp_name, rq->req_header.rqs_entry_count-1,
1181 			    seglim, crq->req_dataseg[seglim].ds_count,
1182 			    crq->req_dataseg[seglim].ds_base);
1183 #endif
1184 			rq->req_seg_count++;
1185 		}
1186 	}
1187 
1188 	return (CMD_QUEUED);
1189 }
1190 #endif
1191 
1192 static void
1193 isp_pci_reset1(struct ispsoftc *isp)
1194 {
1195 	/* Make sure the BIOS is disabled */
1196 	isp_pci_wr_reg(isp, HCCR, PCI_HCCR_CMD_BIOS);
1197 }
1198 
1199 static void
1200 isp_pci_dumpregs(struct ispsoftc *isp)
1201 {
1202 	struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp;
1203 	printf("%s: PCI Status Command/Status=%lx\n", pci->pci_isp.isp_name,
1204 	    pci_conf_read(pci->pci_id, PCIR_COMMAND));
1205 }
1206