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