xref: /openbsd-src/sys/dev/pci/qle.c (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
1 /*	$OpenBSD: qle.c,v 1.31 2014/07/13 23:10:23 deraadt Exp $ */
2 
3 /*
4  * Copyright (c) 2013, 2014 Jonathan Matthew <jmatthew@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include "bio.h"
20 
21 #include <sys/param.h>
22 #include <sys/systm.h>
23 #include <sys/kernel.h>
24 #include <sys/malloc.h>
25 #include <sys/device.h>
26 #include <sys/sensors.h>
27 #include <sys/rwlock.h>
28 #include <sys/task.h>
29 
30 #include <machine/atomic.h>
31 #include <machine/bus.h>
32 
33 #include <dev/pci/pcireg.h>
34 #include <dev/pci/pcivar.h>
35 #include <dev/pci/pcidevs.h>
36 
37 #ifdef __sparc64__
38 #include <dev/ofw/openfirm.h>
39 #endif
40 
41 #include <scsi/scsi_all.h>
42 #include <scsi/scsiconf.h>
43 
44 #include <dev/pci/qlereg.h>
45 
46 #ifdef QLE_DEBUG
47 #define DPRINTF(m, f...) do { if ((qledebug & (m)) == (m)) printf(f); } \
48     while (0)
49 #define QLE_D_MBOX		0x01
50 #define QLE_D_INTR		0x02
51 #define QLE_D_PORT		0x04
52 #define QLE_D_IO		0x08
53 #define QLE_D_IOCB		0x10
54 int qledebug = QLE_D_PORT;
55 #else
56 #define DPRINTF(m, f...)
57 #endif
58 
59 #ifndef QLE_NOFIRMWARE
60 #include <dev/microcode/isp/asm_2400.h>
61 #include <dev/microcode/isp/asm_2500.h>
62 #endif
63 
64 #define QLE_PCI_MEM_BAR		0x14
65 #define QLE_PCI_IO_BAR		0x10
66 
67 
68 #define QLE_DEFAULT_PORT_NAME		0x400000007F000003ULL /* from isp(4) */
69 
70 #define QLE_WAIT_FOR_LOOP		10
71 
72 /* rounded up range of assignable handles */
73 #define QLE_MAX_TARGETS			2048
74 
75 /* maximum number of segments allowed for in a single io */
76 #define QLE_MAX_SEGS			16
77 
78 enum qle_isp_gen {
79 	QLE_GEN_ISP24XX = 1,
80 	QLE_GEN_ISP25XX
81 };
82 
83 enum qle_isp_type {
84 	QLE_ISP2422 = 1,
85 	QLE_ISP2432,
86 	QLE_ISP2512,
87 	QLE_ISP2522,
88 	QLE_ISP2532
89 };
90 
91 /* port database things */
92 #define QLE_SCRATCH_SIZE		0x1000
93 
94 enum qle_port_disp {
95 	QLE_PORT_DISP_NEW,
96 	QLE_PORT_DISP_GONE,
97 	QLE_PORT_DISP_SAME,
98 	QLE_PORT_DISP_CHANGED,
99 	QLE_PORT_DISP_MOVED,
100 	QLE_PORT_DISP_DUP
101 };
102 
103 #define QLE_LOCATION_LOOP		(1 << 24)
104 #define QLE_LOCATION_FABRIC		(2 << 24)
105 #define QLE_LOCATION_LOOP_ID(l)		(l | QLE_LOCATION_LOOP)
106 #define QLE_LOCATION_PORT_ID(p)		(p | QLE_LOCATION_FABRIC)
107 
108 struct qle_fc_port {
109 	TAILQ_ENTRY(qle_fc_port) ports;
110 	TAILQ_ENTRY(qle_fc_port) update;
111 
112 	u_int64_t	node_name;
113 	u_int64_t	port_name;
114 	u_int32_t	location;	/* port id or loop id */
115 
116 	int		flags;
117 #define QLE_PORT_FLAG_IS_TARGET		1
118 #define QLE_PORT_FLAG_NEEDS_LOGIN	2
119 
120 	u_int32_t	portid;
121 	u_int16_t	loopid;
122 };
123 
124 
125 /* request/response queue stuff */
126 #define QLE_QUEUE_ENTRY_SIZE		64
127 
128 struct qle_ccb {
129 	struct qle_softc 	*ccb_sc;
130 	int			ccb_id;
131 	struct scsi_xfer	*ccb_xs;
132 
133 	bus_dmamap_t		ccb_dmamap;
134 
135 	struct qle_iocb_seg	*ccb_segs;
136 	u_int64_t		ccb_seg_offset;
137 
138 	SIMPLEQ_ENTRY(qle_ccb)	ccb_link;
139 };
140 
141 SIMPLEQ_HEAD(qle_ccb_list, qle_ccb);
142 
143 struct qle_dmamem {
144 	bus_dmamap_t		qdm_map;
145 	bus_dma_segment_t	qdm_seg;
146 	size_t			qdm_size;
147 	caddr_t			qdm_kva;
148 };
149 #define QLE_DMA_MAP(_qdm)	((_qdm)->qdm_map)
150 #define QLE_DMA_LEN(_qdm)	((_qdm)->qdm_size)
151 #define QLE_DMA_DVA(_qdm)	((u_int64_t)(_qdm)->qdm_map->dm_segs[0].ds_addr)
152 #define QLE_DMA_KVA(_qdm)	((void *)(_qdm)->qdm_kva)
153 
154 struct qle_softc {
155 	struct device		sc_dev;
156 
157 	pci_chipset_tag_t	sc_pc;
158 	pcitag_t		sc_tag;
159 
160 	void			*sc_ih;
161 	bus_space_tag_t		sc_iot;
162 	bus_space_handle_t	sc_ioh;
163 	bus_size_t		sc_ios;
164 	bus_dma_tag_t		sc_dmat;
165 
166 	struct scsi_link        sc_link;
167 
168 	struct scsibus_softc	*sc_scsibus;
169 
170 	enum qle_isp_type	sc_isp_type;
171 	enum qle_isp_gen	sc_isp_gen;
172 	int			sc_port;
173 
174 	bus_space_handle_t	sc_mbox_ioh;
175 	u_int16_t		sc_mbox[QLE_MBOX_COUNT];
176 	int			sc_mbox_pending;
177 	struct mutex		sc_mbox_mtx;
178 
179 	int			sc_loop_up;
180 	int			sc_topology;
181 	int			sc_loop_id;
182 	int			sc_port_id;
183 	int			sc_loop_max_id;
184 	u_int64_t		sc_sns_port_name;
185 
186 	struct mutex		sc_port_mtx;
187 	TAILQ_HEAD(, qle_fc_port) sc_ports;
188 	TAILQ_HEAD(, qle_fc_port) sc_ports_new;
189 	TAILQ_HEAD(, qle_fc_port) sc_ports_gone;
190 	TAILQ_HEAD(, qle_fc_port) sc_ports_found;
191 	struct qle_fc_port	*sc_targets[QLE_MAX_TARGETS];
192 
193 	struct taskq		*sc_update_taskq;
194 	struct task		sc_update_task;
195 	int			sc_update;
196 	int			sc_update_tasks;
197 #define	QLE_UPDATE_TASK_CLEAR_ALL	0x00000001
198 #define QLE_UPDATE_TASK_SOFTRESET	0x00000002
199 #define QLE_UPDATE_TASK_UPDATE_TOPO	0x00000004
200 #define QLE_UPDATE_TASK_GET_PORT_LIST	0x00000008
201 #define QLE_UPDATE_TASK_PORT_LIST	0x00000010
202 #define QLE_UPDATE_TASK_SCAN_FABRIC	0x00000020
203 #define QLE_UPDATE_TASK_SCANNING_FABRIC	0x00000040
204 #define QLE_UPDATE_TASK_FABRIC_LOGIN	0x00000080
205 #define QLE_UPDATE_TASK_FABRIC_RELOGIN	0x00000100
206 #define QLE_UPDATE_TASK_DETACH_TARGET	0x00000200
207 #define QLE_UPDATE_TASK_ATTACH_TARGET	0x00000400
208 
209 	int			sc_maxcmds;
210 	struct qle_dmamem	*sc_requests;
211 	struct qle_dmamem	*sc_responses;
212 	struct qle_dmamem	*sc_segments;
213 	struct qle_dmamem	*sc_pri_requests;
214 	struct qle_dmamem	*sc_scratch;
215 	struct qle_dmamem	*sc_fcp_cmnds;
216 	struct qle_ccb		*sc_ccbs;
217 	struct qle_ccb_list	sc_ccb_free;
218 	struct mutex		sc_ccb_mtx;
219 	struct mutex		sc_queue_mtx;
220 	struct scsi_iopool	sc_iopool;
221 	u_int32_t		sc_next_req_id;
222 	u_int32_t		sc_last_resp_id;
223 	int			sc_marker_required;
224 	int			sc_fabric_pending;
225 	u_int8_t		sc_fabric_response[QLE_QUEUE_ENTRY_SIZE];
226 
227 	struct qle_nvram	sc_nvram;
228 	int			sc_nvram_valid;
229 };
230 #define DEVNAME(_sc) ((_sc)->sc_dev.dv_xname)
231 
232 int	qle_intr(void *);
233 
234 int	qle_match(struct device *, void *, void *);
235 void	qle_attach(struct device *, struct device *, void *);
236 int	qle_detach(struct device *, int);
237 
238 struct cfattach qle_ca = {
239 	sizeof(struct qle_softc),
240 	qle_match,
241 	qle_attach,
242 	qle_detach
243 };
244 
245 struct cfdriver qle_cd = {
246 	NULL,
247 	"qle",
248 	DV_DULL
249 };
250 
251 void		qle_scsi_cmd(struct scsi_xfer *);
252 int		qle_scsi_probe(struct scsi_link *);
253 
254 
255 struct scsi_adapter qle_switch = {
256 	qle_scsi_cmd,
257 	scsi_minphys,
258 	qle_scsi_probe,
259 	NULL,	/* scsi_free */
260 	NULL	/* ioctl */
261 };
262 
263 u_int32_t	qle_read(struct qle_softc *, int);
264 void		qle_write(struct qle_softc *, int, u_int32_t);
265 void		qle_host_cmd(struct qle_softc *sc, u_int32_t);
266 
267 int		qle_mbox(struct qle_softc *, int);
268 int		qle_ct_pass_through(struct qle_softc *sc,
269 		    u_int32_t port_handle, struct qle_dmamem *mem,
270 		    size_t req_size, size_t resp_size);
271 void		qle_mbox_putaddr(u_int16_t *, struct qle_dmamem *);
272 u_int16_t	qle_read_mbox(struct qle_softc *, int);
273 void		qle_write_mbox(struct qle_softc *, int, u_int16_t);
274 
275 void		qle_handle_intr(struct qle_softc *, u_int16_t, u_int16_t);
276 void		qle_set_ints(struct qle_softc *, int);
277 int		qle_read_isr(struct qle_softc *, u_int16_t *, u_int16_t *);
278 void		qle_clear_isr(struct qle_softc *, u_int16_t);
279 
280 void		qle_put_marker(struct qle_softc *, void *);
281 void		qle_put_cmd(struct qle_softc *, void *, struct scsi_xfer *,
282 		    struct qle_ccb *, u_int32_t);
283 struct qle_ccb *qle_handle_resp(struct qle_softc *, u_int32_t);
284 void		qle_sge(struct qle_iocb_seg *, u_int64_t, u_int32_t);
285 
286 struct qle_fc_port *qle_next_fabric_port(struct qle_softc *, u_int32_t *,
287 		    u_int32_t *);
288 int		qle_get_port_db(struct qle_softc *, u_int16_t,
289 		    struct qle_dmamem *);
290 int		qle_get_port_name_list(struct qle_softc *sc, u_int32_t);
291 int		qle_add_loop_port(struct qle_softc *, struct qle_fc_port *);
292 int		qle_add_fabric_port(struct qle_softc *, struct qle_fc_port *);
293 int		qle_add_logged_in_port(struct qle_softc *, u_int16_t,
294 		    u_int32_t);
295 int		qle_classify_port(struct qle_softc *, u_int32_t, u_int64_t,
296 		    u_int64_t, struct qle_fc_port **);
297 int		qle_get_loop_id(struct qle_softc *sc, int);
298 void		qle_clear_port_lists(struct qle_softc *);
299 int		qle_softreset(struct qle_softc *);
300 void		qle_update_topology(struct qle_softc *);
301 int		qle_update_fabric(struct qle_softc *);
302 int		qle_fabric_plogx(struct qle_softc *, struct qle_fc_port *, int,
303 		    u_int32_t *);
304 int		qle_fabric_plogi(struct qle_softc *, struct qle_fc_port *);
305 void		qle_fabric_plogo(struct qle_softc *, struct qle_fc_port *);
306 
307 void		qle_update_start(struct qle_softc *, int);
308 void		qle_update_done(struct qle_softc *, int);
309 void		qle_do_update(void *, void *);
310 int		qle_async(struct qle_softc *, u_int16_t);
311 
312 int		qle_load_fwchunk(struct qle_softc *,
313 		    struct qle_dmamem *, const u_int32_t *);
314 u_int32_t	qle_read_ram_word(struct qle_softc *, u_int32_t);
315 int		qle_verify_firmware(struct qle_softc *, u_int32_t);
316 int		qle_load_firmware_chunks(struct qle_softc *, const u_int32_t *);
317 int		qle_read_nvram(struct qle_softc *);
318 
319 struct qle_dmamem *qle_dmamem_alloc(struct qle_softc *, size_t);
320 void		qle_dmamem_free(struct qle_softc *, struct qle_dmamem *);
321 
322 int		qle_alloc_ccbs(struct qle_softc *);
323 void		qle_free_ccbs(struct qle_softc *);
324 void		*qle_get_ccb(void *);
325 void		qle_put_ccb(void *, void *);
326 
327 void		qle_dump_stuff(struct qle_softc *, void *, int);
328 void		qle_dump_iocb(struct qle_softc *, void *);
329 void		qle_dump_iocb_segs(struct qle_softc *, void *, int);
330 
331 static const struct pci_matchid qle_devices[] = {
332 	{ PCI_VENDOR_QLOGIC,	PCI_PRODUCT_QLOGIC_ISP2422 },
333 	{ PCI_VENDOR_QLOGIC,	PCI_PRODUCT_QLOGIC_ISP2432 },
334 	{ PCI_VENDOR_QLOGIC,	PCI_PRODUCT_QLOGIC_ISP2512 },
335 	{ PCI_VENDOR_QLOGIC,	PCI_PRODUCT_QLOGIC_ISP2522 },
336 	{ PCI_VENDOR_QLOGIC,	PCI_PRODUCT_QLOGIC_ISP2532 },
337 };
338 
339 int
340 qle_match(struct device *parent, void *match, void *aux)
341 {
342 	return (pci_matchbyid(aux, qle_devices, nitems(qle_devices)));
343 }
344 
345 void
346 qle_attach(struct device *parent, struct device *self, void *aux)
347 {
348 	struct qle_softc *sc = (void *)self;
349 	struct pci_attach_args *pa = aux;
350 	pci_intr_handle_t ih;
351 	const char *intrstr;
352 	u_int32_t pcictl;
353 	struct scsibus_attach_args saa;
354 	struct qle_init_cb *icb;
355 	bus_size_t mbox_base;
356 	u_int32_t firmware_addr;
357 #ifndef QLE_NOFIRMWARE
358 	const u_int32_t *firmware = NULL;
359 #endif
360 
361 	pcireg_t bars[] = { QLE_PCI_MEM_BAR, QLE_PCI_IO_BAR };
362 	pcireg_t memtype;
363 	int r, i, rv;
364 
365 	sc->sc_pc = pa->pa_pc;
366 	sc->sc_tag = pa->pa_tag;
367 	sc->sc_ih = NULL;
368 	sc->sc_dmat = pa->pa_dmat;
369 	sc->sc_ios = 0;
370 
371 	for (r = 0; r < nitems(bars); r++) {
372 		memtype = pci_mapreg_type(sc->sc_pc, sc->sc_tag, bars[r]);
373 		if (pci_mapreg_map(pa, bars[r], memtype, 0,
374 		    &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_ios, 0) == 0)
375 			break;
376 
377 		sc->sc_ios = 0;
378 	}
379 	if (sc->sc_ios == 0) {
380 		printf(": unable to map registers\n");
381 		return;
382 	}
383 
384 	if (pci_intr_map_msi(pa, &ih) != 0 && pci_intr_map(pa, &ih) != 0) {
385 		printf(": unable to map interrupt\n");
386 		goto unmap;
387 	}
388 	intrstr = pci_intr_string(sc->sc_pc, ih);
389 	sc->sc_ih = pci_intr_establish(sc->sc_pc, ih, IPL_BIO,
390 	    qle_intr, sc, DEVNAME(sc));
391 	if (sc->sc_ih == NULL) {
392 		printf(": unable to establish interrupt");
393 		if (intrstr != NULL)
394 			printf(" at %s", intrstr);
395 		printf("\n");
396 		goto deintr;
397 	}
398 
399 	printf(": %s\n", intrstr);
400 
401 	pcictl = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
402 	pcictl |= PCI_COMMAND_INVALIDATE_ENABLE |
403 	    PCI_COMMAND_PARITY_ENABLE | PCI_COMMAND_SERR_ENABLE;
404 	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, pcictl);
405 
406 	pcictl = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
407 	pcictl &= ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT);
408 	pcictl &= ~(PCI_CACHELINE_MASK << PCI_CACHELINE_SHIFT);
409 	pcictl |= (0x80 << PCI_LATTIMER_SHIFT);
410 	pcictl |= (0x10 << PCI_CACHELINE_SHIFT);
411 	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG, pcictl);
412 
413 	pcictl = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG);
414 	pcictl &= ~1;
415 	pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, pcictl);
416 
417 	switch (PCI_PRODUCT(pa->pa_id)) {
418 	case PCI_PRODUCT_QLOGIC_ISP2422:
419 		sc->sc_isp_type = QLE_ISP2422;
420 		sc->sc_isp_gen = QLE_GEN_ISP24XX;
421 		break;
422 	case PCI_PRODUCT_QLOGIC_ISP2432:
423 		sc->sc_isp_type = QLE_ISP2432;
424 		sc->sc_isp_gen = QLE_GEN_ISP24XX;
425 		break;
426 	case PCI_PRODUCT_QLOGIC_ISP2512:
427 		sc->sc_isp_type = QLE_ISP2512;
428 		sc->sc_isp_gen = QLE_GEN_ISP25XX;
429 		break;
430 	case PCI_PRODUCT_QLOGIC_ISP2522:
431 		sc->sc_isp_type = QLE_ISP2522;
432 		sc->sc_isp_gen = QLE_GEN_ISP25XX;
433 		break;
434 	case PCI_PRODUCT_QLOGIC_ISP2532:
435 		sc->sc_isp_type = QLE_ISP2532;
436 		sc->sc_isp_gen = QLE_GEN_ISP25XX;
437 		break;
438 
439 	default:
440 		printf("unknown pci id %x", pa->pa_id);
441 		goto deintr;
442 	}
443 
444 	/* these are the same for 24xx and 25xx but may vary later */
445 	mbox_base = QLE_MBOX_BASE_24XX;
446 	firmware_addr = QLE_2400_CODE_ORG;
447 
448 	if (bus_space_subregion(sc->sc_iot, sc->sc_ioh, mbox_base,
449 	    sizeof(sc->sc_mbox), &sc->sc_mbox_ioh) != 0) {
450 		printf("%s: unable to map mbox registers\n", DEVNAME(sc));
451 		goto deintr;
452 	}
453 
454 	sc->sc_port = pa->pa_function;
455 
456 	TAILQ_INIT(&sc->sc_ports);
457 	TAILQ_INIT(&sc->sc_ports_new);
458 	TAILQ_INIT(&sc->sc_ports_gone);
459 	TAILQ_INIT(&sc->sc_ports_found);
460 
461 	/* after reset, mbox regs 1 and 2 contain the string "ISP " */
462 	if (qle_read_mbox(sc, 1) != 0x4953 ||
463 	    qle_read_mbox(sc, 2) != 0x5020) {
464 		/* try releasing the risc processor */
465 		printf("%s: bad startup mboxes: %x %x\n", DEVNAME(sc),
466 		    qle_read_mbox(sc, 1), qle_read_mbox(sc, 2));
467 		qle_host_cmd(sc, QLE_HOST_CMD_RELEASE);
468 	}
469 
470 	qle_host_cmd(sc, QLE_HOST_CMD_PAUSE);
471 	if (qle_softreset(sc) != 0) {
472 		printf("softreset failed\n");
473 		goto deintr;
474 	}
475 
476 	if (qle_read_nvram(sc) == 0)
477 		sc->sc_nvram_valid = 1;
478 
479 #ifdef QLE_NOFIRMWARE
480 	if (qle_verify_firmware(sc, firmware_addr)) {
481 		printf("%s: no firmware loaded\n", DEVNAME(sc));
482 		goto deintr;
483 	}
484 #else
485 	switch (sc->sc_isp_gen) {
486 	case QLE_GEN_ISP24XX:
487 		firmware = isp_2400_risc_code;
488 		break;
489 	case QLE_GEN_ISP25XX:
490 		firmware = isp_2500_risc_code;
491 		break;
492 	default:
493 		printf("%s: no firmware to load?\n", DEVNAME(sc));
494 		goto deintr;
495 	}
496 	if (qle_load_firmware_chunks(sc, firmware)) {
497 		printf("%s: firmware load failed\n", DEVNAME(sc));
498 		goto deintr;
499 	}
500 #endif
501 
502 	/* execute firmware */
503 	sc->sc_mbox[0] = QLE_MBOX_EXEC_FIRMWARE;
504 	sc->sc_mbox[1] = firmware_addr >> 16;
505 	sc->sc_mbox[2] = firmware_addr & 0xffff;
506 #ifdef QLE_NOFIRMWARE
507 	sc->sc_mbox[3] = 1;
508 #else
509 	sc->sc_mbox[3] = 0;
510 #endif
511 	sc->sc_mbox[4] = 0;
512 	if (qle_mbox(sc, 0x001f)) {
513 		printf("ISP couldn't exec firmware: %x\n", sc->sc_mbox[0]);
514 		goto deintr;
515 	}
516 
517 	delay(250000);		/* from isp(4) */
518 
519 	sc->sc_mbox[0] = QLE_MBOX_ABOUT_FIRMWARE;
520 	if (qle_mbox(sc, 0x0001)) {
521 		printf("ISP not talking after firmware exec: %x\n",
522 		    sc->sc_mbox[0]);
523 		goto deintr;
524 	}
525 	printf("%s: firmware rev %d.%d.%d, attrs 0x%x\n", DEVNAME(sc),
526 	    sc->sc_mbox[1], sc->sc_mbox[2], sc->sc_mbox[3], sc->sc_mbox[6]);
527 
528 	sc->sc_maxcmds = 4096;
529 
530 	/* reserve queue slots for markers and fabric ops */
531 	sc->sc_maxcmds -= 2;
532 
533 	if (qle_alloc_ccbs(sc)) {
534 		/* error already printed */
535 		goto deintr;
536 	}
537 	sc->sc_scratch = qle_dmamem_alloc(sc, QLE_SCRATCH_SIZE);
538 	if (sc->sc_scratch == NULL) {
539 		printf("%s: unable to allocate scratch\n", DEVNAME(sc));
540 		goto free_ccbs;
541 	}
542 
543 	/* build init buffer thing */
544 	icb = (struct qle_init_cb *)QLE_DMA_KVA(sc->sc_scratch);
545 	memset(icb, 0, sizeof(*icb));
546 	icb->icb_version = QLE_ICB_VERSION;
547 	if (sc->sc_nvram_valid) {
548 		icb->icb_max_frame_len = sc->sc_nvram.frame_payload_size;
549 		icb->icb_exec_throttle = sc->sc_nvram.execution_throttle;
550 		icb->icb_hardaddr = sc->sc_nvram.hard_address;
551 		icb->icb_portname = sc->sc_nvram.port_name;
552 		icb->icb_nodename = sc->sc_nvram.node_name;
553 		icb->icb_login_retry = sc->sc_nvram.login_retry;
554 		icb->icb_login_timeout = sc->sc_nvram.login_timeout;
555 		icb->icb_fwoptions1 = sc->sc_nvram.fwoptions1;
556 		icb->icb_fwoptions2 = sc->sc_nvram.fwoptions2;
557 		icb->icb_fwoptions3 = sc->sc_nvram.fwoptions3;
558 	} else {
559 		/* defaults copied from isp(4) */
560 		htolem16(&icb->icb_max_frame_len, 1024);
561 		htolem16(&icb->icb_exec_throttle, 16);
562 		icb->icb_portname = htobe64(QLE_DEFAULT_PORT_NAME);
563 		icb->icb_nodename = 0;
564 		icb->icb_login_retry = 3;
565 
566 		htolem32(&icb->icb_fwoptions1, QLE_ICB_FW1_FAIRNESS |
567 		    QLE_ICB_FW1_HARD_ADDR | QLE_ICB_FW1_FULL_DUPLEX);
568 		htolem32(&icb->icb_fwoptions2, QLE_ICB_FW2_LOOP_PTP);
569 		htolem32(&icb->icb_fwoptions3, QLE_ICB_FW3_FCP_RSP_24_0 |
570 		    QLE_ICB_FW3_AUTONEG);
571 	}
572 
573 	icb->icb_exchange_count = 0;
574 
575 	icb->icb_req_out = 0;
576 	icb->icb_resp_in = 0;
577 	icb->icb_pri_req_out = 0;
578 	htolem16(&icb->icb_req_queue_len, sc->sc_maxcmds);
579 	htolem16(&icb->icb_resp_queue_len, sc->sc_maxcmds);
580 	htolem16(&icb->icb_pri_req_queue_len, 8); /* apparently the minimum */
581 	htolem32(&icb->icb_req_queue_addr_lo,
582 	    QLE_DMA_DVA(sc->sc_requests));
583 	htolem32(&icb->icb_req_queue_addr_hi,
584 	    QLE_DMA_DVA(sc->sc_requests) >> 32);
585 	htolem32(&icb->icb_resp_queue_addr_lo,
586 	    QLE_DMA_DVA(sc->sc_responses));
587 	htolem32(&icb->icb_resp_queue_addr_hi,
588 	    QLE_DMA_DVA(sc->sc_responses) >> 32);
589 	htolem32(&icb->icb_pri_req_queue_addr_lo,
590 	    QLE_DMA_DVA(sc->sc_pri_requests));
591 	htolem32(&icb->icb_pri_req_queue_addr_hi,
592 	    QLE_DMA_DVA(sc->sc_pri_requests) >> 32);
593 
594 	htolem16(&icb->icb_link_down_nos, 200);
595 	icb->icb_int_delay = 0;
596 	icb->icb_login_timeout = 0;
597 
598 	sc->sc_mbox[0] = QLE_MBOX_INIT_FIRMWARE;
599 	sc->sc_mbox[4] = 0;
600 	sc->sc_mbox[5] = 0;
601 	qle_mbox_putaddr(sc->sc_mbox, sc->sc_scratch);
602 	bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(sc->sc_scratch), 0,
603 	    sizeof(*icb), BUS_DMASYNC_PREWRITE);
604 	rv = qle_mbox(sc, 0x00fd);
605 	bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(sc->sc_scratch), 0,
606 	    sizeof(*icb), BUS_DMASYNC_POSTWRITE);
607 
608 	if (rv != 0) {
609 		printf("%s: ISP firmware init failed: %x\n", DEVNAME(sc),
610 		    sc->sc_mbox[0]);
611 		goto free_scratch;
612 	}
613 
614 	/* enable some more notifications */
615 	sc->sc_mbox[0] = QLE_MBOX_SET_FIRMWARE_OPTIONS;
616 	sc->sc_mbox[1] = QLE_FW_OPTION1_ASYNC_LIP_F8 |
617 	    QLE_FW_OPTION1_ASYNC_LIP_RESET |
618 	    QLE_FW_OPTION1_ASYNC_LIP_ERROR |
619 	    QLE_FW_OPTION1_ASYNC_LOGIN_RJT;
620 	sc->sc_mbox[2] = 0;
621 	sc->sc_mbox[3] = 0;
622 	if (qle_mbox(sc, 0x000f)) {
623 		printf("%s: setting firmware options failed: %x\n",
624 		    DEVNAME(sc), sc->sc_mbox[0]);
625 		goto free_scratch;
626 	}
627 
628 	sc->sc_update_taskq = taskq_create(DEVNAME(sc), 1, IPL_BIO);
629 	task_set(&sc->sc_update_task, qle_do_update, sc, NULL);
630 
631 	/* wait a bit for link to come up so we can scan and attach devices */
632 	for (i = 0; i < QLE_WAIT_FOR_LOOP * 10000; i++) {
633 		u_int16_t isr, info;
634 
635 		delay(100);
636 
637 		if (qle_read_isr(sc, &isr, &info) == 0)
638 			continue;
639 
640 		qle_handle_intr(sc, isr, info);
641 
642 		if (sc->sc_loop_up)
643 			break;
644 	}
645 
646 	if (sc->sc_loop_up) {
647 		qle_do_update(sc, NULL);
648 	} else {
649 		DPRINTF(QLE_D_PORT, "%s: loop still down, giving up\n",
650 		    DEVNAME(sc));
651 	}
652 
653 	/* we should be good to go now, attach scsibus */
654 	sc->sc_link.adapter = &qle_switch;
655 	sc->sc_link.adapter_softc = sc;
656 	sc->sc_link.adapter_target = QLE_MAX_TARGETS;
657 	sc->sc_link.adapter_buswidth = QLE_MAX_TARGETS;
658 	sc->sc_link.openings = sc->sc_maxcmds;
659 	sc->sc_link.pool = &sc->sc_iopool;
660 	if (sc->sc_nvram_valid) {
661 		sc->sc_link.port_wwn = betoh64(sc->sc_nvram.port_name);
662 		sc->sc_link.node_wwn = betoh64(sc->sc_nvram.node_name);
663 	} else {
664 		sc->sc_link.port_wwn = QLE_DEFAULT_PORT_NAME;
665 		sc->sc_link.node_wwn = 0;
666 	}
667 	if (sc->sc_link.node_wwn == 0) {
668 		/*
669 		 * mask out the port number from the port name to get
670 		 * the node name.
671 		 */
672 		sc->sc_link.node_wwn = sc->sc_link.port_wwn;
673 		sc->sc_link.node_wwn &= ~(0xfULL << 56);
674 	}
675 
676 	memset(&saa, 0, sizeof(saa));
677 	saa.saa_sc_link = &sc->sc_link;
678 
679 	/* config_found() returns the scsibus attached to us */
680 	sc->sc_scsibus = (struct scsibus_softc *)config_found(&sc->sc_dev,
681 	    &saa, scsiprint);
682 
683 	return;
684 
685 free_scratch:
686 	qle_dmamem_free(sc, sc->sc_scratch);
687 free_ccbs:
688 	qle_free_ccbs(sc);
689 deintr:
690 	pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
691 	sc->sc_ih = NULL;
692 unmap:
693 	bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
694 	sc->sc_ios = 0;
695 }
696 
697 int
698 qle_detach(struct device *self, int flags)
699 {
700 	struct qle_softc *sc = (struct qle_softc *)self;
701 
702 	if (sc->sc_ih == NULL) {
703 		/* we didnt attach properly, so nothing to detach */
704 		return (0);
705 	}
706 
707 	pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
708 	sc->sc_ih = NULL;
709 
710 	bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
711 	sc->sc_ios = 0;
712 
713 	return (0);
714 }
715 
716 int
717 qle_classify_port(struct qle_softc *sc, u_int32_t location,
718     u_int64_t port_name, u_int64_t node_name, struct qle_fc_port **prev)
719 {
720 	struct qle_fc_port *port, *locmatch, *wwnmatch;
721 	locmatch = NULL;
722 	wwnmatch = NULL;
723 
724 	/* make sure we don't try to add a port or location twice */
725 	TAILQ_FOREACH(port, &sc->sc_ports_new, update) {
726 		if ((port->port_name == port_name &&
727 		    port->node_name == node_name) ||
728 		    port->location == location) {
729 			*prev = port;
730 			return (QLE_PORT_DISP_DUP);
731 		}
732 	}
733 
734 	/* if we're attaching, everything is new */
735 	if (sc->sc_scsibus == NULL) {
736 		*prev = NULL;
737 		return (QLE_PORT_DISP_NEW);
738 	}
739 
740 	TAILQ_FOREACH(port, &sc->sc_ports, ports) {
741 		if (port->location == location)
742 			locmatch = port;
743 
744 		if (port->port_name == port_name &&
745 		    port->node_name == node_name)
746 			wwnmatch = port;
747 	}
748 
749 	if (locmatch == NULL && wwnmatch == NULL) {
750 		*prev = NULL;
751 		return (QLE_PORT_DISP_NEW);
752 	} else if (locmatch == wwnmatch) {
753 		*prev = locmatch;
754 		return (QLE_PORT_DISP_SAME);
755 	} else if (wwnmatch != NULL) {
756 		*prev = wwnmatch;
757 		return (QLE_PORT_DISP_MOVED);
758 	} else {
759 		*prev = locmatch;
760 		return (QLE_PORT_DISP_CHANGED);
761 	}
762 }
763 
764 int
765 qle_get_loop_id(struct qle_softc *sc, int start)
766 {
767 	int i, last;
768 
769 	i = QLE_MIN_HANDLE;
770 	last = QLE_MAX_HANDLE;
771 	if (i < start)
772 		i = start;
773 
774 	for (; i <= last; i++) {
775 		if (sc->sc_targets[i] == NULL)
776 			return (i);
777 	}
778 
779 	return (-1);
780 }
781 
782 int
783 qle_get_port_db(struct qle_softc *sc, u_int16_t loopid, struct qle_dmamem *mem)
784 {
785 	sc->sc_mbox[0] = QLE_MBOX_GET_PORT_DB;
786 	sc->sc_mbox[1] = loopid;
787 	qle_mbox_putaddr(sc->sc_mbox, mem);
788 	bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(mem), 0,
789 	    sizeof(struct qle_get_port_db), BUS_DMASYNC_PREREAD);
790 	if (qle_mbox(sc, 0x00cf)) {
791 		DPRINTF(QLE_D_PORT, "%s: get port db for %d failed: %x\n",
792 		    DEVNAME(sc), loopid, sc->sc_mbox[0]);
793 		return (1);
794 	}
795 
796 	bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(mem), 0,
797 	    sizeof(struct qle_get_port_db), BUS_DMASYNC_POSTREAD);
798 	return (0);
799 }
800 
801 int
802 qle_get_port_name_list(struct qle_softc *sc, u_int32_t match)
803 {
804 	struct qle_port_name_list *l;
805 	struct qle_fc_port *port;
806 	int i;
807 
808 	sc->sc_mbox[0] = QLE_MBOX_GET_PORT_NAME_LIST;
809 	sc->sc_mbox[1] = 0;
810 	sc->sc_mbox[8] = QLE_DMA_LEN(sc->sc_scratch);
811 	sc->sc_mbox[9] = 0;
812 	qle_mbox_putaddr(sc->sc_mbox, sc->sc_scratch);
813 	bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(sc->sc_scratch), 0,
814 	    QLE_DMA_LEN(sc->sc_scratch), BUS_DMASYNC_PREREAD);
815 	if (qle_mbox(sc, 0x03cf)) {
816 		DPRINTF(QLE_D_PORT, "%s: get port name list failed: %x\n",
817 		    DEVNAME(sc), sc->sc_mbox[0]);
818 		return (1);
819 	}
820 	bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(sc->sc_scratch), 0,
821 	    sc->sc_mbox[1], BUS_DMASYNC_POSTREAD);
822 
823 	i = 0;
824 	l = QLE_DMA_KVA(sc->sc_scratch);
825 	mtx_enter(&sc->sc_port_mtx);
826 	while (i * sizeof(*l) < sc->sc_mbox[1]) {
827 		u_int16_t loopid;
828 		u_int32_t loc;
829 
830 		loopid = lemtoh16(&l[i].loopid) & 0xfff;
831 		/* skip special ports */
832 		switch (loopid) {
833 		case QLE_F_PORT_HANDLE:
834 		case QLE_SNS_HANDLE:
835 		case QLE_FABRIC_CTRL_HANDLE:
836 		case QLE_IP_BCAST_HANDLE:
837 			loc = 0;
838 			break;
839 		default:
840 			if (loopid <= sc->sc_loop_max_id) {
841 				loc = QLE_LOCATION_LOOP_ID(loopid);
842 			} else {
843 				/*
844 				 * we don't have the port id here, so just
845 				 * indicate it's a fabric port.
846 				 */
847 				loc = QLE_LOCATION_FABRIC;
848 			}
849 			break;
850 		}
851 
852 		if (match & loc) {
853 			port = malloc(sizeof(*port), M_DEVBUF, M_ZERO |
854 			    M_NOWAIT);
855 			if (port == NULL) {
856 				printf("%s: failed to allocate port struct\n",
857 				    DEVNAME(sc));
858 				break;
859 			}
860 			port->location = loc;
861 			port->loopid = loopid;
862 			port->port_name = letoh64(l[i].port_name);
863 			DPRINTF(QLE_D_PORT, "%s: loop id %d, port name %llx\n",
864 			    DEVNAME(sc), port->loopid, port->port_name);
865 			TAILQ_INSERT_TAIL(&sc->sc_ports_found, port, update);
866 		}
867 		i++;
868 	}
869 	mtx_leave(&sc->sc_port_mtx);
870 
871 	return (0);
872 }
873 
874 int
875 qle_add_loop_port(struct qle_softc *sc, struct qle_fc_port *port)
876 {
877 	struct qle_get_port_db *pdb;
878 	struct qle_fc_port *pport;
879 	int disp;
880 
881 	if (qle_get_port_db(sc, port->loopid, sc->sc_scratch) != 0) {
882 		return (1);
883 	}
884 	pdb = QLE_DMA_KVA(sc->sc_scratch);
885 
886 	if (lemtoh16(&pdb->prli_svc_word3) & QLE_SVC3_TARGET_ROLE)
887 		port->flags |= QLE_PORT_FLAG_IS_TARGET;
888 
889 	port->port_name = betoh64(pdb->port_name);
890 	port->node_name = betoh64(pdb->node_name);
891 	port->portid = (pdb->port_id[0] << 16) | (pdb->port_id[1] << 8) |
892 	    pdb->port_id[2];
893 
894 	mtx_enter(&sc->sc_port_mtx);
895 	disp = qle_classify_port(sc, port->location, port->port_name,
896 	    port->node_name, &pport);
897 	switch (disp) {
898 	case QLE_PORT_DISP_CHANGED:
899 	case QLE_PORT_DISP_MOVED:
900 	case QLE_PORT_DISP_NEW:
901 		TAILQ_INSERT_TAIL(&sc->sc_ports_new, port, update);
902 		sc->sc_targets[port->loopid] = port;
903 		break;
904 	case QLE_PORT_DISP_DUP:
905 		free(port, M_DEVBUF, 0);
906 		break;
907 	case QLE_PORT_DISP_SAME:
908 		TAILQ_REMOVE(&sc->sc_ports_gone, pport, update);
909 		free(port, M_DEVBUF, 0);
910 		break;
911 	}
912 	mtx_leave(&sc->sc_port_mtx);
913 
914 	switch (disp) {
915 	case QLE_PORT_DISP_CHANGED:
916 	case QLE_PORT_DISP_MOVED:
917 	case QLE_PORT_DISP_NEW:
918 		DPRINTF(QLE_D_PORT, "%s: %s %d; name %llx\n",
919 		    DEVNAME(sc), ISSET(port->flags, QLE_PORT_FLAG_IS_TARGET) ?
920 		    "target" : "non-target", port->loopid,
921 		    betoh64(pdb->port_name));
922 		break;
923 	default:
924 		break;
925 	}
926 	return (0);
927 }
928 
929 int
930 qle_add_fabric_port(struct qle_softc *sc, struct qle_fc_port *port)
931 {
932 	struct qle_get_port_db *pdb;
933 
934 	if (qle_get_port_db(sc, port->loopid, sc->sc_scratch) != 0) {
935 		free(port, M_DEVBUF, 0);
936 		return (1);
937 	}
938 	pdb = QLE_DMA_KVA(sc->sc_scratch);
939 
940 	if (lemtoh16(&pdb->prli_svc_word3) & QLE_SVC3_TARGET_ROLE)
941 		port->flags |= QLE_PORT_FLAG_IS_TARGET;
942 
943 	/*
944 	 * if we only know about this port because qle_get_port_name_list
945 	 * returned it, we don't have its port id or node name, so fill
946 	 * those in and update its location.
947 	 */
948 	if (port->location == QLE_LOCATION_FABRIC) {
949 		port->node_name = betoh64(pdb->node_name);
950 		port->port_name = betoh64(pdb->port_name);
951 		port->portid = (pdb->port_id[0] << 16) |
952 		    (pdb->port_id[1] << 8) | pdb->port_id[2];
953 		port->location = QLE_LOCATION_PORT_ID(port->portid);
954 	}
955 
956 	mtx_enter(&sc->sc_port_mtx);
957 	TAILQ_INSERT_TAIL(&sc->sc_ports_new, port, update);
958 	sc->sc_targets[port->loopid] = port;
959 	mtx_leave(&sc->sc_port_mtx);
960 
961 	DPRINTF(QLE_D_PORT, "%s: %s %d; name %llx\n",
962 	    DEVNAME(sc), ISSET(port->flags, QLE_PORT_FLAG_IS_TARGET) ?
963 	    "target" : "non-target", port->loopid, port->port_name);
964 	return (0);
965 }
966 
967 int
968 qle_add_logged_in_port(struct qle_softc *sc, u_int16_t loopid,
969     u_int32_t portid)
970 {
971 	struct qle_fc_port *port;
972 	struct qle_get_port_db *pdb;
973 	u_int64_t node_name, port_name;
974 	int flags, ret;
975 
976 	ret = qle_get_port_db(sc, loopid, sc->sc_scratch);
977 	mtx_enter(&sc->sc_port_mtx);
978 	if (ret != 0) {
979 		/* put in a fake port to prevent use of this loop id */
980 		printf("%s: loop id %d used, but can't see what's using it\n",
981 		    DEVNAME(sc), loopid);
982 		node_name = 0;
983 		port_name = 0;
984 		flags = 0;
985 	} else {
986 		pdb = QLE_DMA_KVA(sc->sc_scratch);
987 		node_name = betoh64(pdb->node_name);
988 		port_name = betoh64(pdb->port_name);
989 		flags = 0;
990 		if (lemtoh16(&pdb->prli_svc_word3) & QLE_SVC3_TARGET_ROLE)
991 			flags |= QLE_PORT_FLAG_IS_TARGET;
992 
993 		/* see if we've already found this port */
994 		TAILQ_FOREACH(port, &sc->sc_ports_found, update) {
995 			if ((port->node_name == node_name) &&
996 			    (port->port_name == port_name) &&
997 			    (port->portid == portid)) {
998 				mtx_leave(&sc->sc_port_mtx);
999 				DPRINTF(QLE_D_PORT, "%s: already found port "
1000 				    "%06x\n", DEVNAME(sc), portid);
1001 				return (0);
1002 			}
1003 		}
1004 	}
1005 
1006 	port = malloc(sizeof(*port), M_DEVBUF, M_ZERO | M_NOWAIT);
1007 	if (port == NULL) {
1008 		mtx_leave(&sc->sc_port_mtx);
1009 		printf("%s: failed to allocate a port structure\n",
1010 		    DEVNAME(sc));
1011 		return (1);
1012 	}
1013 	port->location = QLE_LOCATION_PORT_ID(portid);
1014 	port->port_name = port_name;
1015 	port->node_name = node_name;
1016 	port->loopid = loopid;
1017 	port->portid = portid;
1018 	port->flags = flags;
1019 
1020 	TAILQ_INSERT_TAIL(&sc->sc_ports, port, ports);
1021 	sc->sc_targets[port->loopid] = port;
1022 	mtx_leave(&sc->sc_port_mtx);
1023 
1024 	DPRINTF(QLE_D_PORT, "%s: added logged in port %06x at %d\n",
1025 	    DEVNAME(sc), portid, loopid);
1026 	return (0);
1027 }
1028 
1029 struct qle_ccb *
1030 qle_handle_resp(struct qle_softc *sc, u_int32_t id)
1031 {
1032 	struct qle_ccb *ccb;
1033 	struct qle_iocb_status *status;
1034 	struct qle_iocb_req6 *req;
1035 	struct scsi_xfer *xs;
1036 	u_int32_t handle;
1037 	u_int16_t completion;
1038 	u_int8_t *entry;
1039 	u_int8_t *data;
1040 
1041 	ccb = NULL;
1042 	entry = QLE_DMA_KVA(sc->sc_responses) + (id * QLE_QUEUE_ENTRY_SIZE);
1043 
1044 	bus_dmamap_sync(sc->sc_dmat,
1045 	    QLE_DMA_MAP(sc->sc_responses), id * QLE_QUEUE_ENTRY_SIZE,
1046 	    QLE_QUEUE_ENTRY_SIZE, BUS_DMASYNC_POSTREAD);
1047 
1048 	qle_dump_iocb(sc, entry);
1049 	switch(entry[0]) {
1050 	case QLE_IOCB_STATUS:
1051 		status = (struct qle_iocb_status *)entry;
1052 		handle = status->handle;
1053 		if (handle > sc->sc_maxcmds) {
1054 			panic("bad completed command handle: %d (> %d)",
1055 			    handle, sc->sc_maxcmds);
1056 		}
1057 
1058 		ccb = &sc->sc_ccbs[handle];
1059 		xs = ccb->ccb_xs;
1060 		if (xs == NULL) {
1061 			DPRINTF(QLE_D_IO, "%s: got status for inactive ccb %d\n",
1062 			    DEVNAME(sc), handle);
1063 			ccb = NULL;
1064 			break;
1065 		}
1066 		if (xs->io != ccb) {
1067 			panic("completed command handle doesn't match xs "
1068 			    "(handle %d, ccb %p, xs->io %p)", handle, ccb,
1069 			    xs->io);
1070 		}
1071 		qle_dump_iocb(sc, status);
1072 
1073 		if (xs->datalen > 0) {
1074 			if (ccb->ccb_dmamap->dm_nsegs >
1075 			    QLE_IOCB_SEGS_PER_CMD) {
1076 				bus_dmamap_sync(sc->sc_dmat,
1077 				    QLE_DMA_MAP(sc->sc_segments),
1078 				    ccb->ccb_seg_offset,
1079 				    sizeof(*ccb->ccb_segs) *
1080 				    ccb->ccb_dmamap->dm_nsegs,
1081 				    BUS_DMASYNC_POSTWRITE);
1082 			}
1083 
1084 			bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmamap, 0,
1085 			    ccb->ccb_dmamap->dm_mapsize,
1086 			    (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
1087 			    BUS_DMASYNC_POSTWRITE);
1088 			bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmamap);
1089 		}
1090 
1091 		xs->status = lemtoh16(&status->scsi_status) & 0x0f;
1092 		completion = lemtoh16(&status->completion);
1093 		switch (completion) {
1094 		case QLE_IOCB_STATUS_DATA_OVERRUN:
1095 		case QLE_IOCB_STATUS_DATA_UNDERRUN:
1096 		case QLE_IOCB_STATUS_COMPLETE:
1097 			if (completion == QLE_IOCB_STATUS_COMPLETE) {
1098 				xs->resid = 0;
1099 			} else {
1100 				xs->resid = lemtoh32(&status->resid);
1101 			}
1102 
1103 			if (lemtoh16(&status->scsi_status) &
1104 			    QLE_SCSI_STATUS_SENSE_VALID) {
1105 				u_int32_t *pp;
1106 				int sr;
1107 				data = status->data +
1108 				    lemtoh32(&status->fcp_rsp_len);
1109 				memcpy(&xs->sense, data,
1110 				    lemtoh32(&status->fcp_sense_len));
1111 				xs->error = XS_SENSE;
1112 				pp = (u_int32_t *)&xs->sense;
1113 				for (sr = 0; sr < sizeof(xs->sense)/4; sr++) {
1114 					pp[sr] = swap32(pp[sr]);
1115 				}
1116 			} else {
1117 				xs->error = XS_NOERROR;
1118 			}
1119 			break;
1120 
1121 		case QLE_IOCB_STATUS_DMA_ERROR:
1122 			DPRINTF(QLE_D_IO, "%s: dma error\n", DEVNAME(sc));
1123 			/* set resid apparently? */
1124 			break;
1125 
1126 		case QLE_IOCB_STATUS_RESET:
1127 			DPRINTF(QLE_D_IO, "%s: reset destroyed command\n",
1128 			    DEVNAME(sc));
1129 			sc->sc_marker_required = 1;
1130 			xs->error = XS_RESET;
1131 			break;
1132 
1133 		case QLE_IOCB_STATUS_ABORTED:
1134 			DPRINTF(QLE_D_IO, "%s: aborted\n", DEVNAME(sc));
1135 			sc->sc_marker_required = 1;
1136 			xs->error = XS_DRIVER_STUFFUP;
1137 			break;
1138 
1139 		case QLE_IOCB_STATUS_TIMEOUT:
1140 			DPRINTF(QLE_D_IO, "%s: command timed out\n",
1141 			    DEVNAME(sc));
1142 			xs->error = XS_TIMEOUT;
1143 			break;
1144 
1145 		case QLE_IOCB_STATUS_QUEUE_FULL:
1146 			DPRINTF(QLE_D_IO, "%s: queue full\n", DEVNAME(sc));
1147 			xs->error = XS_BUSY;
1148 			break;
1149 
1150 		case QLE_IOCB_STATUS_PORT_UNAVAIL:
1151 		case QLE_IOCB_STATUS_PORT_LOGGED_OUT:
1152 		case QLE_IOCB_STATUS_PORT_CHANGED:
1153 			DPRINTF(QLE_D_IO, "%s: dev gone\n", DEVNAME(sc));
1154 			xs->error = XS_SELTIMEOUT;
1155 			/* mark port as needing relogin? */
1156 			break;
1157 
1158 		default:
1159 			DPRINTF(QLE_D_IO, "%s: unexpected completion status "
1160 			    "%x\n", DEVNAME(sc), status->completion);
1161 			xs->error = XS_DRIVER_STUFFUP;
1162 			break;
1163 		}
1164 		break;
1165 
1166 	case QLE_IOCB_STATUS_CONT:
1167 		DPRINTF(QLE_D_IO, "%s: ignoring status continuation iocb\n",
1168 		    DEVNAME(sc));
1169 		break;
1170 
1171 	case QLE_IOCB_PLOGX:
1172 	case QLE_IOCB_CT_PASSTHROUGH:
1173 		if (sc->sc_fabric_pending) {
1174 			qle_dump_iocb(sc, entry);
1175 			memcpy(sc->sc_fabric_response, entry,
1176 			    QLE_QUEUE_ENTRY_SIZE);
1177 			sc->sc_fabric_pending = 2;
1178 			wakeup(sc->sc_scratch);
1179 		} else {
1180 			DPRINTF(QLE_D_IO, "%s: unexpected fabric response %x\n",
1181 			    DEVNAME(sc), entry[0]);
1182 		}
1183 		break;
1184 
1185 	case QLE_IOCB_MARKER:
1186 		break;
1187 
1188 	case QLE_IOCB_CMD_TYPE_6:
1189 	case QLE_IOCB_CMD_TYPE_7:
1190 		DPRINTF(QLE_D_IO, "%s: request bounced back\n", DEVNAME(sc));
1191 		req = (struct qle_iocb_req6 *)entry;
1192 		handle = req->req_handle;
1193 		if (handle > sc->sc_maxcmds) {
1194 			panic("bad bounced command handle: %d (> %d)",
1195 			    handle, sc->sc_maxcmds);
1196 		}
1197 
1198 		ccb = &sc->sc_ccbs[handle];
1199 		xs = ccb->ccb_xs;
1200 		xs->error = XS_DRIVER_STUFFUP;
1201 		break;
1202 	default:
1203 		DPRINTF(QLE_D_IO, "%s: unexpected response entry type %x\n",
1204 		    DEVNAME(sc), entry[0]);
1205 		break;
1206 	}
1207 
1208 	return (ccb);
1209 }
1210 
1211 void
1212 qle_handle_intr(struct qle_softc *sc, u_int16_t isr, u_int16_t info)
1213 {
1214 	int i;
1215 	u_int32_t rspin;
1216 	struct qle_ccb *ccb;
1217 
1218 	switch (isr) {
1219 	case QLE_INT_TYPE_ASYNC:
1220 		qle_async(sc, info);
1221 		break;
1222 
1223 	case QLE_INT_TYPE_IO:
1224 		rspin = qle_read(sc, QLE_RESP_IN);
1225 		if (rspin == sc->sc_last_resp_id)
1226 			break;
1227 
1228 		do {
1229 			ccb = qle_handle_resp(sc, sc->sc_last_resp_id);
1230 			if (ccb)
1231 				scsi_done(ccb->ccb_xs);
1232 
1233 			sc->sc_last_resp_id++;
1234 			sc->sc_last_resp_id %= sc->sc_maxcmds;
1235 		} while (sc->sc_last_resp_id != rspin);
1236 
1237 		qle_write(sc, QLE_RESP_OUT, sc->sc_last_resp_id);
1238 		break;
1239 
1240 	case QLE_INT_TYPE_MBOX:
1241 		mtx_enter(&sc->sc_mbox_mtx);
1242 		if (sc->sc_mbox_pending) {
1243 			for (i = 0; i < nitems(sc->sc_mbox); i++) {
1244 				sc->sc_mbox[i] = qle_read_mbox(sc, i);
1245 			}
1246 			sc->sc_mbox_pending = 2;
1247 			wakeup(sc->sc_mbox);
1248 			mtx_leave(&sc->sc_mbox_mtx);
1249 		} else {
1250 			mtx_leave(&sc->sc_mbox_mtx);
1251 			DPRINTF(QLE_D_INTR, "%s: unexpected mbox interrupt: "
1252 			    "%x\n", DEVNAME(sc), info);
1253 		}
1254 		break;
1255 
1256 	default:
1257 		break;
1258 	}
1259 
1260 	qle_clear_isr(sc, isr);
1261 }
1262 
1263 int
1264 qle_intr(void *xsc)
1265 {
1266 	struct qle_softc *sc = xsc;
1267 	u_int16_t isr;
1268 	u_int16_t info;
1269 
1270 	if (qle_read_isr(sc, &isr, &info) == 0)
1271 		return (0);
1272 
1273 	qle_handle_intr(sc, isr, info);
1274 	return (1);
1275 }
1276 
1277 int
1278 qle_scsi_probe(struct scsi_link *link)
1279 {
1280 	struct qle_softc *sc = link->adapter_softc;
1281 	int rv = 0;
1282 
1283 	mtx_enter(&sc->sc_port_mtx);
1284 	if (sc->sc_targets[link->target] == NULL)
1285 		rv = ENXIO;
1286 	else if (!ISSET(sc->sc_targets[link->target]->flags,
1287 	    QLE_PORT_FLAG_IS_TARGET))
1288 		rv = ENXIO;
1289 	mtx_leave(&sc->sc_port_mtx);
1290 
1291 	return (rv);
1292 }
1293 
1294 void
1295 qle_scsi_cmd(struct scsi_xfer *xs)
1296 {
1297 	struct scsi_link	*link = xs->sc_link;
1298 	struct qle_softc	*sc = link->adapter_softc;
1299 	struct qle_ccb		*ccb;
1300 	void			*iocb;
1301 	struct qle_ccb_list	list;
1302 	u_int16_t		req;
1303 	u_int32_t		portid;
1304 	int			offset, error, done;
1305 	bus_dmamap_t		dmap;
1306 
1307 	if (xs->cmdlen > 16) {
1308 		DPRINTF(QLE_D_IO, "%s: cmd too big (%d)\n", DEVNAME(sc),
1309 		    xs->cmdlen);
1310 		memset(&xs->sense, 0, sizeof(xs->sense));
1311 		xs->sense.error_code = SSD_ERRCODE_VALID | SSD_ERRCODE_CURRENT;
1312 		xs->sense.flags = SKEY_ILLEGAL_REQUEST;
1313 		xs->sense.add_sense_code = 0x20;
1314 		xs->error = XS_SENSE;
1315 		scsi_done(xs);
1316 		return;
1317 	}
1318 
1319 	portid = 0xffffffff;
1320 	mtx_enter(&sc->sc_port_mtx);
1321 	if (sc->sc_targets[xs->sc_link->target] != NULL) {
1322 		portid = sc->sc_targets[xs->sc_link->target]->portid;
1323 	}
1324 	mtx_leave(&sc->sc_port_mtx);
1325 	if (portid == 0xffffffff) {
1326 		xs->error = XS_DRIVER_STUFFUP;
1327 		scsi_done(xs);
1328 		return;
1329 	}
1330 
1331 	ccb = xs->io;
1332 	dmap = ccb->ccb_dmamap;
1333 	if (xs->datalen > 0) {
1334 		error = bus_dmamap_load(sc->sc_dmat, dmap, xs->data,
1335 		    xs->datalen, NULL, (xs->flags & SCSI_NOSLEEP) ?
1336 		    BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
1337 		if (error) {
1338 			xs->error = XS_DRIVER_STUFFUP;
1339 			scsi_done(xs);
1340 			return;
1341 		}
1342 
1343 		bus_dmamap_sync(sc->sc_dmat, dmap, 0,
1344 		    dmap->dm_mapsize,
1345 		    (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
1346 		    BUS_DMASYNC_PREWRITE);
1347 	}
1348 
1349 	mtx_enter(&sc->sc_queue_mtx);
1350 
1351 	/* put in a sync marker if required */
1352 	if (sc->sc_marker_required) {
1353 		req = sc->sc_next_req_id++;
1354 		if (sc->sc_next_req_id == sc->sc_maxcmds)
1355 			sc->sc_next_req_id = 0;
1356 
1357 		DPRINTF(QLE_D_IO, "%s: writing marker at request %d\n",
1358 		    DEVNAME(sc), req);
1359 		offset = (req * QLE_QUEUE_ENTRY_SIZE);
1360 		iocb = QLE_DMA_KVA(sc->sc_requests) + offset;
1361 		bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(sc->sc_requests),
1362 		    offset, QLE_QUEUE_ENTRY_SIZE, BUS_DMASYNC_POSTWRITE);
1363 		qle_put_marker(sc, iocb);
1364 		qle_write(sc, QLE_REQ_IN, sc->sc_next_req_id);
1365 		sc->sc_marker_required = 0;
1366 	}
1367 
1368 	req = sc->sc_next_req_id++;
1369 	if (sc->sc_next_req_id == sc->sc_maxcmds)
1370 		sc->sc_next_req_id = 0;
1371 
1372 	offset = (req * QLE_QUEUE_ENTRY_SIZE);
1373 	iocb = QLE_DMA_KVA(sc->sc_requests) + offset;
1374 	bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(sc->sc_requests), offset,
1375 	    QLE_QUEUE_ENTRY_SIZE, BUS_DMASYNC_POSTWRITE);
1376 
1377 	ccb->ccb_xs = xs;
1378 
1379 	qle_put_cmd(sc, iocb, xs, ccb, portid);
1380 
1381 	bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(sc->sc_requests), offset,
1382 	    QLE_QUEUE_ENTRY_SIZE, BUS_DMASYNC_PREREAD);
1383 	qle_write(sc, QLE_REQ_IN, sc->sc_next_req_id);
1384 
1385 	if (!ISSET(xs->flags, SCSI_POLL)) {
1386 		mtx_leave(&sc->sc_queue_mtx);
1387 		return;
1388 	}
1389 
1390 	done = 0;
1391 	SIMPLEQ_INIT(&list);
1392 	do {
1393 		u_int16_t isr, info;
1394 		u_int32_t rspin;
1395 		delay(100);
1396 
1397 		if (qle_read_isr(sc, &isr, &info) == 0) {
1398 			continue;
1399 		}
1400 
1401 		if (isr != QLE_INT_TYPE_IO) {
1402 			qle_handle_intr(sc, isr, info);
1403 			continue;
1404 		}
1405 
1406 		rspin = qle_read(sc, QLE_RESP_IN);
1407 		while (rspin != sc->sc_last_resp_id) {
1408 			ccb = qle_handle_resp(sc, sc->sc_last_resp_id);
1409 
1410 			sc->sc_last_resp_id++;
1411 			if (sc->sc_last_resp_id == sc->sc_maxcmds)
1412 				sc->sc_last_resp_id = 0;
1413 
1414 			if (ccb != NULL)
1415 				SIMPLEQ_INSERT_TAIL(&list, ccb, ccb_link);
1416 			if (ccb == xs->io)
1417 				done = 1;
1418 		}
1419 		qle_write(sc, QLE_RESP_OUT, sc->sc_last_resp_id);
1420 		qle_clear_isr(sc, isr);
1421 	} while (done == 0);
1422 
1423 	mtx_leave(&sc->sc_queue_mtx);
1424 
1425 	while ((ccb = SIMPLEQ_FIRST(&list)) != NULL) {
1426 		SIMPLEQ_REMOVE_HEAD(&list, ccb_link);
1427 		scsi_done(ccb->ccb_xs);
1428 	}
1429 }
1430 
1431 u_int32_t
1432 qle_read(struct qle_softc *sc, int offset)
1433 {
1434 	u_int32_t v;
1435 	v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, offset);
1436 	bus_space_barrier(sc->sc_iot, sc->sc_ioh, offset, 4,
1437 	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
1438 	return (v);
1439 }
1440 
1441 void
1442 qle_write(struct qle_softc *sc, int offset, u_int32_t value)
1443 {
1444 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, offset, value);
1445 	bus_space_barrier(sc->sc_iot, sc->sc_ioh, offset, 4,
1446 	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
1447 }
1448 
1449 u_int16_t
1450 qle_read_mbox(struct qle_softc *sc, int mbox)
1451 {
1452 	u_int16_t v;
1453 	bus_size_t offset = mbox * 2;
1454 	v = bus_space_read_2(sc->sc_iot, sc->sc_mbox_ioh, offset);
1455 	bus_space_barrier(sc->sc_iot, sc->sc_mbox_ioh, offset, 2,
1456 	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
1457 	return (v);
1458 }
1459 
1460 void
1461 qle_write_mbox(struct qle_softc *sc, int mbox, u_int16_t value)
1462 {
1463 	bus_size_t offset = (mbox * 2);
1464 	bus_space_write_2(sc->sc_iot, sc->sc_mbox_ioh, offset, value);
1465 	bus_space_barrier(sc->sc_iot, sc->sc_mbox_ioh, offset, 2,
1466 	    BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
1467 }
1468 
1469 void
1470 qle_host_cmd(struct qle_softc *sc, u_int32_t cmd)
1471 {
1472 	qle_write(sc, QLE_HOST_CMD_CTRL, cmd << QLE_HOST_CMD_SHIFT);
1473 }
1474 
1475 #define MBOX_COMMAND_TIMEOUT	400000
1476 
1477 int
1478 qle_mbox(struct qle_softc *sc, int maskin)
1479 {
1480 	int i;
1481 	int result = 0;
1482 	int rv;
1483 
1484 	for (i = 0; i < nitems(sc->sc_mbox); i++) {
1485 		if (maskin & (1 << i)) {
1486 			qle_write_mbox(sc, i, sc->sc_mbox[i]);
1487 		}
1488 	}
1489 	qle_host_cmd(sc, QLE_HOST_CMD_SET_HOST_INT);
1490 
1491 	if (sc->sc_scsibus != NULL) {
1492 		mtx_enter(&sc->sc_mbox_mtx);
1493 		sc->sc_mbox_pending = 1;
1494 		while (sc->sc_mbox_pending == 1) {
1495 			msleep(sc->sc_mbox, &sc->sc_mbox_mtx, PRIBIO,
1496 			    "qlembox", 0);
1497 		}
1498 		result = sc->sc_mbox[0];
1499 		sc->sc_mbox_pending = 0;
1500 		mtx_leave(&sc->sc_mbox_mtx);
1501 		return (result == QLE_MBOX_COMPLETE ? 0 : result);
1502 	}
1503 
1504 	for (i = 0; i < MBOX_COMMAND_TIMEOUT && result == 0; i++) {
1505 		u_int16_t isr, info;
1506 
1507 		delay(100);
1508 
1509 		if (qle_read_isr(sc, &isr, &info) == 0)
1510 			continue;
1511 
1512 		switch (isr) {
1513 		case QLE_INT_TYPE_MBOX:
1514 			result = info;
1515 			break;
1516 
1517 		default:
1518 			qle_handle_intr(sc, isr, info);
1519 			break;
1520 		}
1521 	}
1522 
1523 	if (result == 0) {
1524 		/* timed out; do something? */
1525 		DPRINTF(QLE_D_MBOX, "%s: mbox timed out\n", DEVNAME(sc));
1526 		rv = 1;
1527 	} else {
1528 		for (i = 0; i < nitems(sc->sc_mbox); i++) {
1529 			sc->sc_mbox[i] = qle_read_mbox(sc, i);
1530 		}
1531 		rv = (result == QLE_MBOX_COMPLETE ? 0 : result);
1532 	}
1533 
1534 	qle_clear_isr(sc, QLE_INT_TYPE_MBOX);
1535 	return (rv);
1536 }
1537 
1538 void
1539 qle_mbox_putaddr(u_int16_t *mbox, struct qle_dmamem *mem)
1540 {
1541 	mbox[2] = (QLE_DMA_DVA(mem) >> 16) & 0xffff;
1542 	mbox[3] = (QLE_DMA_DVA(mem) >> 0) & 0xffff;
1543 	mbox[6] = (QLE_DMA_DVA(mem) >> 48) & 0xffff;
1544 	mbox[7] = (QLE_DMA_DVA(mem) >> 32) & 0xffff;
1545 }
1546 
1547 void
1548 qle_set_ints(struct qle_softc *sc, int enabled)
1549 {
1550 	u_int32_t v = enabled ? QLE_INT_CTRL_ENABLE : 0;
1551 	qle_write(sc, QLE_INT_CTRL, v);
1552 }
1553 
1554 int
1555 qle_read_isr(struct qle_softc *sc, u_int16_t *isr, u_int16_t *info)
1556 {
1557 	u_int32_t v;
1558 
1559 	switch (sc->sc_isp_gen) {
1560 	case QLE_GEN_ISP24XX:
1561 	case QLE_GEN_ISP25XX:
1562 		if ((qle_read(sc, QLE_INT_STATUS) & QLE_RISC_INT_REQ) == 0)
1563 			return (0);
1564 
1565 		v = qle_read(sc, QLE_RISC_STATUS);
1566 
1567 		switch (v & QLE_INT_STATUS_MASK) {
1568 		case QLE_24XX_INT_ROM_MBOX:
1569 		case QLE_24XX_INT_ROM_MBOX_FAIL:
1570 		case QLE_24XX_INT_MBOX:
1571 		case QLE_24XX_INT_MBOX_FAIL:
1572 			*isr = QLE_INT_TYPE_MBOX;
1573 			break;
1574 
1575 		case QLE_24XX_INT_ASYNC:
1576 			*isr = QLE_INT_TYPE_ASYNC;
1577 			break;
1578 
1579 		case QLE_24XX_INT_RSPQ:
1580 			*isr = QLE_INT_TYPE_IO;
1581 			break;
1582 
1583 		default:
1584 			*isr = QLE_INT_TYPE_OTHER;
1585 			break;
1586 		}
1587 
1588 		*info = (v >> QLE_INT_INFO_SHIFT);
1589 		return (1);
1590 
1591 	default:
1592 		return (0);
1593 	}
1594 }
1595 
1596 void
1597 qle_clear_isr(struct qle_softc *sc, u_int16_t isr)
1598 {
1599 	qle_host_cmd(sc, QLE_HOST_CMD_CLR_RISC_INT);
1600 }
1601 
1602 void
1603 qle_update_done(struct qle_softc *sc, int task)
1604 {
1605 	atomic_clearbits_int(&sc->sc_update_tasks, task);
1606 }
1607 
1608 void
1609 qle_update_start(struct qle_softc *sc, int task)
1610 {
1611 	atomic_setbits_int(&sc->sc_update_tasks, task);
1612 	task_add(sc->sc_update_taskq, &sc->sc_update_task);
1613 }
1614 
1615 void
1616 qle_clear_port_lists(struct qle_softc *sc)
1617 {
1618 	struct qle_fc_port *p;
1619 	while (!TAILQ_EMPTY(&sc->sc_ports_found)) {
1620 		p = TAILQ_FIRST(&sc->sc_ports_found);
1621 		TAILQ_REMOVE(&sc->sc_ports_found, p, update);
1622 		free(p, M_DEVBUF, 0);
1623 	}
1624 
1625 	while (!TAILQ_EMPTY(&sc->sc_ports_new)) {
1626 		p = TAILQ_FIRST(&sc->sc_ports_new);
1627 		TAILQ_REMOVE(&sc->sc_ports_new, p, update);
1628 		free(p, M_DEVBUF, 0);
1629 	}
1630 
1631 	while (!TAILQ_EMPTY(&sc->sc_ports_gone)) {
1632 		p = TAILQ_FIRST(&sc->sc_ports_gone);
1633 		TAILQ_REMOVE(&sc->sc_ports_gone, p, update);
1634 	}
1635 }
1636 
1637 int
1638 qle_softreset(struct qle_softc *sc)
1639 {
1640 	int i;
1641 	qle_set_ints(sc, 0);
1642 
1643 	/* set led control bits, stop dma */
1644 	qle_write(sc, QLE_GPIO_DATA, 0);
1645 	qle_write(sc, QLE_CTRL_STATUS, QLE_CTRL_DMA_SHUTDOWN);
1646 	while (qle_read(sc, QLE_CTRL_STATUS) & QLE_CTRL_DMA_ACTIVE) {
1647 		DPRINTF(QLE_D_IO, "%s: dma still active\n", DEVNAME(sc));
1648 		delay(100);
1649 	}
1650 
1651 	/* reset */
1652 	qle_write(sc, QLE_CTRL_STATUS, QLE_CTRL_RESET | QLE_CTRL_DMA_SHUTDOWN);
1653 	delay(100);
1654 	/* clear data and control dma engines? */
1655 
1656 	/* wait for soft reset to clear */
1657 	for (i = 0; i < 1000; i++) {
1658 		if (qle_read_mbox(sc, 0) == 0x0000)
1659 			break;
1660 
1661 		delay(100);
1662 	}
1663 
1664 	if (i == 1000) {
1665 		printf("%s: reset mbox didn't clear\n", DEVNAME(sc));
1666 		qle_set_ints(sc, 0);
1667 		return (ENXIO);
1668 	}
1669 
1670 	for (i = 0; i < 500000; i++) {
1671 		if ((qle_read(sc, QLE_CTRL_STATUS) & QLE_CTRL_RESET) == 0)
1672 			break;
1673 		delay(5);
1674 	}
1675 	if (i == 500000) {
1676 		printf("%s: reset status didn't clear\n", DEVNAME(sc));
1677 		return (ENXIO);
1678 	}
1679 
1680 	/* reset risc processor */
1681 	qle_host_cmd(sc, QLE_HOST_CMD_RESET);
1682 	qle_host_cmd(sc, QLE_HOST_CMD_RELEASE);
1683 	qle_host_cmd(sc, QLE_HOST_CMD_CLEAR_RESET);
1684 
1685 	/* wait for reset to clear */
1686 	for (i = 0; i < 1000; i++) {
1687 		if (qle_read_mbox(sc, 0) == 0x0000)
1688 			break;
1689 		delay(100);
1690 	}
1691 	if (i == 1000) {
1692 		printf("%s: risc not ready after reset\n", DEVNAME(sc));
1693 		return (ENXIO);
1694 	}
1695 
1696 	/* reset queue pointers */
1697 	qle_write(sc, QLE_REQ_IN, 0);
1698 	qle_write(sc, QLE_REQ_OUT, 0);
1699 	qle_write(sc, QLE_RESP_IN, 0);
1700 	qle_write(sc, QLE_RESP_OUT, 0);
1701 
1702 	qle_set_ints(sc, 1);
1703 
1704 	/* do a basic mailbox operation to check we're alive */
1705 	sc->sc_mbox[0] = QLE_MBOX_NOP;
1706 	if (qle_mbox(sc, 0x0001)) {
1707 		printf("ISP not responding after reset\n");
1708 		return (ENXIO);
1709 	}
1710 
1711 	return (0);
1712 }
1713 
1714 void
1715 qle_update_topology(struct qle_softc *sc)
1716 {
1717 	sc->sc_mbox[0] = QLE_MBOX_GET_ID;
1718 	if (qle_mbox(sc, 0x0001)) {
1719 		DPRINTF(QLE_D_PORT, "%s: unable to get loop id\n", DEVNAME(sc));
1720 		sc->sc_topology = QLE_TOPO_N_PORT_NO_TARGET;
1721 	} else {
1722 		sc->sc_topology = sc->sc_mbox[6];
1723 		sc->sc_loop_id = sc->sc_mbox[1];
1724 
1725 		switch (sc->sc_topology) {
1726 		case QLE_TOPO_NL_PORT:
1727 		case QLE_TOPO_N_PORT:
1728 			DPRINTF(QLE_D_PORT, "%s: loop id %d\n", DEVNAME(sc),
1729 			    sc->sc_loop_id);
1730 			break;
1731 
1732 		case QLE_TOPO_FL_PORT:
1733 		case QLE_TOPO_F_PORT:
1734 			sc->sc_port_id = sc->sc_mbox[2] |
1735 			    (sc->sc_mbox[3] << 16);
1736 			DPRINTF(QLE_D_PORT, "%s: fabric port id %06x\n",
1737 			    DEVNAME(sc), sc->sc_port_id);
1738 			break;
1739 
1740 		case QLE_TOPO_N_PORT_NO_TARGET:
1741 		default:
1742 			DPRINTF(QLE_D_PORT, "%s: not useful\n", DEVNAME(sc));
1743 			break;
1744 		}
1745 
1746 		switch (sc->sc_topology) {
1747 		case QLE_TOPO_NL_PORT:
1748 		case QLE_TOPO_FL_PORT:
1749 			sc->sc_loop_max_id = 126;
1750 			break;
1751 
1752 		case QLE_TOPO_N_PORT:
1753 			sc->sc_loop_max_id = 2;
1754 			break;
1755 
1756 		default:
1757 			sc->sc_loop_max_id = 0;
1758 			break;
1759 		}
1760 	}
1761 }
1762 
1763 int
1764 qle_update_fabric(struct qle_softc *sc)
1765 {
1766 	/*struct qle_sns_rft_id *rft;*/
1767 
1768 	switch (sc->sc_topology) {
1769 	case QLE_TOPO_F_PORT:
1770 	case QLE_TOPO_FL_PORT:
1771 		break;
1772 
1773 	default:
1774 		return (0);
1775 	}
1776 
1777 	/* get the name server's port db entry */
1778 	sc->sc_mbox[0] = QLE_MBOX_GET_PORT_DB;
1779 	sc->sc_mbox[1] = QLE_F_PORT_HANDLE;
1780 	qle_mbox_putaddr(sc->sc_mbox, sc->sc_scratch);
1781 	bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(sc->sc_scratch), 0,
1782 	    sizeof(struct qle_get_port_db), BUS_DMASYNC_PREREAD);
1783 	if (qle_mbox(sc, 0x00cf)) {
1784 		DPRINTF(QLE_D_PORT, "%s: get port db for SNS failed: %x\n",
1785 		    DEVNAME(sc), sc->sc_mbox[0]);
1786 		sc->sc_sns_port_name = 0;
1787 	} else {
1788 		struct qle_get_port_db *pdb;
1789 		bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(sc->sc_scratch), 0,
1790 		    sizeof(struct qle_get_port_db), BUS_DMASYNC_POSTREAD);
1791 		pdb = QLE_DMA_KVA(sc->sc_scratch);
1792 		DPRINTF(QLE_D_PORT, "%s: SNS port name %llx\n", DEVNAME(sc),
1793 		    betoh64(pdb->port_name));
1794 		sc->sc_sns_port_name = betoh64(pdb->port_name);
1795 	}
1796 
1797 	/*
1798 	 * register fc4 types with the fabric
1799 	 * some switches do this automatically, but apparently
1800 	 * some don't.
1801 	 */
1802 	/*
1803 	rft = QLE_DMA_KVA(sc->sc_scratch);
1804 	memset(rft, 0, sizeof(*rft) + sizeof(struct qle_sns_req_hdr));
1805 	htolem16(&rft->subcmd, QLE_SNS_RFT_ID);
1806 	htolem16(&rft->max_word, sizeof(struct qle_sns_req_hdr) / 4);
1807 	htolem32(&rft->port_id, sc->sc_port_id);
1808 	rft->fc4_types[0] = (1 << QLE_FC4_SCSI);
1809 	if (qle_sns_req(sc, sc->sc_scratch, sizeof(*rft))) {
1810 		printf("%s: RFT_ID failed\n", DEVNAME(sc));
1811 		/ * we might be able to continue after this fails * /
1812 	}
1813 	*/
1814 
1815 	return (1);
1816 }
1817 
1818 int
1819 qle_ct_pass_through(struct qle_softc *sc, u_int32_t port_handle,
1820     struct qle_dmamem *mem, size_t req_size, size_t resp_size)
1821 {
1822 	struct qle_iocb_ct_passthrough *iocb;
1823 	u_int16_t req;
1824 	u_int64_t offset;
1825 	int rv;
1826 
1827 	mtx_enter(&sc->sc_queue_mtx);
1828 
1829 	req = sc->sc_next_req_id++;
1830 	if (sc->sc_next_req_id == sc->sc_maxcmds)
1831 		sc->sc_next_req_id = 0;
1832 
1833 	offset = (req * QLE_QUEUE_ENTRY_SIZE);
1834 	iocb = QLE_DMA_KVA(sc->sc_requests) + offset;
1835 	bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(sc->sc_requests), offset,
1836 	    QLE_QUEUE_ENTRY_SIZE, BUS_DMASYNC_POSTWRITE);
1837 
1838 	memset(iocb, 0, QLE_QUEUE_ENTRY_SIZE);
1839 	iocb->entry_type = QLE_IOCB_CT_PASSTHROUGH;
1840 	iocb->entry_count = 1;
1841 
1842 	iocb->req_handle = 9;
1843 	htolem16(&iocb->req_nport_handle, port_handle);
1844 	htolem16(&iocb->req_dsd_count, 1);
1845 	htolem16(&iocb->req_resp_dsd_count, 1);
1846 	htolem32(&iocb->req_cmd_byte_count, req_size);
1847 	htolem32(&iocb->req_resp_byte_count, resp_size);
1848 	qle_sge(&iocb->req_cmd_seg, QLE_DMA_DVA(mem), req_size);
1849 	qle_sge(&iocb->req_resp_seg, QLE_DMA_DVA(mem) + req_size, resp_size);
1850 
1851 	bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(mem), 0, QLE_DMA_LEN(mem),
1852 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1853 	qle_write(sc, QLE_REQ_IN, sc->sc_next_req_id);
1854 	sc->sc_fabric_pending = 1;
1855 	mtx_leave(&sc->sc_queue_mtx);
1856 
1857 	/* maybe put a proper timeout on this */
1858 	rv = 0;
1859 	while (sc->sc_fabric_pending == 1) {
1860 		if (sc->sc_scsibus == NULL) {
1861 			u_int16_t isr, info;
1862 
1863 			delay(100);
1864 			if (qle_read_isr(sc, &isr, &info) != 0)
1865 				qle_handle_intr(sc, isr, info);
1866 		} else {
1867 			tsleep(sc->sc_scratch, PRIBIO, "qle_fabric", 100);
1868 		}
1869 	}
1870 	if (rv == 0)
1871 		bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(mem), 0,
1872 		    QLE_DMA_LEN(mem), BUS_DMASYNC_POSTREAD |
1873 		    BUS_DMASYNC_POSTWRITE);
1874 
1875 	sc->sc_fabric_pending = 0;
1876 
1877 	return (rv);
1878 }
1879 
1880 struct qle_fc_port *
1881 qle_next_fabric_port(struct qle_softc *sc, u_int32_t *firstport,
1882     u_int32_t *lastport)
1883 {
1884 	struct qle_ct_ga_nxt_req *ga;
1885 	struct qle_ct_ga_nxt_resp *gar;
1886 	struct qle_fc_port *fport;
1887 	int result;
1888 
1889 	/* get the next port from the fabric nameserver */
1890 	ga = QLE_DMA_KVA(sc->sc_scratch);
1891 	memset(ga, 0, sizeof(*ga) + sizeof(*gar));
1892 	ga->header.ct_revision = 0x01;
1893 	ga->header.ct_gs_type = 0xfc;
1894 	ga->header.ct_gs_subtype = 0x02;
1895 	ga->subcmd = htobe16(QLE_SNS_GA_NXT);
1896 	ga->max_word = htobe16((sizeof(*gar) - 16) / 4);
1897 	ga->port_id = htobe32(*lastport);
1898 	result = qle_ct_pass_through(sc, QLE_SNS_HANDLE, sc->sc_scratch,
1899 	    sizeof(*ga), sizeof(*gar));
1900 	if (result) {
1901 		DPRINTF(QLE_D_PORT, "%s: GA_NXT %06x failed: %x\n", DEVNAME(sc),
1902 		    *lastport, result);
1903 		*lastport = 0xffffffff;
1904 		return (NULL);
1905 	}
1906 
1907 	gar = (struct qle_ct_ga_nxt_resp *)(ga + 1);
1908 	/* if the response is all zeroes, try again */
1909 	if (gar->port_type_id == 0 && gar->port_name == 0 &&
1910 	    gar->node_name == 0) {
1911 		DPRINTF(QLE_D_PORT, "%s: GA_NXT returned junk\n", DEVNAME(sc));
1912 		return (NULL);
1913 	}
1914 
1915 	/* are we back at the start? */
1916 	*lastport = betoh32(gar->port_type_id) & 0xffffff;
1917 	if (*lastport == *firstport) {
1918 		*lastport = 0xffffffff;
1919 		return (NULL);
1920 	}
1921 	if (*firstport == 0xffffffff)
1922 		*firstport = *lastport;
1923 
1924 	DPRINTF(QLE_D_PORT, "%s: GA_NXT: port id: %06x, wwpn %llx, wwnn %llx\n",
1925 	    DEVNAME(sc), *lastport, betoh64(gar->port_name),
1926 	    betoh64(gar->node_name));
1927 
1928 	/* don't try to log in to ourselves */
1929 	if (*lastport == sc->sc_port_id) {
1930 		return (NULL);
1931 	}
1932 
1933 	fport = malloc(sizeof(*fport), M_DEVBUF, M_ZERO | M_NOWAIT);
1934 	if (fport == NULL) {
1935 		printf("%s: failed to allocate a port struct\n",
1936 		    DEVNAME(sc));
1937 		*lastport = 0xffffffff;
1938 		return (NULL);
1939 	}
1940 	fport->port_name = betoh64(gar->port_name);
1941 	fport->node_name = betoh64(gar->node_name);
1942 	fport->location = QLE_LOCATION_PORT_ID(*lastport);
1943 	fport->portid = *lastport;
1944 	return (fport);
1945 }
1946 
1947 int
1948 qle_fabric_plogx(struct qle_softc *sc, struct qle_fc_port *port, int flags,
1949     u_int32_t *info)
1950 {
1951 	struct qle_iocb_plogx *iocb;
1952 	u_int16_t req;
1953 	u_int64_t offset;
1954 	int rv;
1955 
1956 	mtx_enter(&sc->sc_queue_mtx);
1957 
1958 	req = sc->sc_next_req_id++;
1959 	if (sc->sc_next_req_id == sc->sc_maxcmds)
1960 		sc->sc_next_req_id = 0;
1961 
1962 	offset = (req * QLE_QUEUE_ENTRY_SIZE);
1963 	iocb = QLE_DMA_KVA(sc->sc_requests) + offset;
1964 	bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(sc->sc_requests), offset,
1965 	    QLE_QUEUE_ENTRY_SIZE, BUS_DMASYNC_POSTWRITE);
1966 
1967 	memset(iocb, 0, QLE_QUEUE_ENTRY_SIZE);
1968 	iocb->entry_type = QLE_IOCB_PLOGX;
1969 	iocb->entry_count = 1;
1970 
1971 	iocb->req_handle = 7;
1972 	htolem16(&iocb->req_nport_handle, port->loopid);
1973 	htolem16(&iocb->req_port_id_lo, port->portid);
1974 	iocb->req_port_id_hi = port->portid >> 16;
1975 	htolem16(&iocb->req_flags, flags);
1976 
1977 	DPRINTF(QLE_D_PORT, "%s: plogx loop id %d port %06x, flags %x\n",
1978 	    DEVNAME(sc), port->loopid, port->portid, flags);
1979 	qle_dump_iocb(sc, iocb);
1980 
1981 	qle_write(sc, QLE_REQ_IN, sc->sc_next_req_id);
1982 	sc->sc_fabric_pending = 1;
1983 	mtx_leave(&sc->sc_queue_mtx);
1984 
1985 	/* maybe put a proper timeout on this */
1986 	rv = 0;
1987 	while (sc->sc_fabric_pending == 1) {
1988 		if (sc->sc_scsibus == NULL) {
1989 			u_int16_t isr, info;
1990 
1991 			delay(100);
1992 			if (qle_read_isr(sc, &isr, &info) != 0)
1993 				qle_handle_intr(sc, isr, info);
1994 		} else {
1995 			tsleep(sc->sc_scratch, PRIBIO, "qle_fabric", 100);
1996 		}
1997 	}
1998 	sc->sc_fabric_pending = 0;
1999 
2000 	iocb = (struct qle_iocb_plogx *)&sc->sc_fabric_response;
2001 	rv = lemtoh16(&iocb->req_status);
2002 	if (rv == QLE_PLOGX_ERROR) {
2003 		rv = lemtoh32(&iocb->req_ioparms[0]);
2004 		*info = lemtoh32(&iocb->req_ioparms[1]);
2005 	}
2006 
2007 	return (rv);
2008 }
2009 
2010 int
2011 qle_fabric_plogi(struct qle_softc *sc, struct qle_fc_port *port)
2012 {
2013 	u_int32_t info;
2014 	int err, loopid;
2015 
2016 	loopid = 0;
2017 retry:
2018 	if (port->loopid == 0) {
2019 
2020 		mtx_enter(&sc->sc_port_mtx);
2021 		loopid = qle_get_loop_id(sc, loopid);
2022 		mtx_leave(&sc->sc_port_mtx);
2023 		if (loopid == -1) {
2024 			printf("%s: ran out of loop ids\n", DEVNAME(sc));
2025 			return (1);
2026 		}
2027 
2028 		port->loopid = loopid;
2029 	}
2030 
2031 	err = qle_fabric_plogx(sc, port, QLE_PLOGX_LOGIN, &info);
2032 	switch (err) {
2033 	case 0:
2034 		DPRINTF(QLE_D_PORT, "%s: logged in to %06x as %d\n",
2035 		    DEVNAME(sc), port->portid, port->loopid);
2036 		port->flags &= ~QLE_PORT_FLAG_NEEDS_LOGIN;
2037 		return (0);
2038 
2039 	case QLE_PLOGX_ERROR_PORT_ID_USED:
2040 		DPRINTF(QLE_D_PORT, "%s: already logged in to %06x as %d\n",
2041 		    DEVNAME(sc), port->portid, info);
2042 		port->loopid = info;
2043 		port->flags &= ~QLE_PORT_FLAG_NEEDS_LOGIN;
2044 		return (0);
2045 
2046 	case QLE_PLOGX_ERROR_HANDLE_USED:
2047 		if (qle_add_logged_in_port(sc, loopid, info)) {
2048 			return (1);
2049 		}
2050 		port->loopid = 0;
2051 		loopid++;
2052 		goto retry;
2053 
2054 	default:
2055 		DPRINTF(QLE_D_PORT, "%s: error %x logging in to port %06x\n",
2056 		    DEVNAME(sc), err, port->portid);
2057 		port->loopid = 0;
2058 		return (1);
2059 	}
2060 }
2061 
2062 void
2063 qle_fabric_plogo(struct qle_softc *sc, struct qle_fc_port *port)
2064 {
2065 	int err;
2066 	u_int32_t info;
2067 
2068 	/*
2069 	 * we only log out if we can't see the port any more, so we always
2070 	 * want to do an explicit logout and free the n-port handle.
2071 	 */
2072 	err = qle_fabric_plogx(sc, port, QLE_PLOGX_LOGOUT |
2073 	    QLE_PLOGX_LOGOUT_EXPLICIT | QLE_PLOGX_LOGOUT_FREE_HANDLE, &info);
2074 	if (err == 0) {
2075 		DPRINTF(QLE_D_PORT, "%s: logged out of port %06x\n",
2076 		    DEVNAME(sc), port->portid);
2077 	} else {
2078 		DPRINTF(QLE_D_PORT, "%s: failed to log out of port %06x: "
2079 		    "%x %x\n", DEVNAME(sc), port->portid, err, info);
2080 	}
2081 }
2082 
2083 void
2084 qle_do_update(void *xsc, void *x)
2085 {
2086 	struct qle_softc *sc = xsc;
2087 	int firstport, lastport;
2088 	struct qle_fc_port *port, *fport;
2089 
2090 	DPRINTF(QLE_D_PORT, "%s: updating\n", DEVNAME(sc));
2091 	while (sc->sc_update_tasks != 0) {
2092 		if (sc->sc_update_tasks & QLE_UPDATE_TASK_CLEAR_ALL) {
2093 			TAILQ_HEAD(, qle_fc_port) detach;
2094 			DPRINTF(QLE_D_PORT, "%s: detaching everything\n",
2095 			    DEVNAME(sc));
2096 
2097 			mtx_enter(&sc->sc_port_mtx);
2098 			qle_clear_port_lists(sc);
2099 			TAILQ_INIT(&detach);
2100 			while (!TAILQ_EMPTY(&sc->sc_ports)) {
2101 				port = TAILQ_FIRST(&sc->sc_ports);
2102 				TAILQ_REMOVE(&sc->sc_ports, port, ports);
2103 				TAILQ_INSERT_TAIL(&detach, port, ports);
2104 			}
2105 			mtx_leave(&sc->sc_port_mtx);
2106 
2107 			while (!TAILQ_EMPTY(&detach)) {
2108 				port = TAILQ_FIRST(&detach);
2109 				TAILQ_REMOVE(&detach, port, ports);
2110 				if (port->flags & QLE_PORT_FLAG_IS_TARGET) {
2111 					scsi_detach_target(sc->sc_scsibus,
2112 					    port->loopid, -1);
2113 					sc->sc_targets[port->loopid] = NULL;
2114 				}
2115 				if (port->location & QLE_LOCATION_FABRIC)
2116 					qle_fabric_plogo(sc, port);
2117 
2118 				free(port, M_DEVBUF, 0);
2119 			}
2120 
2121 			qle_update_done(sc, QLE_UPDATE_TASK_CLEAR_ALL);
2122 			continue;
2123 		}
2124 
2125 		if (sc->sc_update_tasks & QLE_UPDATE_TASK_SOFTRESET) {
2126 			DPRINTF(QLE_D_IO, "%s: attempting softreset\n",
2127 			    DEVNAME(sc));
2128 			if (qle_softreset(sc) != 0) {
2129 				DPRINTF(QLE_D_IO, "%s: couldn't softreset\n",
2130 				    DEVNAME(sc));
2131 			}
2132 			qle_update_done(sc, QLE_UPDATE_TASK_SOFTRESET);
2133 			continue;
2134 		}
2135 
2136 		if (sc->sc_update_tasks & QLE_UPDATE_TASK_UPDATE_TOPO) {
2137 			DPRINTF(QLE_D_PORT, "%s: updating topology\n",
2138 			    DEVNAME(sc));
2139 			qle_update_topology(sc);
2140 			qle_update_done(sc, QLE_UPDATE_TASK_UPDATE_TOPO);
2141 			continue;
2142 		}
2143 
2144 		if (sc->sc_update_tasks & QLE_UPDATE_TASK_GET_PORT_LIST) {
2145 			DPRINTF(QLE_D_PORT, "%s: getting port name list\n",
2146 			    DEVNAME(sc));
2147 			mtx_enter(&sc->sc_port_mtx);
2148 			qle_clear_port_lists(sc);
2149 			mtx_leave(&sc->sc_port_mtx);
2150 
2151 			qle_get_port_name_list(sc, QLE_LOCATION_LOOP |
2152 			    QLE_LOCATION_FABRIC);
2153 			mtx_enter(&sc->sc_port_mtx);
2154 			TAILQ_FOREACH(port, &sc->sc_ports, ports) {
2155 				TAILQ_INSERT_TAIL(&sc->sc_ports_gone, port,
2156 				    update);
2157 				if (port->location & QLE_LOCATION_FABRIC) {
2158 					port->flags |=
2159 					    QLE_PORT_FLAG_NEEDS_LOGIN;
2160 				}
2161 			}
2162 
2163 			/* take care of ports that haven't changed first */
2164 			TAILQ_FOREACH(fport, &sc->sc_ports_found, update) {
2165 				port = sc->sc_targets[fport->loopid];
2166 				if (port == NULL || fport->port_name !=
2167 				    port->port_name) {
2168 					/* new or changed port, handled later */
2169 					continue;
2170 				}
2171 
2172 				/*
2173 				 * the port hasn't been logged out, which
2174 				 * means we don't need to log in again, and,
2175 				 * for loop ports, that the port still exists
2176 				 */
2177 				port->flags &= ~QLE_PORT_FLAG_NEEDS_LOGIN;
2178 				if (port->location & QLE_LOCATION_LOOP)
2179 					TAILQ_REMOVE(&sc->sc_ports_gone,
2180 					    port, update);
2181 
2182 				fport->location = 0;
2183 			}
2184 			mtx_leave(&sc->sc_port_mtx);
2185 			qle_update_start(sc, QLE_UPDATE_TASK_PORT_LIST);
2186 			qle_update_done(sc, QLE_UPDATE_TASK_GET_PORT_LIST);
2187 			continue;
2188 		}
2189 
2190 		if (sc->sc_update_tasks & QLE_UPDATE_TASK_PORT_LIST) {
2191 			mtx_enter(&sc->sc_port_mtx);
2192 			fport = TAILQ_FIRST(&sc->sc_ports_found);
2193 			if (fport != NULL) {
2194 				TAILQ_REMOVE(&sc->sc_ports_found, fport,
2195 				    update);
2196 			}
2197 			mtx_leave(&sc->sc_port_mtx);
2198 
2199 			if (fport == NULL) {
2200 				DPRINTF(QLE_D_PORT, "%s: done with ports\n",
2201 				    DEVNAME(sc));
2202 				qle_update_done(sc,
2203 				    QLE_UPDATE_TASK_PORT_LIST);
2204 				qle_update_start(sc,
2205 				    QLE_UPDATE_TASK_SCAN_FABRIC);
2206 			} else if (fport->location & QLE_LOCATION_LOOP) {
2207 				DPRINTF(QLE_D_PORT, "%s: loop port %04x\n",
2208 				    DEVNAME(sc), fport->loopid);
2209 				if (qle_add_loop_port(sc, fport) != 0)
2210 					free(fport, M_DEVBUF, 0);
2211 			} else if (fport->location & QLE_LOCATION_FABRIC) {
2212 				qle_add_fabric_port(sc, fport);
2213 			} else {
2214 				/* already processed */
2215 				free(fport, M_DEVBUF, 0);
2216 			}
2217 			continue;
2218 		}
2219 
2220 		if (sc->sc_update_tasks & QLE_UPDATE_TASK_SCAN_FABRIC) {
2221 			DPRINTF(QLE_D_PORT, "%s: starting fabric scan\n",
2222 			    DEVNAME(sc));
2223 			lastport = sc->sc_port_id;
2224 			firstport = 0xffffffff;
2225 			if (qle_update_fabric(sc))
2226 				qle_update_start(sc,
2227 				    QLE_UPDATE_TASK_SCANNING_FABRIC);
2228 
2229 			qle_update_done(sc, QLE_UPDATE_TASK_SCAN_FABRIC);
2230 			continue;
2231 		}
2232 
2233 		if (sc->sc_update_tasks & QLE_UPDATE_TASK_SCANNING_FABRIC) {
2234 			fport = qle_next_fabric_port(sc, &firstport, &lastport);
2235 			if (fport != NULL) {
2236 				int disp;
2237 
2238 				mtx_enter(&sc->sc_port_mtx);
2239 				disp = qle_classify_port(sc, fport->location,
2240 				    fport->port_name, fport->node_name, &port);
2241 				switch (disp) {
2242 				case QLE_PORT_DISP_CHANGED:
2243 				case QLE_PORT_DISP_MOVED:
2244 					/* we'll log out the old port later */
2245 				case QLE_PORT_DISP_NEW:
2246 					DPRINTF(QLE_D_PORT, "%s: new port "
2247 					    "%06x\n", DEVNAME(sc),
2248 					    fport->portid);
2249 					TAILQ_INSERT_TAIL(&sc->sc_ports_found,
2250 					    fport, update);
2251 					break;
2252 				case QLE_PORT_DISP_DUP:
2253 					free(fport, M_DEVBUF, 0);
2254 					break;
2255 				case QLE_PORT_DISP_SAME:
2256 					DPRINTF(QLE_D_PORT, "%s: existing port "
2257 					    " %06x\n", DEVNAME(sc),
2258 					    fport->portid);
2259 					TAILQ_REMOVE(&sc->sc_ports_gone, port,
2260 					    update);
2261 					free(fport, M_DEVBUF, 0);
2262 					break;
2263 				}
2264 				mtx_leave(&sc->sc_port_mtx);
2265 			}
2266 			if (lastport == 0xffffffff) {
2267 				DPRINTF(QLE_D_PORT, "%s: finished\n",
2268 				    DEVNAME(sc));
2269 				qle_update_done(sc,
2270 				    QLE_UPDATE_TASK_SCANNING_FABRIC);
2271 				qle_update_start(sc,
2272 				    QLE_UPDATE_TASK_FABRIC_LOGIN);
2273 			}
2274 			continue;
2275 		}
2276 
2277 		if (sc->sc_update_tasks & QLE_UPDATE_TASK_FABRIC_LOGIN) {
2278 			mtx_enter(&sc->sc_port_mtx);
2279 			port = TAILQ_FIRST(&sc->sc_ports_found);
2280 			if (port != NULL) {
2281 				TAILQ_REMOVE(&sc->sc_ports_found, port, update);
2282 			}
2283 			mtx_leave(&sc->sc_port_mtx);
2284 
2285 			if (port != NULL) {
2286 				DPRINTF(QLE_D_PORT, "%s: found port %06x\n",
2287 				    DEVNAME(sc), port->portid);
2288 				if (qle_fabric_plogi(sc, port) == 0) {
2289 					qle_add_fabric_port(sc, port);
2290 				} else {
2291 					DPRINTF(QLE_D_PORT, "%s: plogi %06x "
2292 					    "failed\n", DEVNAME(sc),
2293 					    port->portid);
2294 					free(port, M_DEVBUF, 0);
2295 				}
2296 			} else {
2297 				DPRINTF(QLE_D_PORT, "%s: done with logins\n",
2298 				    DEVNAME(sc));
2299 				qle_update_done(sc,
2300 				    QLE_UPDATE_TASK_FABRIC_LOGIN);
2301 				qle_update_start(sc,
2302 				    QLE_UPDATE_TASK_ATTACH_TARGET |
2303 				    QLE_UPDATE_TASK_DETACH_TARGET);
2304 			}
2305 			continue;
2306 		}
2307 
2308 		if (sc->sc_update_tasks & QLE_UPDATE_TASK_FABRIC_RELOGIN) {
2309 			TAILQ_FOREACH(port, &sc->sc_ports, ports) {
2310 				if (port->flags & QLE_PORT_FLAG_NEEDS_LOGIN) {
2311 					qle_fabric_plogi(sc, port);
2312 					break;
2313 				}
2314 			}
2315 
2316 			if (port == TAILQ_END(&sc->sc_ports))
2317 				qle_update_done(sc,
2318 				    QLE_UPDATE_TASK_FABRIC_RELOGIN);
2319 			continue;
2320 		}
2321 
2322 		if (sc->sc_update_tasks & QLE_UPDATE_TASK_DETACH_TARGET) {
2323 			mtx_enter(&sc->sc_port_mtx);
2324 			port = TAILQ_FIRST(&sc->sc_ports_gone);
2325 			if (port != NULL) {
2326 				sc->sc_targets[port->loopid] = NULL;
2327 				TAILQ_REMOVE(&sc->sc_ports_gone, port, update);
2328 				TAILQ_REMOVE(&sc->sc_ports, port, ports);
2329 			}
2330 			mtx_leave(&sc->sc_port_mtx);
2331 
2332 			if (port != NULL) {
2333 				DPRINTF(QLE_D_PORT, "%s: detaching port %06x\n",
2334 				    DEVNAME(sc), port->portid);
2335 				if (sc->sc_scsibus != NULL)
2336 					scsi_detach_target(sc->sc_scsibus,
2337 					    port->loopid, -1);
2338 
2339 				if (port->location & QLE_LOCATION_FABRIC)
2340 					qle_fabric_plogo(sc, port);
2341 
2342 				free(port, M_DEVBUF, 0);
2343 			} else {
2344 				DPRINTF(QLE_D_PORT, "%s: nothing to detach\n",
2345 				    DEVNAME(sc));
2346 				qle_update_done(sc,
2347 				    QLE_UPDATE_TASK_DETACH_TARGET);
2348 			}
2349 			continue;
2350 		}
2351 
2352 		if (sc->sc_update_tasks & QLE_UPDATE_TASK_ATTACH_TARGET) {
2353 			mtx_enter(&sc->sc_port_mtx);
2354 			port = TAILQ_FIRST(&sc->sc_ports_new);
2355 			if (port != NULL) {
2356 				TAILQ_REMOVE(&sc->sc_ports_new, port, update);
2357 				TAILQ_INSERT_TAIL(&sc->sc_ports, port, ports);
2358 			}
2359 			mtx_leave(&sc->sc_port_mtx);
2360 
2361 			if (port != NULL) {
2362 				if (sc->sc_scsibus != NULL)
2363 					scsi_probe_target(sc->sc_scsibus,
2364 					    port->loopid);
2365 			} else {
2366 				qle_update_done(sc,
2367 				    QLE_UPDATE_TASK_ATTACH_TARGET);
2368 			}
2369 			continue;
2370 		}
2371 
2372 	}
2373 
2374 	DPRINTF(QLE_D_PORT, "%s: done updating\n", DEVNAME(sc));
2375 }
2376 
2377 int
2378 qle_async(struct qle_softc *sc, u_int16_t info)
2379 {
2380 	switch (info) {
2381 	case QLE_ASYNC_SYSTEM_ERROR:
2382 		qle_update_start(sc, QLE_UPDATE_TASK_SOFTRESET);
2383 		break;
2384 
2385 	case QLE_ASYNC_REQ_XFER_ERROR:
2386 		qle_update_start(sc, QLE_UPDATE_TASK_SOFTRESET);
2387 		break;
2388 
2389 	case QLE_ASYNC_RSP_XFER_ERROR:
2390 		qle_update_start(sc, QLE_UPDATE_TASK_SOFTRESET);
2391 		break;
2392 
2393 	case QLE_ASYNC_LIP_OCCURRED:
2394 		DPRINTF(QLE_D_INTR, "%s: lip occurred\n", DEVNAME(sc));
2395 		break;
2396 
2397 	case QLE_ASYNC_LOOP_UP:
2398 		DPRINTF(QLE_D_PORT, "%s: loop up\n", DEVNAME(sc));
2399 		sc->sc_loop_up = 1;
2400 		sc->sc_marker_required = 1;
2401 		qle_update_start(sc, QLE_UPDATE_TASK_UPDATE_TOPO |
2402 		    QLE_UPDATE_TASK_GET_PORT_LIST);
2403 		break;
2404 
2405 	case QLE_ASYNC_LOOP_DOWN:
2406 		DPRINTF(QLE_D_PORT, "%s: loop down\n", DEVNAME(sc));
2407 		sc->sc_loop_up = 0;
2408 		qle_update_start(sc, QLE_UPDATE_TASK_CLEAR_ALL);
2409 		break;
2410 
2411 	case QLE_ASYNC_LIP_RESET:
2412 		DPRINTF(QLE_D_PORT, "%s: lip reset\n", DEVNAME(sc));
2413 		sc->sc_marker_required = 1;
2414 		qle_update_start(sc, QLE_UPDATE_TASK_FABRIC_RELOGIN);
2415 		break;
2416 
2417 	case QLE_ASYNC_PORT_DB_CHANGE:
2418 		DPRINTF(QLE_D_PORT, "%s: port db changed %x\n", DEVNAME(sc),
2419 		    qle_read_mbox(sc, 1));
2420 		qle_update_start(sc, QLE_UPDATE_TASK_GET_PORT_LIST);
2421 		break;
2422 
2423 	case QLE_ASYNC_CHANGE_NOTIFY:
2424 		DPRINTF(QLE_D_PORT, "%s: name server change (%02x:%02x)\n",
2425 		    DEVNAME(sc), qle_read_mbox(sc, 1), qle_read_mbox(sc, 2));
2426 		qle_update_start(sc, QLE_UPDATE_TASK_GET_PORT_LIST);
2427 		break;
2428 
2429 	case QLE_ASYNC_LIP_F8:
2430 		DPRINTF(QLE_D_INTR, "%s: lip f8\n", DEVNAME(sc));
2431 		break;
2432 
2433 	case QLE_ASYNC_LOOP_INIT_ERROR:
2434 		DPRINTF(QLE_D_PORT, "%s: loop initialization error: %x\n",
2435 		    DEVNAME(sc), qle_read_mbox(sc, 1));
2436 		break;
2437 
2438 	case QLE_ASYNC_POINT_TO_POINT:
2439 		DPRINTF(QLE_D_PORT, "%s: connected in point-to-point mode\n",
2440 		    DEVNAME(sc));
2441 		break;
2442 
2443 	case QLE_ASYNC_ZIO_RESP_UPDATE:
2444 		/* shouldn't happen, we don't do zio */
2445 		break;
2446 
2447 	default:
2448 		DPRINTF(QLE_D_INTR, "%s: unknown async %x\n", DEVNAME(sc), info);
2449 		break;
2450 	}
2451 	return (1);
2452 }
2453 
2454 void
2455 qle_dump_stuff(struct qle_softc *sc, void *buf, int n)
2456 {
2457 #ifdef QLE_DEBUG
2458 	u_int8_t *d = buf;
2459 	int l;
2460 
2461 	if ((qledebug & QLE_D_IOCB) == 0)
2462 		return;
2463 
2464 	printf("%s: stuff\n", DEVNAME(sc));
2465 	for (l = 0; l < n; l++) {
2466 		printf(" %2.2x", d[l]);
2467 		if (l % 16 == 15)
2468 			printf("\n");
2469 	}
2470 	if (n % 16 != 0)
2471 		printf("\n");
2472 #endif
2473 }
2474 
2475 void
2476 qle_dump_iocb(struct qle_softc *sc, void *buf)
2477 {
2478 #ifdef QLE_DEBUG
2479 	u_int8_t *iocb = buf;
2480 	int l;
2481 	int b;
2482 
2483 	if ((qledebug & QLE_D_IOCB) == 0)
2484 		return;
2485 
2486 	printf("%s: iocb:\n", DEVNAME(sc));
2487 	for (l = 0; l < 4; l++) {
2488 		for (b = 0; b < 16; b++) {
2489 			printf(" %2.2x", iocb[(l*16)+b]);
2490 		}
2491 		printf("\n");
2492 	}
2493 #endif
2494 }
2495 
2496 void
2497 qle_dump_iocb_segs(struct qle_softc *sc, void *segs, int n)
2498 {
2499 #ifdef QLE_DEBUG
2500 	u_int8_t *buf = segs;
2501 	int s, b;
2502 
2503 	if ((qledebug & QLE_D_IOCB) == 0)
2504 		return;
2505 
2506 	printf("%s: iocb segs:\n", DEVNAME(sc));
2507 	for (s = 0; s < n; s++) {
2508 		for (b = 0; b < sizeof(struct qle_iocb_seg); b++) {
2509 			printf(" %2.2x", buf[(s*(sizeof(struct qle_iocb_seg)))
2510 			    + b]);
2511 		}
2512 		printf("\n");
2513 	}
2514 #endif
2515 }
2516 
2517 void
2518 qle_put_marker(struct qle_softc *sc, void *buf)
2519 {
2520 	struct qle_iocb_marker *marker = buf;
2521 
2522 	marker->entry_type = QLE_IOCB_MARKER;
2523 	marker->entry_count = 1;
2524 	marker->seqno = 0;
2525 	marker->flags = 0;
2526 
2527 	/* could be more specific here; isp(4) isn't */
2528 	marker->target = 0;
2529 	marker->modifier = QLE_IOCB_MARKER_SYNC_ALL;
2530 }
2531 
2532 void
2533 qle_sge(struct qle_iocb_seg *seg, u_int64_t addr, u_int32_t len)
2534 {
2535 	htolem32(&seg->seg_addr_lo, addr);
2536 	htolem32(&seg->seg_addr_hi, addr >> 32);
2537 	htolem32(&seg->seg_len, len);
2538 }
2539 
2540 void
2541 qle_put_cmd(struct qle_softc *sc, void *buf, struct scsi_xfer *xs,
2542     struct qle_ccb *ccb, u_int32_t target_port)
2543 {
2544 	bus_dmamap_t dmap = ccb->ccb_dmamap;
2545 	struct qle_iocb_req6 *req = buf;
2546 	struct qle_fcp_cmnd *cmnd;
2547 	u_int64_t fcp_cmnd_offset;
2548 	u_int32_t fcp_dl;
2549 	int seg;
2550 	int target = xs->sc_link->target;
2551 	int lun = xs->sc_link->lun;
2552 	u_int16_t flags;
2553 
2554 	memset(req, 0, sizeof(*req));
2555 	req->entry_type = QLE_IOCB_CMD_TYPE_6;
2556 	req->entry_count = 1;
2557 
2558 	req->req_handle = ccb->ccb_id;
2559 	htolem16(&req->req_nport_handle, target);
2560 
2561 	/*
2562 	 * timeout is in seconds.  make sure it's at least 1 if a timeout
2563 	 * was specified in xs
2564 	 */
2565 	if (xs->timeout != 0)
2566 		htolem16(&req->req_timeout, MAX(1, xs->timeout/1000));
2567 
2568 	if (xs->datalen > 0) {
2569 		flags = (xs->flags & SCSI_DATA_IN) ?
2570 		    QLE_IOCB_CTRL_FLAG_READ : QLE_IOCB_CTRL_FLAG_WRITE;
2571 		if (dmap->dm_nsegs == 1) {
2572 			qle_sge(&req->req_data_seg, dmap->dm_segs[0].ds_addr,
2573 			    dmap->dm_segs[0].ds_len);
2574 		} else {
2575 			flags |= QLE_IOCB_CTRL_FLAG_EXT_SEG;
2576 			qle_sge(&req->req_data_seg,
2577 			    QLE_DMA_DVA(sc->sc_segments) +
2578 			     ccb->ccb_seg_offset,
2579 			    (ccb->ccb_dmamap->dm_nsegs + 1) *
2580 			     sizeof(struct qle_iocb_seg));
2581 
2582 			for (seg = 0; seg < dmap->dm_nsegs; seg++) {
2583 				qle_sge(&ccb->ccb_segs[seg],
2584 				    dmap->dm_segs[seg].ds_addr,
2585 				    dmap->dm_segs[seg].ds_len);
2586 			}
2587 			qle_sge(&ccb->ccb_segs[seg], 0, 0);
2588 
2589 			bus_dmamap_sync(sc->sc_dmat,
2590 			    QLE_DMA_MAP(sc->sc_segments), ccb->ccb_seg_offset,
2591 			    sizeof(*ccb->ccb_segs) * ccb->ccb_dmamap->dm_nsegs,
2592 			    BUS_DMASYNC_PREWRITE);
2593 		}
2594 
2595 		htolem16(&req->req_data_seg_count, dmap->dm_nsegs);
2596 		htolem32(&req->req_data_len, xs->datalen);
2597 		htolem16(&req->req_ctrl_flags, flags);
2598 	}
2599 
2600 	htobem16(&req->req_fcp_lun[0], lun);
2601 	htobem16(&req->req_fcp_lun[1], lun >> 16);
2602 	htolem32(&req->req_target_id, target_port & 0xffffff);
2603 
2604 	fcp_cmnd_offset = ccb->ccb_id * sizeof(*cmnd);
2605 	/* set up FCP_CMND */
2606 	cmnd = (struct qle_fcp_cmnd *)QLE_DMA_KVA(sc->sc_fcp_cmnds) +
2607 	    ccb->ccb_id;
2608 
2609 	memset(cmnd, 0, sizeof(*cmnd));
2610 	htobem16(&cmnd->fcp_lun[0], lun);
2611 	htobem16(&cmnd->fcp_lun[1], lun >> 16);
2612 	/* cmnd->fcp_task_attr = TSK_SIMPLE; */
2613 	/* cmnd->fcp_task_mgmt = 0; */
2614 	memcpy(cmnd->fcp_cdb, xs->cmd, xs->cmdlen);
2615 
2616 	/* FCP_DL goes after the cdb */
2617 	fcp_dl = htobe32(xs->datalen);
2618 	if (xs->cmdlen > 16) {
2619 		htolem16(&req->req_fcp_cmnd_len, 12 + xs->cmdlen + 4);
2620 		cmnd->fcp_add_cdb_len = xs->cmdlen - 16;
2621 		memcpy(cmnd->fcp_cdb + xs->cmdlen, &fcp_dl, sizeof(fcp_dl));
2622 	} else {
2623 		htolem16(&req->req_fcp_cmnd_len, 12 + 16 + 4);
2624 		cmnd->fcp_add_cdb_len = 0;
2625 		memcpy(cmnd->fcp_cdb + 16, &fcp_dl, sizeof(fcp_dl));
2626 	}
2627 	if (xs->datalen > 0)
2628 		cmnd->fcp_add_cdb_len |= (xs->flags & SCSI_DATA_IN) ? 2 : 1;
2629 
2630 	bus_dmamap_sync(sc->sc_dmat,
2631 	    QLE_DMA_MAP(sc->sc_fcp_cmnds), fcp_cmnd_offset,
2632 	    sizeof(*cmnd), BUS_DMASYNC_PREWRITE);
2633 
2634 	/* link req to cmnd */
2635 	fcp_cmnd_offset += QLE_DMA_DVA(sc->sc_fcp_cmnds);
2636 	htolem32(&req->req_fcp_cmnd_addr_lo, fcp_cmnd_offset);
2637 	htolem32(&req->req_fcp_cmnd_addr_hi, fcp_cmnd_offset >> 32);
2638 }
2639 
2640 int
2641 qle_load_fwchunk(struct qle_softc *sc, struct qle_dmamem *mem,
2642     const u_int32_t *src)
2643 {
2644 	u_int32_t dest, done, total;
2645 	int i;
2646 
2647 	dest = src[2];
2648 	done = 0;
2649 	total = src[3];
2650 
2651 	while (done < total) {
2652 		u_int32_t *copy;
2653 		u_int32_t words;
2654 
2655 		/* limit transfer size otherwise it just doesn't work */
2656 		words = MIN(total - done, 1 << 10);
2657 		copy = QLE_DMA_KVA(mem);
2658 		for (i = 0; i < words; i++) {
2659 			htolem32(&copy[i], src[done++]);
2660 		}
2661 		bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(mem), 0, words * 4,
2662 		    BUS_DMASYNC_PREWRITE);
2663 
2664 		sc->sc_mbox[0] = QLE_MBOX_LOAD_RISC_RAM;
2665 		sc->sc_mbox[1] = dest;
2666 		sc->sc_mbox[4] = words >> 16;
2667 		sc->sc_mbox[5] = words & 0xffff;
2668 		sc->sc_mbox[8] = dest >> 16;
2669 		qle_mbox_putaddr(sc->sc_mbox, mem);
2670 		if (qle_mbox(sc, 0x01ff)) {
2671 			printf("firmware load failed\n");
2672 			return (1);
2673 		}
2674 		bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(mem), 0, words * 4,
2675 		    BUS_DMASYNC_POSTWRITE);
2676 
2677 		dest += words;
2678 	}
2679 
2680 	return (qle_verify_firmware(sc, src[2]));
2681 }
2682 
2683 int
2684 qle_load_firmware_chunks(struct qle_softc *sc, const u_int32_t *fw)
2685 {
2686 	struct qle_dmamem *mem;
2687 	int res = 0;
2688 
2689 	mem = qle_dmamem_alloc(sc, 65536);
2690 	for (;;) {
2691 		if (qle_load_fwchunk(sc, mem, fw)) {
2692 			res = 1;
2693 			break;
2694 		}
2695 		if (fw[1] == 0)
2696 			break;
2697 		fw += fw[3];
2698 	}
2699 
2700 	qle_dmamem_free(sc, mem);
2701 	return (res);
2702 }
2703 
2704 u_int32_t
2705 qle_read_ram_word(struct qle_softc *sc, u_int32_t addr)
2706 {
2707 	sc->sc_mbox[0] = QLE_MBOX_READ_RISC_RAM;
2708 	sc->sc_mbox[1] = addr & 0xffff;
2709 	sc->sc_mbox[8] = addr >> 16;
2710 	if (qle_mbox(sc, 0x0103)) {
2711 		return (0);
2712 	}
2713 	return ((sc->sc_mbox[3] << 16) | sc->sc_mbox[2]);
2714 }
2715 
2716 int
2717 qle_verify_firmware(struct qle_softc *sc, u_int32_t addr)
2718 {
2719 	/*
2720 	 * QLE_MBOX_VERIFY_CSUM requires at least the firmware header
2721 	 * to be correct, otherwise it wanders all over ISP memory and
2722 	 * gets lost.  Check that chunk address (addr+2) is right and
2723 	 * size (addr+3) is plausible first.
2724 	 */
2725 	if ((qle_read_ram_word(sc, addr+2) != addr) ||
2726 	    (qle_read_ram_word(sc, addr+3) > 0xffff)) {
2727 		return (1);
2728 	}
2729 
2730 	sc->sc_mbox[0] = QLE_MBOX_VERIFY_CSUM;
2731 	sc->sc_mbox[1] = addr >> 16;
2732 	sc->sc_mbox[2] = addr;
2733 	if (qle_mbox(sc, 0x0007)) {
2734 		return (1);
2735 	}
2736 	return (0);
2737 }
2738 
2739 int
2740 qle_read_nvram(struct qle_softc *sc)
2741 {
2742 	u_int32_t data[sizeof(sc->sc_nvram) / 4];
2743 	u_int32_t csum, tmp, v;
2744 	int i, base, l;
2745 
2746 	switch (sc->sc_isp_gen) {
2747 	case QLE_GEN_ISP24XX:
2748 		base = 0x7ffe0080;
2749 		break;
2750 	case QLE_GEN_ISP25XX:
2751 		base = 0x7ff48080;
2752 		break;
2753 	}
2754 	base += sc->sc_port * 0x100;
2755 
2756 	csum = 0;
2757 	for (i = 0; i < nitems(data); i++) {
2758 		data[i] = 0xffffffff;
2759 		qle_write(sc, QLE_FLASH_NVRAM_ADDR, base + i);
2760 		for (l = 0; l < 5000; l++) {
2761 			delay(10);
2762 			tmp = qle_read(sc, QLE_FLASH_NVRAM_ADDR);
2763 			if (tmp & (1U << 31)) {
2764 				v = qle_read(sc, QLE_FLASH_NVRAM_DATA);
2765 				csum += v;
2766 				data[i] = letoh32(v);
2767 				break;
2768 			}
2769 		}
2770 	}
2771 
2772 	bcopy(data, &sc->sc_nvram, sizeof(sc->sc_nvram));
2773 	/* id field should be 'ISP' */
2774 	if (sc->sc_nvram.id[0] != 'I' || sc->sc_nvram.id[1] != 'S' ||
2775 	    sc->sc_nvram.id[2] != 'P' || csum != 0) {
2776 		printf("%s: nvram corrupt\n", DEVNAME(sc));
2777 		return (1);
2778 	}
2779 	return (0);
2780 }
2781 
2782 struct qle_dmamem *
2783 qle_dmamem_alloc(struct qle_softc *sc, size_t size)
2784 {
2785 	struct qle_dmamem *m;
2786 	int nsegs;
2787 
2788 	m = malloc(sizeof(*m), M_DEVBUF, M_NOWAIT | M_ZERO);
2789 	if (m == NULL)
2790 		return (NULL);
2791 
2792 	m->qdm_size = size;
2793 
2794 	if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
2795 	    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &m->qdm_map) != 0)
2796 		goto qdmfree;
2797 
2798 	if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &m->qdm_seg, 1,
2799 	    &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO) != 0)
2800 		goto destroy;
2801 
2802 	if (bus_dmamem_map(sc->sc_dmat, &m->qdm_seg, nsegs, size, &m->qdm_kva,
2803 	    BUS_DMA_NOWAIT) != 0)
2804 		goto free;
2805 
2806 	if (bus_dmamap_load(sc->sc_dmat, m->qdm_map, m->qdm_kva, size, NULL,
2807 	    BUS_DMA_NOWAIT) != 0)
2808 		goto unmap;
2809 
2810 	return (m);
2811 
2812 unmap:
2813 	bus_dmamem_unmap(sc->sc_dmat, m->qdm_kva, m->qdm_size);
2814 free:
2815 	bus_dmamem_free(sc->sc_dmat, &m->qdm_seg, 1);
2816 destroy:
2817 	bus_dmamap_destroy(sc->sc_dmat, m->qdm_map);
2818 qdmfree:
2819 	free(m, M_DEVBUF, 0);
2820 
2821 	return (NULL);
2822 }
2823 
2824 void
2825 qle_dmamem_free(struct qle_softc *sc, struct qle_dmamem *m)
2826 {
2827 	bus_dmamap_unload(sc->sc_dmat, m->qdm_map);
2828 	bus_dmamem_unmap(sc->sc_dmat, m->qdm_kva, m->qdm_size);
2829 	bus_dmamem_free(sc->sc_dmat, &m->qdm_seg, 1);
2830 	bus_dmamap_destroy(sc->sc_dmat, m->qdm_map);
2831 	free(m, M_DEVBUF, 0);
2832 }
2833 
2834 int
2835 qle_alloc_ccbs(struct qle_softc *sc)
2836 {
2837 	struct qle_ccb		*ccb;
2838 	u_int8_t		*cmd;
2839 	int			i;
2840 
2841 	SIMPLEQ_INIT(&sc->sc_ccb_free);
2842 	mtx_init(&sc->sc_ccb_mtx, IPL_BIO);
2843 	mtx_init(&sc->sc_queue_mtx, IPL_BIO);
2844 	mtx_init(&sc->sc_port_mtx, IPL_BIO);
2845 	mtx_init(&sc->sc_mbox_mtx, IPL_BIO);
2846 
2847 	sc->sc_ccbs = mallocarray(sc->sc_maxcmds, sizeof(struct qle_ccb),
2848 	    M_DEVBUF, M_WAITOK | M_CANFAIL | M_ZERO);
2849 	if (sc->sc_ccbs == NULL) {
2850 		printf("%s: unable to allocate ccbs\n", DEVNAME(sc));
2851 		return (1);
2852 	}
2853 
2854 	sc->sc_requests = qle_dmamem_alloc(sc, sc->sc_maxcmds *
2855 	    QLE_QUEUE_ENTRY_SIZE);
2856 	if (sc->sc_requests == NULL) {
2857 		printf("%s: unable to allocate ccb dmamem\n", DEVNAME(sc));
2858 		goto free_ccbs;
2859 	}
2860 	sc->sc_responses = qle_dmamem_alloc(sc, sc->sc_maxcmds *
2861 	    QLE_QUEUE_ENTRY_SIZE);
2862 	if (sc->sc_responses == NULL) {
2863 		printf("%s: unable to allocate rcb dmamem\n", DEVNAME(sc));
2864 		goto free_req;
2865 	}
2866 	sc->sc_pri_requests = qle_dmamem_alloc(sc, 8 * QLE_QUEUE_ENTRY_SIZE);
2867 	if (sc->sc_pri_requests == NULL) {
2868 		printf("%s: unable to allocate pri ccb dmamem\n", DEVNAME(sc));
2869 		goto free_pri;
2870 	}
2871 	sc->sc_segments = qle_dmamem_alloc(sc, sc->sc_maxcmds * QLE_MAX_SEGS *
2872 	    sizeof(struct qle_iocb_seg));
2873 	if (sc->sc_segments == NULL) {
2874 		printf("%s: unable to allocate iocb segments\n", DEVNAME(sc));
2875 		goto free_res;
2876 	}
2877 
2878 	sc->sc_fcp_cmnds = qle_dmamem_alloc(sc, sc->sc_maxcmds *
2879 	    sizeof(struct qle_fcp_cmnd));
2880 	if (sc->sc_fcp_cmnds == NULL) {
2881 		printf("%s: unable to allocate FCP_CMNDs\n", DEVNAME(sc));
2882 		goto free_seg;
2883 	}
2884 
2885 	cmd = QLE_DMA_KVA(sc->sc_requests);
2886 	memset(cmd, 0, QLE_QUEUE_ENTRY_SIZE * sc->sc_maxcmds);
2887 	for (i = 0; i < sc->sc_maxcmds; i++) {
2888 		ccb = &sc->sc_ccbs[i];
2889 
2890 		if (bus_dmamap_create(sc->sc_dmat, MAXPHYS,
2891 		    QLE_MAX_SEGS, MAXPHYS, 0,
2892 		    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
2893 		    &ccb->ccb_dmamap) != 0) {
2894 			printf("%s: unable to create dma map\n", DEVNAME(sc));
2895 			goto free_maps;
2896 		}
2897 
2898 		ccb->ccb_sc = sc;
2899 		ccb->ccb_id = i;
2900 
2901 		ccb->ccb_seg_offset = i * QLE_MAX_SEGS *
2902 		    sizeof(struct qle_iocb_seg);
2903 		ccb->ccb_segs = QLE_DMA_KVA(sc->sc_segments) +
2904 		    ccb->ccb_seg_offset;
2905 
2906 		qle_put_ccb(sc, ccb);
2907 	}
2908 
2909 	scsi_iopool_init(&sc->sc_iopool, sc, qle_get_ccb, qle_put_ccb);
2910 	return (0);
2911 
2912 free_maps:
2913 	while ((ccb = qle_get_ccb(sc)) != NULL)
2914 		bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
2915 
2916 	qle_dmamem_free(sc, sc->sc_fcp_cmnds);
2917 free_seg:
2918 	qle_dmamem_free(sc, sc->sc_segments);
2919 free_pri:
2920 	qle_dmamem_free(sc, sc->sc_pri_requests);
2921 free_res:
2922 	qle_dmamem_free(sc, sc->sc_responses);
2923 free_req:
2924 	qle_dmamem_free(sc, sc->sc_requests);
2925 free_ccbs:
2926 	free(sc->sc_ccbs, M_DEVBUF, 0);
2927 
2928 	return (1);
2929 }
2930 
2931 void
2932 qle_free_ccbs(struct qle_softc *sc)
2933 {
2934 	struct qle_ccb		*ccb;
2935 
2936 	scsi_iopool_destroy(&sc->sc_iopool);
2937 	while ((ccb = qle_get_ccb(sc)) != NULL)
2938 		bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
2939 	qle_dmamem_free(sc, sc->sc_segments);
2940 	qle_dmamem_free(sc, sc->sc_responses);
2941 	qle_dmamem_free(sc, sc->sc_requests);
2942 	free(sc->sc_ccbs, M_DEVBUF, 0);
2943 }
2944 
2945 void *
2946 qle_get_ccb(void *xsc)
2947 {
2948 	struct qle_softc 	*sc = xsc;
2949 	struct qle_ccb		*ccb;
2950 
2951 	mtx_enter(&sc->sc_ccb_mtx);
2952 	ccb = SIMPLEQ_FIRST(&sc->sc_ccb_free);
2953 	if (ccb != NULL) {
2954 		SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_free, ccb_link);
2955 	}
2956 	mtx_leave(&sc->sc_ccb_mtx);
2957 	return (ccb);
2958 }
2959 
2960 void
2961 qle_put_ccb(void *xsc, void *io)
2962 {
2963 	struct qle_softc	*sc = xsc;
2964 	struct qle_ccb		*ccb = io;
2965 
2966 	ccb->ccb_xs = NULL;
2967 	mtx_enter(&sc->sc_ccb_mtx);
2968 	SIMPLEQ_INSERT_HEAD(&sc->sc_ccb_free, ccb, ccb_link);
2969 	mtx_leave(&sc->sc_ccb_mtx);
2970 }
2971