xref: /freebsd/sys/dev/isp/isp_pci.c (revision 601752d5a7bef087e755da5a2b158fa35cb51ccb)
1 /* $Id: isp_pci.c,v 1.18 1999/04/04 01:14:02 mjacob Exp $ */
2 /* release_4_3_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 	union {
260 		sdparam	_x;
261 		fcparam _y;
262 	} _z;
263 };
264 
265 static u_long ispunit;
266 
267 static struct pci_device isp_pci_driver = {
268 	"isp",
269 	isp_pci_probe,
270 	isp_pci_attach,
271 	&ispunit,
272 	NULL
273 };
274 DATA_SET (pcidevice_set, isp_pci_driver);
275 
276 
277 static PROBETYPE
278 isp_pci_probe(pcici_t tag, pcidi_t type)
279 {
280 	static int oneshot = 1;
281 	char *x;
282 
283         switch (type) {
284 #ifndef	ISP_DISABLE_1020_SUPPORT
285 	case PCI_QLOGIC_ISP:
286 		x = "Qlogic ISP 1020/1040 PCI SCSI Adapter";
287 		break;
288 #endif
289 #ifndef	ISP_DISABLE_1080_SUPPORT
290 	case PCI_QLOGIC_ISP1080:
291 #if	0
292 	case PCI_QLOGIC_ISP1240:	/* 1240 not ready yet */
293 #endif
294 		x = "Qlogic ISP 1080/1240 PCI SCSI Adapter";
295 		break;
296 #endif
297 #ifndef	ISP_DISABLE_2100_SUPPORT
298 	case PCI_QLOGIC_ISP2100:
299 		x = "Qlogic ISP 2100 PCI FC-AL Adapter";
300 		break;
301 #endif
302 	default:
303 		return (NULL);
304 	}
305 	if (oneshot) {
306 		oneshot = 0;
307 		printf("%s Version %d.%d, Core Version %d.%d\n", PVS,
308 		    ISP_PLATFORM_VERSION_MAJOR, ISP_PLATFORM_VERSION_MINOR,
309 		    ISP_CORE_VERSION_MAJOR, ISP_CORE_VERSION_MINOR);
310 	}
311 	return (x);
312 }
313 
314 
315 static void
316 isp_pci_attach(pcici_t config_id, int unit)
317 {
318 	int mapped;
319 	pci_port_t io_port;
320 	u_int32_t data, linesz;
321 	struct isp_pcisoftc *pcs;
322 	struct ispsoftc *isp;
323 	vm_offset_t vaddr, paddr;
324 	ISP_LOCKVAL_DECL;
325 
326 
327 	pcs = malloc(sizeof (struct isp_pcisoftc), M_DEVBUF, M_NOWAIT);
328 	if (pcs == NULL) {
329 		printf("isp%d: cannot allocate softc\n", unit);
330 		return;
331 	}
332 	bzero(pcs, sizeof (struct isp_pcisoftc));
333 
334 	vaddr = paddr = NULL;
335 	mapped = 0;
336 	linesz = PCI_DFLT_LNSZ;
337 	/*
338 	 * Note that pci_conf_read is a 32 bit word aligned function.
339 	 */
340 	data = pci_conf_read(config_id, PCIR_COMMAND);
341 #if	SCSI_ISP_PREFER_MEM_MAP == 1
342 	if (mapped == 0 && (data & PCI_COMMAND_MEM_ENABLE)) {
343 		if (pci_map_mem(config_id, MEM_MAP_REG, &vaddr, &paddr)) {
344 			pcs->pci_st = MEM_SPACE_MAPPING;
345 			pcs->pci_sh = vaddr;
346 			mapped++;
347 		}
348 	}
349 	if (mapped == 0 && (data & PCI_COMMAND_IO_ENABLE)) {
350 		if (pci_map_port(config_id, PCI_MAP_REG_START, &io_port)) {
351 			pcs->pci_st = IO_SPACE_MAPPING;
352 			pcs->pci_sh = io_port;
353 			mapped++;
354 		}
355 	}
356 #else
357 	if (mapped == 0 && (data & PCI_COMMAND_IO_ENABLE)) {
358 		if (pci_map_port(config_id, PCI_MAP_REG_START, &io_port)) {
359 			pcs->pci_st = IO_SPACE_MAPPING;
360 			pcs->pci_sh = io_port;
361 			mapped++;
362 		}
363 	}
364 	if (mapped == 0 && (data & PCI_COMMAND_MEM_ENABLE)) {
365 		if (pci_map_mem(config_id, MEM_MAP_REG, &vaddr, &paddr)) {
366 			pcs->pci_st = MEM_SPACE_MAPPING;
367 			pcs->pci_sh = vaddr;
368 			mapped++;
369 		}
370 	}
371 #endif
372 	if (mapped == 0) {
373 		printf("isp%d: unable to map any ports!\n", unit);
374 		free(pcs, M_DEVBUF);
375 		return;
376 	}
377 	printf("isp%d: using %s space register mapping\n", unit,
378 	    pcs->pci_st == IO_SPACE_MAPPING? "I/O" : "Memory");
379 
380 	isp = &pcs->pci_isp;
381 #if	__FreeBSD_version >= 300006
382 	(void) snprintf(isp->isp_name, sizeof (isp->isp_name), "isp%d", unit);
383 #else
384 	(void) sprintf(isp->isp_name, "isp%d", unit);
385 #endif
386 	isp->isp_osinfo.unit = unit;
387 
388 	data = pci_conf_read(config_id, PCI_ID_REG);
389 	pcs->pci_poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF;
390 	pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS_OFF;
391 	pcs->pci_poff[SXP_BLOCK >> _BLK_REG_SHFT] = PCI_SXP_REGS_OFF;
392 	pcs->pci_poff[RISC_BLOCK >> _BLK_REG_SHFT] = PCI_RISC_REGS_OFF;
393 	pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = DMA_REGS_OFF;
394 #ifndef	ISP_DISABLE_1020_SUPPORT
395 	if (data == PCI_QLOGIC_ISP) {
396 		isp->isp_mdvec = &mdvec;
397 		isp->isp_type = ISP_HA_SCSI_UNKNOWN;
398 		isp->isp_param = &pcs->_z._x;
399 	}
400 #endif
401 #ifndef	ISP_DISABLE_1080_SUPPORT
402 	if (data == PCI_QLOGIC_ISP1080 || data == PCI_QLOGIC_ISP1240) {
403 		isp->isp_mdvec = &mdvec_1080;
404 		isp->isp_type = ISP_HA_SCSI_1080;
405 		isp->isp_param = &pcs->_z._x;
406 		pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
407 		    ISP1080_DMA_REGS_OFF;
408 	}
409 #endif
410 #ifndef	ISP_DISABLE_2100_SUPPORT
411 	if (data == PCI_QLOGIC_ISP2100) {
412 		isp->isp_mdvec = &mdvec_2100;
413 		isp->isp_type = ISP_HA_FC_2100;
414 		isp->isp_param = &pcs->_z._y;
415 		pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
416 		    PCI_MBOX_REGS2100_OFF;
417 
418 		data = pci_conf_read(config_id, PCI_CLASS_REG);
419 		if ((data & 0xff) < 3) {
420 			/*
421 			 * XXX: Need to get the actual revision
422 			 * XXX: number of the 2100 FB. At any rate,
423 			 * XXX: lower cache line size for early revision
424 			 * XXX; boards.
425 			 */
426 			linesz = 1;
427 		}
428 	}
429 #endif
430 
431 #if	__FreeBSD_version >= 300004
432 	ISP_LOCK(isp);
433 
434 	/*
435 	 * Make sure that SERR, PERR, WRITE INVALIDATE and BUSMASTER
436 	 * are set.
437 	 */
438 	data = pci_cfgread(config_id, PCIR_COMMAND, 2);
439 	data |=	PCIM_CMD_SEREN		|
440 		PCIM_CMD_PERRESPEN	|
441 		PCIM_CMD_BUSMASTEREN	|
442 		PCIM_CMD_INVEN;
443 	pci_cfgwrite(config_id, PCIR_COMMAND, 2, data);
444 
445 	/*
446 	 * Make sure the CACHE Line Size register is set sensibly.
447 	 */
448 	data = pci_cfgread(config_id, PCIR_CACHELNSZ, 1);
449 	if (data != linesz) {
450 		data = PCI_DFLT_LNSZ;
451 		printf("%s: set PCI line size to %d\n", isp->isp_name, data);
452 		pci_cfgwrite(config_id, PCIR_CACHELNSZ, data, 1);
453 	}
454 
455 	/*
456 	 * Make sure the Latency Timer is sane.
457 	 */
458 	data = pci_cfgread(config_id, PCIR_LATTIMER, 1);
459 	if (data < PCI_DFLT_LTNCY) {
460 		data = PCI_DFLT_LTNCY;
461 		printf("%s: set PCI latency to %d\n", isp->isp_name, data);
462 		pci_cfgwrite(config_id, PCIR_LATTIMER, data, 1);
463 	}
464 
465 	/*
466 	 * Make sure we've disabled the ROM.
467 	 */
468 	data = pci_cfgread(config_id, PCIR_ROMADDR, 4);
469 	data &= ~1;
470 	pci_cfgwrite(config_id, PCIR_ROMADDR, data, 4);
471 
472 	ISP_UNLOCK(isp);
473 
474 	if (bus_dma_tag_create(NULL, 0, 0, BUS_SPACE_MAXADDR_32BIT,
475 	    BUS_SPACE_MAXADDR, NULL, NULL, 1<<24,
476 	    255, 1<<24, 0, &pcs->parent_dmat) != 0) {
477 		printf("%s: could not create master dma tag\n", isp->isp_name);
478 		free(pcs, M_DEVBUF);
479 		return;
480 	}
481 #else
482 	ISP_LOCK(isp);
483 	data = pci_conf_read(config_id, PCIR_COMMAND);
484 	data |=	PCIM_CMD_SEREN		|
485 		PCIM_CMD_PERRESPEN	|
486 		PCIM_CMD_BUSMASTEREN	|
487 		PCIM_CMD_INVEN;
488 	pci_conf_write(config_id, PCIR_COMMAND, data);
489 	data = pci_conf_read(config_id, PCIR_CACHELNSZ);
490 	if ((data & ~0xffff) != ((PCI_DFLT_LTNCY << 8) | linesz)) {
491 		data &= ~0xffff;
492 		data |= (PCI_DFLT_LTNCY << 8) | linesz;
493 		pci_conf_write(config_id, PCIR_CACHELNSZ, data);
494 		printf("%s: set PCI line size to %d\n", isp->isp_name, linesz);
495 		printf("%s: set PCI latency to %d\n", isp->isp_name,
496 		    PCI_DFLT_LTNCY);
497 	}
498 
499 	/*
500 	 * Make sure we've disabled the ROM.
501 	 */
502 	data = pci_conf_read(config_id, PCIR_ROMADDR);
503 	data &= ~1;
504 	pci_conf_write(config_id, PCIR_ROMADDR, data);
505 	ISP_UNLOCK(isp);
506 #endif
507 	if (pci_map_int(config_id, (void (*)(void *))isp_intr,
508 	    (void *)isp, &IMASK) == 0) {
509 		printf("%s: could not map interrupt\n", isp->isp_name);
510 		free(pcs, M_DEVBUF);
511 		return;
512 	}
513 
514 	pcs->pci_id = config_id;
515 #ifdef	SCSI_ISP_NO_FWLOAD_MASK
516 	if (SCSI_ISP_NO_FWLOAD_MASK && (SCSI_ISP_NO_FWLOAD_MASK & (1 << unit)))
517 		isp->isp_confopts |= ISP_CFG_NORELOAD;
518 #endif
519 #ifdef	SCSI_ISP_NO_NVRAM_MASK
520 	if (SCSI_ISP_NO_NVRAM_MASK && (SCSI_ISP_NO_NVRAM_MASK & (1 << unit))) {
521 		printf("%s: ignoring NVRAM\n", isp->isp_name);
522 		isp->isp_confopts |= ISP_CFG_NONVRAM;
523 	}
524 #endif
525 	ISP_LOCK(isp);
526 	isp_reset(isp);
527 	if (isp->isp_state != ISP_RESETSTATE) {
528 		ISP_UNLOCK(isp);
529 		free(pcs, M_DEVBUF);
530 		return;
531 	}
532 	isp_init(isp);
533 	if (isp->isp_state != ISP_INITSTATE) {
534 		/* If we're a Fibre Channel Card, we allow deferred attach */
535 		if (isp->isp_type & ISP_HA_SCSI) {
536 			isp_uninit(isp);
537 			free(pcs, M_DEVBUF);
538 		}
539 	}
540 	isp_attach(isp);
541 	if (isp->isp_state != ISP_RUNSTATE) {
542 		/* If we're a Fibre Channel Card, we allow deferred attach */
543 		if (IS_SCSI(isp)) {
544 			isp_uninit(isp);
545 			free(pcs, M_DEVBUF);
546 		}
547 	}
548 	ISP_UNLOCK(isp);
549 #ifdef __alpha__
550 	/*
551 	 * THIS SHOULD NOT HAVE TO BE HERE
552 	 */
553 	alpha_register_pci_scsi(config_id->bus, config_id->slot, isp->isp_sim);
554 #endif
555 }
556 
557 static u_int16_t
558 isp_pci_rd_reg(isp, regoff)
559 	struct ispsoftc *isp;
560 	int regoff;
561 {
562 	u_int16_t rv;
563 	struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
564 	int offset, oldconf = 0;
565 
566 	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
567 		/*
568 		 * We will assume that someone has paused the RISC processor.
569 		 */
570 		oldconf = isp_pci_rd_reg(isp, BIU_CONF1);
571 		isp_pci_wr_reg(isp, BIU_CONF1, oldconf | BIU_PCI_CONF1_SXP);
572 	}
573 	offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
574 	offset += (regoff & 0xff);
575 	rv = bus_space_read_2(pcs->pci_st, pcs->pci_sh, offset);
576 	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
577 		isp_pci_wr_reg(isp, BIU_CONF1, oldconf);
578 	}
579 	return (rv);
580 }
581 
582 static void
583 isp_pci_wr_reg(isp, regoff, val)
584 	struct ispsoftc *isp;
585 	int regoff;
586 	u_int16_t val;
587 {
588 	struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
589 	int offset, oldconf = 0;
590 
591 	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
592 		/*
593 		 * We will assume that someone has paused the RISC processor.
594 		 */
595 		oldconf = isp_pci_rd_reg(isp, BIU_CONF1);
596 		isp_pci_wr_reg(isp, BIU_CONF1, oldconf | BIU_PCI_CONF1_SXP);
597 	}
598 	offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
599 	offset += (regoff & 0xff);
600 	bus_space_write_2(pcs->pci_st, pcs->pci_sh, offset, val);
601 	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
602 		isp_pci_wr_reg(isp, BIU_CONF1, oldconf);
603 	}
604 }
605 
606 #ifndef	ISP_DISABLE_1080_SUPPORT
607 static u_int16_t
608 isp_pci_rd_reg_1080(isp, regoff)
609 	struct ispsoftc *isp;
610 	int regoff;
611 {
612 	u_int16_t rv;
613 	struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
614 	int offset, oc = 0;
615 
616 	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
617 		/*
618 		 * We will assume that someone has paused the RISC processor.
619 		 */
620 		oc = isp_pci_rd_reg(isp, BIU_CONF1);
621 		isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_SXP);
622 	} else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {
623 		oc = isp_pci_rd_reg(isp, BIU_CONF1);
624 		isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_DMA);
625 	}
626 	offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
627 	offset += (regoff & 0xff);
628 	rv = bus_space_read_2(pcs->pci_st, pcs->pci_sh, offset);
629 	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||
630 	    ((regoff & _BLK_REG_MASK) == DMA_BLOCK)) {
631 		isp_pci_wr_reg(isp, BIU_CONF1, oc);
632 	}
633 	return (rv);
634 }
635 
636 static void
637 isp_pci_wr_reg_1080(isp, regoff, val)
638 	struct ispsoftc *isp;
639 	int regoff;
640 	u_int16_t val;
641 {
642 	struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
643 	int offset, oc = 0;
644 
645 	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
646 		/*
647 		 * We will assume that someone has paused the RISC processor.
648 		 */
649 		oc = isp_pci_rd_reg(isp, BIU_CONF1);
650 		isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_SXP);
651 	} else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {
652 		oc = isp_pci_rd_reg(isp, BIU_CONF1);
653 		isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_DMA);
654 	}
655 	offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
656 	offset += (regoff & 0xff);
657 	bus_space_write_2(pcs->pci_st, pcs->pci_sh, offset, val);
658 	if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||
659 	    ((regoff & _BLK_REG_MASK) == DMA_BLOCK)) {
660 		isp_pci_wr_reg(isp, BIU_CONF1, oc);
661 	}
662 }
663 #endif
664 
665 
666 #if	__FreeBSD_version >= 300004
667 static void isp_map_rquest __P((void *, bus_dma_segment_t *, int, int));
668 static void isp_map_result __P((void *, bus_dma_segment_t *, int, int));
669 static void isp_map_fcscrt __P((void *, bus_dma_segment_t *, int, int));
670 
671 static void
672 isp_map_rquest(void *arg, bus_dma_segment_t *segs, int nseg, int error)
673 {
674 	struct ispsoftc *isp = (struct ispsoftc *) arg;
675 	isp->isp_rquest_dma = segs->ds_addr;
676 }
677 
678 static void
679 isp_map_result(void *arg, bus_dma_segment_t *segs, int nseg, int error)
680 {
681 	struct ispsoftc *isp = (struct ispsoftc *) arg;
682 	isp->isp_result_dma = segs->ds_addr;
683 }
684 
685 static void
686 isp_map_fcscrt(void *arg, bus_dma_segment_t *segs, int nseg, int error)
687 {
688 	struct ispsoftc *isp = (struct ispsoftc *) arg;
689 	fcparam *fcp = isp->isp_param;
690 	fcp->isp_scdma = segs->ds_addr;
691 }
692 
693 static int
694 isp_pci_mbxdma(struct ispsoftc *isp)
695 {
696 	struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp;
697 	caddr_t base;
698 	u_int32_t len;
699 	int i, error;
700 
701 	/*
702 	 * Allocate and map the request, result queues, plus FC scratch area.
703 	 */
704 	len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN);
705 	len += ISP_QUEUE_SIZE(RESULT_QUEUE_LEN);
706 	if (isp->isp_type & ISP_HA_FC) {
707 		len += ISP2100_SCRLEN;
708 	}
709 	if (bus_dma_tag_create(pci->parent_dmat, 0, 0, BUS_SPACE_MAXADDR,
710 	    BUS_SPACE_MAXADDR, NULL, NULL, len, 1, BUS_SPACE_MAXSIZE_32BIT,
711 	    0, &pci->cntrol_dmat) != 0) {
712 		printf("%s: cannot create a dma tag for control spaces\n",
713 		    isp->isp_name);
714 		return (1);
715 	}
716 	if (bus_dmamem_alloc(pci->cntrol_dmat, (void **)&base,
717 	    BUS_DMA_NOWAIT, &pci->cntrol_dmap) != 0) {
718 		printf("%s: cannot allocate %d bytes of CCB memory\n",
719 		    isp->isp_name, len);
720 		return (1);
721 	}
722 
723 	isp->isp_rquest = base;
724 	bus_dmamap_load(pci->cntrol_dmat, pci->cntrol_dmap, isp->isp_rquest,
725 	    ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN), isp_map_rquest, pci, 0);
726 
727 	isp->isp_result = base + ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN);
728 	bus_dmamap_load(pci->cntrol_dmat, pci->cntrol_dmap, isp->isp_result,
729 	    ISP_QUEUE_SIZE(RESULT_QUEUE_LEN), isp_map_result, pci, 0);
730 
731 	/*
732 	 * Use this opportunity to initialize/create data DMA maps.
733 	 */
734 	for (i = 0; i < MAXISPREQUEST; i++) {
735 		error = bus_dmamap_create(pci->parent_dmat, 0, &pci->dmaps[i]);
736 		if (error) {
737 			printf("%s: error %d creating mailbox DMA maps\n",
738 			    isp->isp_name, error);
739 			return (1);
740 		}
741 	}
742 
743 	if (isp->isp_type & ISP_HA_FC) {
744 		fcparam *fcp = (fcparam *) isp->isp_param;
745 		fcp->isp_scratch = base +
746 			ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN) +
747 			ISP_QUEUE_SIZE(RESULT_QUEUE_LEN);
748 		bus_dmamap_load(pci->cntrol_dmat, pci->cntrol_dmap,
749 		    fcp->isp_scratch, ISP2100_SCRLEN, isp_map_fcscrt, pci, 0);
750 	}
751 	return (0);
752 }
753 
754 static void dma2 __P((void *, bus_dma_segment_t *, int, int));
755 typedef struct {
756 	struct ispsoftc *isp;
757 	ISP_SCSI_XFER_T *ccb;
758 	ispreq_t *rq;
759 	u_int8_t *iptrp;
760 	u_int8_t optr;
761 	u_int error;
762 } mush_t;
763 
764 #define	MUSHERR_NOQENTRIES	-2
765 
766 static void
767 dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
768 {
769 	mush_t *mp;
770 	ISP_SCSI_XFER_T *ccb;
771 	struct ispsoftc *isp;
772 	struct isp_pcisoftc *pci;
773 	bus_dmamap_t *dp;
774 	bus_dma_segment_t *eseg;
775 	ispreq_t *rq;
776 	u_int8_t *iptrp;
777 	u_int8_t optr;
778 	ispcontreq_t *crq;
779 	int drq, seglim, datalen;
780 
781 	mp = (mush_t *) arg;
782 	if (error) {
783 		mp->error = error;
784 		return;
785 	}
786 
787 	isp = mp->isp;
788 	if (nseg < 1) {
789 		printf("%s: zero or negative segment count\n", isp->isp_name);
790 		mp->error = EFAULT;
791 		return;
792 	}
793 	ccb = mp->ccb;
794 	rq = mp->rq;
795 	iptrp = mp->iptrp;
796 	optr = mp->optr;
797 
798 	pci = (struct isp_pcisoftc *)isp;
799 	dp = &pci->dmaps[rq->req_handle - 1];
800 	if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
801 		bus_dmamap_sync(pci->parent_dmat, *dp, BUS_DMASYNC_PREREAD);
802 		drq = REQFLAG_DATA_IN;
803 	} else {
804 		bus_dmamap_sync(pci->parent_dmat, *dp, BUS_DMASYNC_PREWRITE);
805 		drq = REQFLAG_DATA_OUT;
806 	}
807 
808 	datalen = XS_XFRLEN(ccb);
809 	if (isp->isp_type & ISP_HA_FC) {
810 		seglim = ISP_RQDSEG_T2;
811 		((ispreqt2_t *)rq)->req_totalcnt = datalen;
812 		((ispreqt2_t *)rq)->req_flags |= drq;
813 	} else {
814 		seglim = ISP_RQDSEG;
815 		rq->req_flags |= drq;
816 	}
817 
818 	eseg = dm_segs + nseg;
819 
820 	while (datalen != 0 && rq->req_seg_count < seglim && dm_segs != eseg) {
821 		if (isp->isp_type & ISP_HA_FC) {
822 			ispreqt2_t *rq2 = (ispreqt2_t *)rq;
823 			rq2->req_dataseg[rq2->req_seg_count].ds_base =
824 			    dm_segs->ds_addr;
825 			rq2->req_dataseg[rq2->req_seg_count].ds_count =
826 			    dm_segs->ds_len;
827 		} else {
828 			rq->req_dataseg[rq->req_seg_count].ds_base =
829 				dm_segs->ds_addr;
830 			rq->req_dataseg[rq->req_seg_count].ds_count =
831 				dm_segs->ds_len;
832 		}
833 		datalen -= dm_segs->ds_len;
834 #if	0
835 		if (isp->isp_type & ISP_HA_FC) {
836 			ispreqt2_t *rq2 = (ispreqt2_t *)rq;
837 			printf("%s: seg0[%d] cnt 0x%x paddr 0x%08x\n",
838 			    isp->isp_name, rq->req_seg_count,
839 			    rq2->req_dataseg[rq2->req_seg_count].ds_count,
840 			    rq2->req_dataseg[rq2->req_seg_count].ds_base);
841 		} else {
842 			printf("%s: seg0[%d] cnt 0x%x paddr 0x%08x\n",
843 			    isp->isp_name, rq->req_seg_count,
844 			    rq->req_dataseg[rq->req_seg_count].ds_count,
845 			    rq->req_dataseg[rq->req_seg_count].ds_base);
846 		}
847 #endif
848 		rq->req_seg_count++;
849 		dm_segs++;
850 	}
851 
852 	while (datalen > 0 && dm_segs != eseg) {
853 		crq = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, *iptrp);
854 		*iptrp = ISP_NXT_QENTRY(*iptrp, RQUEST_QUEUE_LEN);
855 		if (*iptrp == optr) {
856 #if	0
857 			printf("%s: Request Queue Overflow++\n", isp->isp_name);
858 #endif
859 			mp->error = MUSHERR_NOQENTRIES;
860 			return;
861 		}
862 		rq->req_header.rqs_entry_count++;
863 		bzero((void *)crq, sizeof (*crq));
864 		crq->req_header.rqs_entry_count = 1;
865 		crq->req_header.rqs_entry_type = RQSTYPE_DATASEG;
866 
867 		seglim = 0;
868 		while (datalen > 0 && seglim < ISP_CDSEG && dm_segs != eseg) {
869 			crq->req_dataseg[seglim].ds_base =
870 			    dm_segs->ds_addr;
871 			crq->req_dataseg[seglim].ds_count =
872 			    dm_segs->ds_len;
873 #if	0
874 			printf("%s: seg%d[%d] cnt 0x%x paddr 0x%08x\n",
875 			    isp->isp_name, rq->req_header.rqs_entry_count-1,
876 			    seglim, crq->req_dataseg[seglim].ds_count,
877 			    crq->req_dataseg[seglim].ds_base);
878 #endif
879 			rq->req_seg_count++;
880 			dm_segs++;
881 			seglim++;
882 			datalen -= dm_segs->ds_len;
883 		}
884 	}
885 }
886 
887 static int
888 isp_pci_dmasetup(struct ispsoftc *isp, ISP_SCSI_XFER_T *ccb, ispreq_t *rq,
889 	u_int8_t *iptrp, u_int8_t optr)
890 {
891 	struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp;
892 	struct ccb_hdr *ccb_h;
893 	struct ccb_scsiio *csio;
894 	bus_dmamap_t *dp;
895 	mush_t mush, *mp;
896 
897 	csio = (struct ccb_scsiio *) ccb;
898 	ccb_h = &csio->ccb_h;
899 
900 	if ((ccb_h->flags & CAM_DIR_MASK) == CAM_DIR_NONE) {
901 		rq->req_seg_count = 1;
902 		return (CMD_QUEUED);
903 	}
904 	dp = &pci->dmaps[rq->req_handle - 1];
905 
906 	/*
907 	 * Do a virtual grapevine step to collect info for
908 	 * the callback dma allocation that we have to use...
909 	 */
910 	mp = &mush;
911 	mp->isp = isp;
912 	mp->ccb = ccb;
913 	mp->rq = rq;
914 	mp->iptrp = iptrp;
915 	mp->optr = optr;
916 	mp->error = 0;
917 
918 	if ((ccb_h->flags & CAM_SCATTER_VALID) == 0) {
919 		if ((ccb_h->flags & CAM_DATA_PHYS) == 0) {
920 			int error, s;
921 
922 			s = splsoftvm();
923 			error = bus_dmamap_load(pci->parent_dmat, *dp,
924 			    csio->data_ptr, csio->dxfer_len, dma2, mp, 0);
925 			if (error == EINPROGRESS) {
926 				bus_dmamap_unload(pci->parent_dmat, *dp);
927 				mp->error = EINVAL;
928 				printf("%s: deferred dma allocation not "
929 				    "supported\n", isp->isp_name);
930 			} else if (error && mp->error == 0) {
931 				mp->error = error;
932 			}
933 			splx(s);
934 		} else {
935 			/* Pointer to physical buffer */
936 			struct bus_dma_segment seg;
937 			seg.ds_addr = (bus_addr_t)csio->data_ptr;
938 			seg.ds_len = csio->dxfer_len;
939 			dma2(mp, &seg, 1, 0);
940 		}
941 	} else {
942 		struct bus_dma_segment *segs;
943 
944 		if ((ccb_h->flags & CAM_DATA_PHYS) != 0) {
945 			printf("%s: Physical segment pointers unsupported",
946 				isp->isp_name);
947 			mp->error = EINVAL;
948 		} else if ((ccb_h->flags & CAM_SG_LIST_PHYS) == 0) {
949 			printf("%s: Virtual segment addresses unsupported",
950 				isp->isp_name);
951 			mp->error = EINVAL;
952 		} else {
953 			/* Just use the segments provided */
954 			segs = (struct bus_dma_segment *) csio->data_ptr;
955 			dma2(mp, segs, csio->sglist_cnt, 0);
956 		}
957 	}
958 	if (mp->error) {
959 		int retval = CMD_COMPLETE;
960 		if (mp->error == MUSHERR_NOQENTRIES) {
961 			retval = CMD_EAGAIN;
962 			ccb_h->status = CAM_UNREC_HBA_ERROR;
963 		} else if (mp->error == EFBIG) {
964 			ccb_h->status = CAM_REQ_TOO_BIG;
965 		} else if (mp->error == EINVAL) {
966 			ccb_h->status = CAM_REQ_INVALID;
967 		} else {
968 			ccb_h->status = CAM_UNREC_HBA_ERROR;
969 		}
970 		return (retval);
971 	} else {
972 		return (CMD_QUEUED);
973 	}
974 }
975 
976 static void
977 isp_pci_dmateardown(struct ispsoftc *isp, ISP_SCSI_XFER_T *ccb,
978 	u_int32_t handle)
979 {
980 	struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp;
981 	bus_dmamap_t *dp = &pci->dmaps[handle];
982 
983 	if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
984 		bus_dmamap_sync(pci->parent_dmat, *dp, BUS_DMASYNC_POSTREAD);
985 	} else {
986 		bus_dmamap_sync(pci->parent_dmat, *dp, BUS_DMASYNC_POSTWRITE);
987 	}
988 	bus_dmamap_unload(pci->parent_dmat, *dp);
989 }
990 
991 #else	/* __FreeBSD_version >= 300004 */
992 
993 
994 static int
995 isp_pci_mbxdma(struct ispsoftc *isp)
996 {
997 	struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp;
998 	u_int32_t len;
999 	int rseg;
1000 
1001 	/* XXXX CHECK FOR ALIGNMENT */
1002 	/*
1003 	 * Allocate and map the request queue.
1004 	 */
1005 	len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN);
1006 	isp->isp_rquest = malloc(len, M_DEVBUF, M_NOWAIT);
1007 	if (isp->isp_rquest == NULL) {
1008 		printf("%s: cannot malloc request queue\n", isp->isp_name);
1009 		return (1);
1010 	}
1011 	isp->isp_rquest_dma = vtophys(isp->isp_rquest);
1012 
1013 #if	0
1014 	printf("RQUEST=0x%x (0x%x)...", isp->isp_rquest, isp->isp_rquest_dma);
1015 #endif
1016 
1017 	/*
1018 	 * Allocate and map the result queue.
1019 	 */
1020 	len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN);
1021 	isp->isp_result = malloc(len, M_DEVBUF, M_NOWAIT);
1022 	if (isp->isp_result == NULL) {
1023 		free(isp->isp_rquest, M_DEVBUF);
1024 		printf("%s: cannot malloc result queue\n", isp->isp_name);
1025 		return (1);
1026 	}
1027 	isp->isp_result_dma = vtophys(isp->isp_result);
1028 #if	0
1029 	printf("RESULT=0x%x (0x%x)\n", isp->isp_result, isp->isp_result_dma);
1030 #endif
1031 	if (isp->isp_type & ISP_HA_FC) {
1032 		fcparam *fcp = isp->isp_param;
1033 		len = ISP2100_SCRLEN;
1034 		fcp->isp_scratch = (volatile caddr_t)
1035 		    malloc(ISP2100_SCRLEN, M_DEVBUF, M_NOWAIT);
1036 		if (fcp->isp_scratch == NULL) {
1037 			printf("%s: cannot alloc scratch\n", isp->isp_name);
1038 			return (1);
1039 		}
1040 		fcp->isp_scdma = vtophys(fcp->isp_scratch);
1041 	}
1042 	return (0);
1043 }
1044 
1045 static int
1046 isp_pci_dmasetup(struct ispsoftc *isp, ISP_SCSI_XFER_T *xs,
1047 	ispreq_t *rq, u_int8_t *iptrp, u_int8_t optr)
1048 {
1049 	struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp;
1050 	ispcontreq_t *crq;
1051 	vm_offset_t vaddr;
1052 	int drq, seglim;
1053 	u_int32_t paddr, nextpaddr, datalen, size, *ctrp;
1054 
1055 	if (xs->datalen == 0) {
1056 		rq->req_seg_count = 1;
1057 		return (CMD_QUEUED);
1058 	}
1059 
1060 	if (xs->flags & SCSI_DATA_IN) {
1061 		drq = REQFLAG_DATA_IN;
1062 	} else {
1063 		drq = REQFLAG_DATA_OUT;
1064 	}
1065 
1066 	if (isp->isp_type & ISP_HA_FC) {
1067 		seglim = ISP_RQDSEG_T2;
1068 		((ispreqt2_t *)rq)->req_totalcnt = XS_XFRLEN(xs);
1069 		((ispreqt2_t *)rq)->req_flags |= drq;
1070 	} else {
1071 		seglim = ISP_RQDSEG;
1072 		rq->req_flags |= drq;
1073 	}
1074 
1075 	datalen = XS_XFRLEN(xs);
1076 	vaddr = (vm_offset_t) xs->data;
1077 	paddr = vtophys(vaddr);
1078 
1079 	while (datalen != 0 && rq->req_seg_count < seglim) {
1080 		if (isp->isp_type & ISP_HA_FC) {
1081 			ispreqt2_t *rq2 = (ispreqt2_t *)rq;
1082 			rq2->req_dataseg[rq2->req_seg_count].ds_base = paddr;
1083 			ctrp = &rq2->req_dataseg[rq2->req_seg_count].ds_count;
1084 		} else {
1085 			rq->req_dataseg[rq->req_seg_count].ds_base = paddr;
1086 			ctrp = &rq->req_dataseg[rq->req_seg_count].ds_count;
1087 		}
1088 		nextpaddr = paddr;
1089 		*(ctrp) = 0;
1090 
1091 		while (datalen != 0 && paddr == nextpaddr) {
1092 			nextpaddr = (paddr & (~PAGE_MASK)) + PAGE_SIZE;
1093 			size = nextpaddr - paddr;
1094 			if (size > datalen)
1095 				size = datalen;
1096 			*(ctrp) += size;
1097 			vaddr += size;
1098 			datalen -= size;
1099 			if (datalen != 0)
1100 				paddr = vtophys(vaddr);
1101 
1102 		}
1103 #if	0
1104 		if (isp->isp_type & ISP_HA_FC) {
1105 			ispreqt2_t *rq2 = (ispreqt2_t *)rq;
1106 			printf("%s: seg0[%d] cnt 0x%x paddr 0x%08x\n",
1107 			    isp->isp_name, rq->req_seg_count,
1108 			    rq2->req_dataseg[rq2->req_seg_count].ds_count,
1109 			    rq2->req_dataseg[rq2->req_seg_count].ds_base);
1110 		} else {
1111 			printf("%s: seg0[%d] cnt 0x%x paddr 0x%08x\n",
1112 			    isp->isp_name, rq->req_seg_count,
1113 			    rq->req_dataseg[rq->req_seg_count].ds_count,
1114 			    rq->req_dataseg[rq->req_seg_count].ds_base);
1115 		}
1116 #endif
1117 		rq->req_seg_count++;
1118 	}
1119 
1120 
1121 
1122 	if (datalen == 0)
1123 		return (CMD_QUEUED);
1124 
1125 	paddr = vtophys(vaddr);
1126 	while (datalen > 0) {
1127 		crq = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, *iptrp);
1128 		*iptrp = ISP_NXT_QENTRY(*iptrp, RQUEST_QUEUE_LEN);
1129 		if (*iptrp == optr) {
1130 			printf("%s: Request Queue Overflow\n", isp->isp_name);
1131 			XS_SETERR(xs, HBA_BOTCH);
1132 			return (CMD_EAGAIN);
1133 		}
1134 		rq->req_header.rqs_entry_count++;
1135 		bzero((void *)crq, sizeof (*crq));
1136 		crq->req_header.rqs_entry_count = 1;
1137 		crq->req_header.rqs_entry_type = RQSTYPE_DATASEG;
1138 
1139 		for (seglim = 0; datalen != 0 && seglim < ISP_CDSEG; seglim++) {
1140 			crq->req_dataseg[seglim].ds_base = paddr;
1141 			ctrp = &crq->req_dataseg[seglim].ds_count;
1142 			*(ctrp) = 0;
1143 			nextpaddr = paddr;
1144 			while (datalen != 0 && paddr == nextpaddr) {
1145 				nextpaddr = (paddr & (~PAGE_MASK)) + PAGE_SIZE;
1146 				size = nextpaddr - paddr;
1147 				if (size > datalen)
1148 					size = datalen;
1149 				*(ctrp) += size;
1150 				vaddr += size;
1151 				datalen -= size;
1152 				if (datalen != 0)
1153 					paddr = vtophys(vaddr);
1154 			}
1155 #if	0
1156 			printf("%s: seg%d[%d] cnt 0x%x paddr 0x%08x\n",
1157 			    isp->isp_name, rq->req_header.rqs_entry_count-1,
1158 			    seglim, crq->req_dataseg[seglim].ds_count,
1159 			    crq->req_dataseg[seglim].ds_base);
1160 #endif
1161 			rq->req_seg_count++;
1162 		}
1163 	}
1164 
1165 	return (CMD_QUEUED);
1166 }
1167 #endif
1168 
1169 static void
1170 isp_pci_reset1(struct ispsoftc *isp)
1171 {
1172 	/* Make sure the BIOS is disabled */
1173 	isp_pci_wr_reg(isp, HCCR, PCI_HCCR_CMD_BIOS);
1174 }
1175 
1176 static void
1177 isp_pci_dumpregs(struct ispsoftc *isp)
1178 {
1179 	struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp;
1180 	printf("%s: PCI Status Command/Status=%lx\n", pci->pci_isp.isp_name,
1181 	    pci_conf_read(pci->pci_id, PCIR_COMMAND));
1182 }
1183