xref: /openbsd-src/sys/dev/pci/qle.c (revision 99fd087599a8791921855f21bd7e36130f39aadc)
1 /*	$OpenBSD: qle.c,v 1.51 2020/02/05 16:29:30 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 	/* we should be good to go now, attach scsibus */
658 	sc->sc_link.adapter = &qle_switch;
659 	sc->sc_link.adapter_softc = sc;
660 	sc->sc_link.adapter_target = QLE_MAX_TARGETS;
661 	sc->sc_link.adapter_buswidth = QLE_MAX_TARGETS;
662 	sc->sc_link.openings = sc->sc_maxcmds;
663 	sc->sc_link.pool = &sc->sc_iopool;
664 	if (sc->sc_nvram_valid) {
665 		sc->sc_link.port_wwn = betoh64(sc->sc_nvram.port_name);
666 		sc->sc_link.node_wwn = betoh64(sc->sc_nvram.node_name);
667 	} else {
668 		sc->sc_link.port_wwn = QLE_DEFAULT_PORT_NAME;
669 		sc->sc_link.node_wwn = 0;
670 	}
671 	if (sc->sc_link.node_wwn == 0) {
672 		/*
673 		 * mask out the port number from the port name to get
674 		 * the node name.
675 		 */
676 		sc->sc_link.node_wwn = sc->sc_link.port_wwn;
677 		sc->sc_link.node_wwn &= ~(0xfULL << 56);
678 	}
679 
680 	memset(&saa, 0, sizeof(saa));
681 	saa.saa_sc_link = &sc->sc_link;
682 
683 	/* config_found() returns the scsibus attached to us */
684 	sc->sc_scsibus = (struct scsibus_softc *)config_found(&sc->sc_dev,
685 	    &saa, scsiprint);
686 
687 	return;
688 
689 free_scratch:
690 	qle_dmamem_free(sc, sc->sc_scratch);
691 free_ccbs:
692 	qle_free_ccbs(sc);
693 deintr:
694 	pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
695 	sc->sc_ih = NULL;
696 unmap:
697 	bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
698 	sc->sc_ios = 0;
699 }
700 
701 int
702 qle_detach(struct device *self, int flags)
703 {
704 	struct qle_softc *sc = (struct qle_softc *)self;
705 
706 	if (sc->sc_ih == NULL) {
707 		/* we didnt attach properly, so nothing to detach */
708 		return (0);
709 	}
710 
711 	pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
712 	sc->sc_ih = NULL;
713 
714 	bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
715 	sc->sc_ios = 0;
716 
717 	return (0);
718 }
719 
720 int
721 qle_classify_port(struct qle_softc *sc, u_int32_t location,
722     u_int64_t port_name, u_int64_t node_name, struct qle_fc_port **prev)
723 {
724 	struct qle_fc_port *port, *locmatch, *wwnmatch;
725 	locmatch = NULL;
726 	wwnmatch = NULL;
727 
728 	/* make sure we don't try to add a port or location twice */
729 	TAILQ_FOREACH(port, &sc->sc_ports_new, update) {
730 		if ((port->port_name == port_name &&
731 		    port->node_name == node_name) ||
732 		    port->location == location) {
733 			*prev = port;
734 			return (QLE_PORT_DISP_DUP);
735 		}
736 	}
737 
738 	/* if we're attaching, everything is new */
739 	if (sc->sc_scsibus == NULL) {
740 		*prev = NULL;
741 		return (QLE_PORT_DISP_NEW);
742 	}
743 
744 	TAILQ_FOREACH(port, &sc->sc_ports, ports) {
745 		if (port->location == location)
746 			locmatch = port;
747 
748 		if (port->port_name == port_name &&
749 		    port->node_name == node_name)
750 			wwnmatch = port;
751 	}
752 
753 	if (locmatch == NULL && wwnmatch == NULL) {
754 		*prev = NULL;
755 		return (QLE_PORT_DISP_NEW);
756 	} else if (locmatch == wwnmatch) {
757 		*prev = locmatch;
758 		return (QLE_PORT_DISP_SAME);
759 	} else if (wwnmatch != NULL) {
760 		*prev = wwnmatch;
761 		return (QLE_PORT_DISP_MOVED);
762 	} else {
763 		*prev = locmatch;
764 		return (QLE_PORT_DISP_CHANGED);
765 	}
766 }
767 
768 int
769 qle_get_loop_id(struct qle_softc *sc, int start)
770 {
771 	int i, last;
772 
773 	i = QLE_MIN_HANDLE;
774 	last = QLE_MAX_HANDLE;
775 	if (i < start)
776 		i = start;
777 
778 	for (; i <= last; i++) {
779 		if (sc->sc_targets[i] == NULL)
780 			return (i);
781 	}
782 
783 	return (-1);
784 }
785 
786 int
787 qle_get_port_db(struct qle_softc *sc, u_int16_t loopid, struct qle_dmamem *mem)
788 {
789 	sc->sc_mbox[0] = QLE_MBOX_GET_PORT_DB;
790 	sc->sc_mbox[1] = loopid;
791 	qle_mbox_putaddr(sc->sc_mbox, mem);
792 	bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(mem), 0,
793 	    sizeof(struct qle_get_port_db), BUS_DMASYNC_PREREAD);
794 	if (qle_mbox(sc, 0x00cf)) {
795 		DPRINTF(QLE_D_PORT, "%s: get port db for %d failed: %x\n",
796 		    DEVNAME(sc), loopid, sc->sc_mbox[0]);
797 		return (1);
798 	}
799 
800 	bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(mem), 0,
801 	    sizeof(struct qle_get_port_db), BUS_DMASYNC_POSTREAD);
802 	return (0);
803 }
804 
805 int
806 qle_get_port_name_list(struct qle_softc *sc, u_int32_t match)
807 {
808 	struct qle_port_name_list *l;
809 	struct qle_fc_port *port;
810 	int i;
811 
812 	sc->sc_mbox[0] = QLE_MBOX_GET_PORT_NAME_LIST;
813 	sc->sc_mbox[1] = 0;
814 	sc->sc_mbox[8] = QLE_DMA_LEN(sc->sc_scratch);
815 	sc->sc_mbox[9] = 0;
816 	qle_mbox_putaddr(sc->sc_mbox, sc->sc_scratch);
817 	bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(sc->sc_scratch), 0,
818 	    QLE_DMA_LEN(sc->sc_scratch), BUS_DMASYNC_PREREAD);
819 	if (qle_mbox(sc, 0x03cf)) {
820 		DPRINTF(QLE_D_PORT, "%s: get port name list failed: %x\n",
821 		    DEVNAME(sc), sc->sc_mbox[0]);
822 		return (1);
823 	}
824 	bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(sc->sc_scratch), 0,
825 	    sc->sc_mbox[1], BUS_DMASYNC_POSTREAD);
826 
827 	i = 0;
828 	l = QLE_DMA_KVA(sc->sc_scratch);
829 	mtx_enter(&sc->sc_port_mtx);
830 	while (i * sizeof(*l) < sc->sc_mbox[1]) {
831 		u_int16_t loopid;
832 		u_int32_t loc;
833 
834 		loopid = lemtoh16(&l[i].loopid) & 0xfff;
835 		/* skip special ports */
836 		switch (loopid) {
837 		case QLE_F_PORT_HANDLE:
838 		case QLE_SNS_HANDLE:
839 		case QLE_FABRIC_CTRL_HANDLE:
840 		case QLE_IP_BCAST_HANDLE:
841 			loc = 0;
842 			break;
843 		default:
844 			if (loopid <= sc->sc_loop_max_id) {
845 				loc = QLE_LOCATION_LOOP_ID(loopid);
846 			} else {
847 				/*
848 				 * we don't have the port id here, so just
849 				 * indicate it's a fabric port.
850 				 */
851 				loc = QLE_LOCATION_FABRIC;
852 			}
853 			break;
854 		}
855 
856 		if (match & loc) {
857 			port = malloc(sizeof(*port), M_DEVBUF, M_ZERO |
858 			    M_NOWAIT);
859 			if (port == NULL) {
860 				printf("%s: failed to allocate port struct\n",
861 				    DEVNAME(sc));
862 				break;
863 			}
864 			port->location = loc;
865 			port->loopid = loopid;
866 			port->port_name = letoh64(l[i].port_name);
867 			DPRINTF(QLE_D_PORT, "%s: loop id %d, port name %llx\n",
868 			    DEVNAME(sc), port->loopid, port->port_name);
869 			TAILQ_INSERT_TAIL(&sc->sc_ports_found, port, update);
870 		}
871 		i++;
872 	}
873 	mtx_leave(&sc->sc_port_mtx);
874 
875 	return (0);
876 }
877 
878 int
879 qle_add_loop_port(struct qle_softc *sc, struct qle_fc_port *port)
880 {
881 	struct qle_get_port_db *pdb;
882 	struct qle_fc_port *pport;
883 	int disp;
884 
885 	if (qle_get_port_db(sc, port->loopid, sc->sc_scratch) != 0) {
886 		return (1);
887 	}
888 	pdb = QLE_DMA_KVA(sc->sc_scratch);
889 
890 	if (lemtoh16(&pdb->prli_svc_word3) & QLE_SVC3_TARGET_ROLE)
891 		port->flags |= QLE_PORT_FLAG_IS_TARGET;
892 
893 	port->port_name = betoh64(pdb->port_name);
894 	port->node_name = betoh64(pdb->node_name);
895 	port->portid = (pdb->port_id[0] << 16) | (pdb->port_id[1] << 8) |
896 	    pdb->port_id[2];
897 
898 	mtx_enter(&sc->sc_port_mtx);
899 	disp = qle_classify_port(sc, port->location, port->port_name,
900 	    port->node_name, &pport);
901 	switch (disp) {
902 	case QLE_PORT_DISP_CHANGED:
903 	case QLE_PORT_DISP_MOVED:
904 	case QLE_PORT_DISP_NEW:
905 		TAILQ_INSERT_TAIL(&sc->sc_ports_new, port, update);
906 		sc->sc_targets[port->loopid] = port;
907 		break;
908 	case QLE_PORT_DISP_DUP:
909 		free(port, M_DEVBUF, sizeof *port);
910 		break;
911 	case QLE_PORT_DISP_SAME:
912 		TAILQ_REMOVE(&sc->sc_ports_gone, pport, update);
913 		free(port, M_DEVBUF, sizeof *port);
914 		break;
915 	}
916 	mtx_leave(&sc->sc_port_mtx);
917 
918 	switch (disp) {
919 	case QLE_PORT_DISP_CHANGED:
920 	case QLE_PORT_DISP_MOVED:
921 	case QLE_PORT_DISP_NEW:
922 		DPRINTF(QLE_D_PORT, "%s: %s %d; name %llx\n",
923 		    DEVNAME(sc), ISSET(port->flags, QLE_PORT_FLAG_IS_TARGET) ?
924 		    "target" : "non-target", port->loopid,
925 		    betoh64(pdb->port_name));
926 		break;
927 	default:
928 		break;
929 	}
930 	return (0);
931 }
932 
933 int
934 qle_add_fabric_port(struct qle_softc *sc, struct qle_fc_port *port)
935 {
936 	struct qle_get_port_db *pdb;
937 
938 	if (qle_get_port_db(sc, port->loopid, sc->sc_scratch) != 0) {
939 		free(port, M_DEVBUF, sizeof *port);
940 		return (1);
941 	}
942 	pdb = QLE_DMA_KVA(sc->sc_scratch);
943 
944 	if (lemtoh16(&pdb->prli_svc_word3) & QLE_SVC3_TARGET_ROLE)
945 		port->flags |= QLE_PORT_FLAG_IS_TARGET;
946 
947 	/*
948 	 * if we only know about this port because qle_get_port_name_list
949 	 * returned it, we don't have its port id or node name, so fill
950 	 * those in and update its location.
951 	 */
952 	if (port->location == QLE_LOCATION_FABRIC) {
953 		port->node_name = betoh64(pdb->node_name);
954 		port->port_name = betoh64(pdb->port_name);
955 		port->portid = (pdb->port_id[0] << 16) |
956 		    (pdb->port_id[1] << 8) | pdb->port_id[2];
957 		port->location = QLE_LOCATION_PORT_ID(port->portid);
958 	}
959 
960 	mtx_enter(&sc->sc_port_mtx);
961 	TAILQ_INSERT_TAIL(&sc->sc_ports_new, port, update);
962 	sc->sc_targets[port->loopid] = port;
963 	mtx_leave(&sc->sc_port_mtx);
964 
965 	DPRINTF(QLE_D_PORT, "%s: %s %d; name %llx\n",
966 	    DEVNAME(sc), ISSET(port->flags, QLE_PORT_FLAG_IS_TARGET) ?
967 	    "target" : "non-target", port->loopid, port->port_name);
968 	return (0);
969 }
970 
971 int
972 qle_add_logged_in_port(struct qle_softc *sc, u_int16_t loopid,
973     u_int32_t portid)
974 {
975 	struct qle_fc_port *port;
976 	struct qle_get_port_db *pdb;
977 	u_int64_t node_name, port_name;
978 	int flags, ret;
979 
980 	ret = qle_get_port_db(sc, loopid, sc->sc_scratch);
981 	mtx_enter(&sc->sc_port_mtx);
982 	if (ret != 0) {
983 		/* put in a fake port to prevent use of this loop id */
984 		printf("%s: loop id %d used, but can't see what's using it\n",
985 		    DEVNAME(sc), loopid);
986 		node_name = 0;
987 		port_name = 0;
988 		flags = 0;
989 	} else {
990 		pdb = QLE_DMA_KVA(sc->sc_scratch);
991 		node_name = betoh64(pdb->node_name);
992 		port_name = betoh64(pdb->port_name);
993 		flags = 0;
994 		if (lemtoh16(&pdb->prli_svc_word3) & QLE_SVC3_TARGET_ROLE)
995 			flags |= QLE_PORT_FLAG_IS_TARGET;
996 
997 		/* see if we've already found this port */
998 		TAILQ_FOREACH(port, &sc->sc_ports_found, update) {
999 			if ((port->node_name == node_name) &&
1000 			    (port->port_name == port_name) &&
1001 			    (port->portid == portid)) {
1002 				mtx_leave(&sc->sc_port_mtx);
1003 				DPRINTF(QLE_D_PORT, "%s: already found port "
1004 				    "%06x\n", DEVNAME(sc), portid);
1005 				return (0);
1006 			}
1007 		}
1008 	}
1009 
1010 	port = malloc(sizeof(*port), M_DEVBUF, M_ZERO | M_NOWAIT);
1011 	if (port == NULL) {
1012 		mtx_leave(&sc->sc_port_mtx);
1013 		printf("%s: failed to allocate a port structure\n",
1014 		    DEVNAME(sc));
1015 		return (1);
1016 	}
1017 	port->location = QLE_LOCATION_PORT_ID(portid);
1018 	port->port_name = port_name;
1019 	port->node_name = node_name;
1020 	port->loopid = loopid;
1021 	port->portid = portid;
1022 	port->flags = flags;
1023 
1024 	TAILQ_INSERT_TAIL(&sc->sc_ports, port, ports);
1025 	sc->sc_targets[port->loopid] = port;
1026 	mtx_leave(&sc->sc_port_mtx);
1027 
1028 	DPRINTF(QLE_D_PORT, "%s: added logged in port %06x at %d\n",
1029 	    DEVNAME(sc), portid, loopid);
1030 	return (0);
1031 }
1032 
1033 struct qle_ccb *
1034 qle_handle_resp(struct qle_softc *sc, u_int32_t id)
1035 {
1036 	struct qle_ccb *ccb;
1037 	struct qle_iocb_status *status;
1038 	struct qle_iocb_req6 *req;
1039 	struct scsi_xfer *xs;
1040 	u_int32_t handle;
1041 	u_int16_t completion;
1042 	u_int8_t *entry;
1043 	u_int8_t *data;
1044 
1045 	ccb = NULL;
1046 	entry = QLE_DMA_KVA(sc->sc_responses) + (id * QLE_QUEUE_ENTRY_SIZE);
1047 
1048 	bus_dmamap_sync(sc->sc_dmat,
1049 	    QLE_DMA_MAP(sc->sc_responses), id * QLE_QUEUE_ENTRY_SIZE,
1050 	    QLE_QUEUE_ENTRY_SIZE, BUS_DMASYNC_POSTREAD);
1051 
1052 	qle_dump_iocb(sc, entry);
1053 	switch(entry[0]) {
1054 	case QLE_IOCB_STATUS:
1055 		status = (struct qle_iocb_status *)entry;
1056 		handle = status->handle;
1057 		if (handle > sc->sc_maxcmds) {
1058 			panic("bad completed command handle: %d (> %d)",
1059 			    handle, sc->sc_maxcmds);
1060 		}
1061 
1062 		ccb = &sc->sc_ccbs[handle];
1063 		xs = ccb->ccb_xs;
1064 		if (xs == NULL) {
1065 			DPRINTF(QLE_D_IO, "%s: got status for inactive ccb %d\n",
1066 			    DEVNAME(sc), handle);
1067 			ccb = NULL;
1068 			break;
1069 		}
1070 		if (xs->io != ccb) {
1071 			panic("completed command handle doesn't match xs "
1072 			    "(handle %d, ccb %p, xs->io %p)", handle, ccb,
1073 			    xs->io);
1074 		}
1075 
1076 		if (xs->datalen > 0) {
1077 			if (ccb->ccb_dmamap->dm_nsegs >
1078 			    QLE_IOCB_SEGS_PER_CMD) {
1079 				bus_dmamap_sync(sc->sc_dmat,
1080 				    QLE_DMA_MAP(sc->sc_segments),
1081 				    ccb->ccb_seg_offset,
1082 				    sizeof(*ccb->ccb_segs) *
1083 				    ccb->ccb_dmamap->dm_nsegs + 1,
1084 				    BUS_DMASYNC_POSTWRITE);
1085 			}
1086 
1087 			bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmamap, 0,
1088 			    ccb->ccb_dmamap->dm_mapsize,
1089 			    (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
1090 			    BUS_DMASYNC_POSTWRITE);
1091 			bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmamap);
1092 		}
1093 
1094 		xs->status = lemtoh16(&status->scsi_status) & 0xff;
1095 		xs->resid = 0;
1096 		completion = lemtoh16(&status->completion);
1097 		switch (completion) {
1098 		case QLE_IOCB_STATUS_DATA_UNDERRUN:
1099 			xs->resid = lemtoh32(&status->resid);
1100 		case QLE_IOCB_STATUS_DATA_OVERRUN:
1101 		case QLE_IOCB_STATUS_COMPLETE:
1102 			if (lemtoh16(&status->scsi_status) &
1103 			    QLE_SCSI_STATUS_SENSE_VALID) {
1104 				u_int32_t *pp;
1105 				int sr;
1106 				data = status->data +
1107 				    lemtoh32(&status->fcp_rsp_len);
1108 				sr = MIN(lemtoh32(&status->fcp_sense_len),
1109 				    sizeof(xs->sense));
1110 				memcpy(&xs->sense, data, sr);
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_nsec(sc->sc_mbox, &sc->sc_mbox_mtx, PRIBIO,
1496 			    "qlembox", INFSLP);
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_cancel(struct qle_softc *sc)
1610 {
1611 	atomic_swap_uint(&sc->sc_update_tasks, 0);
1612 	timeout_del(&sc->sc_update_timeout);
1613 	task_del(sc->sc_update_taskq, &sc->sc_update_task);
1614 }
1615 
1616 void
1617 qle_update_start(struct qle_softc *sc, int task)
1618 {
1619 	atomic_setbits_int(&sc->sc_update_tasks, task);
1620 	if (!timeout_pending(&sc->sc_update_timeout))
1621 		task_add(sc->sc_update_taskq, &sc->sc_update_task);
1622 }
1623 
1624 void
1625 qle_update_defer(struct qle_softc *sc, int task)
1626 {
1627 	atomic_setbits_int(&sc->sc_update_tasks, task);
1628 	timeout_del(&sc->sc_update_timeout);
1629 	task_del(sc->sc_update_taskq, &sc->sc_update_task);
1630 	timeout_add_msec(&sc->sc_update_timeout, QLE_LOOP_SETTLE);
1631 }
1632 
1633 void
1634 qle_clear_port_lists(struct qle_softc *sc)
1635 {
1636 	struct qle_fc_port *port;
1637 	while (!TAILQ_EMPTY(&sc->sc_ports_found)) {
1638 		port = TAILQ_FIRST(&sc->sc_ports_found);
1639 		TAILQ_REMOVE(&sc->sc_ports_found, port, update);
1640 		free(port, M_DEVBUF, sizeof *port);
1641 	}
1642 
1643 	while (!TAILQ_EMPTY(&sc->sc_ports_new)) {
1644 		port = TAILQ_FIRST(&sc->sc_ports_new);
1645 		TAILQ_REMOVE(&sc->sc_ports_new, port, update);
1646 		free(port, M_DEVBUF, sizeof *port);
1647 	}
1648 
1649 	while (!TAILQ_EMPTY(&sc->sc_ports_gone)) {
1650 		port = TAILQ_FIRST(&sc->sc_ports_gone);
1651 		TAILQ_REMOVE(&sc->sc_ports_gone, port, update);
1652 	}
1653 }
1654 
1655 int
1656 qle_softreset(struct qle_softc *sc)
1657 {
1658 	int i;
1659 	qle_set_ints(sc, 0);
1660 
1661 	/* set led control bits, stop dma */
1662 	qle_write(sc, QLE_GPIO_DATA, 0);
1663 	qle_write(sc, QLE_CTRL_STATUS, QLE_CTRL_DMA_SHUTDOWN);
1664 	while (qle_read(sc, QLE_CTRL_STATUS) & QLE_CTRL_DMA_ACTIVE) {
1665 		DPRINTF(QLE_D_IO, "%s: dma still active\n", DEVNAME(sc));
1666 		delay(100);
1667 	}
1668 
1669 	/* reset */
1670 	qle_write(sc, QLE_CTRL_STATUS, QLE_CTRL_RESET | QLE_CTRL_DMA_SHUTDOWN);
1671 	delay(100);
1672 	/* clear data and control dma engines? */
1673 
1674 	/* wait for soft reset to clear */
1675 	for (i = 0; i < 1000; i++) {
1676 		if (qle_read_mbox(sc, 0) == 0x0000)
1677 			break;
1678 
1679 		delay(100);
1680 	}
1681 
1682 	if (i == 1000) {
1683 		printf("%s: reset mbox didn't clear\n", DEVNAME(sc));
1684 		qle_set_ints(sc, 0);
1685 		return (ENXIO);
1686 	}
1687 
1688 	for (i = 0; i < 500000; i++) {
1689 		if ((qle_read(sc, QLE_CTRL_STATUS) & QLE_CTRL_RESET) == 0)
1690 			break;
1691 		delay(5);
1692 	}
1693 	if (i == 500000) {
1694 		printf("%s: reset status didn't clear\n", DEVNAME(sc));
1695 		return (ENXIO);
1696 	}
1697 
1698 	/* reset risc processor */
1699 	qle_host_cmd(sc, QLE_HOST_CMD_RESET);
1700 	qle_host_cmd(sc, QLE_HOST_CMD_RELEASE);
1701 	qle_host_cmd(sc, QLE_HOST_CMD_CLEAR_RESET);
1702 
1703 	/* wait for reset to clear */
1704 	for (i = 0; i < 1000; i++) {
1705 		if (qle_read_mbox(sc, 0) == 0x0000)
1706 			break;
1707 		delay(100);
1708 	}
1709 	if (i == 1000) {
1710 		printf("%s: risc not ready after reset\n", DEVNAME(sc));
1711 		return (ENXIO);
1712 	}
1713 
1714 	/* reset queue pointers */
1715 	qle_write(sc, QLE_REQ_IN, 0);
1716 	qle_write(sc, QLE_REQ_OUT, 0);
1717 	qle_write(sc, QLE_RESP_IN, 0);
1718 	qle_write(sc, QLE_RESP_OUT, 0);
1719 
1720 	qle_set_ints(sc, 1);
1721 
1722 	/* do a basic mailbox operation to check we're alive */
1723 	sc->sc_mbox[0] = QLE_MBOX_NOP;
1724 	if (qle_mbox(sc, 0x0001)) {
1725 		printf("ISP not responding after reset\n");
1726 		return (ENXIO);
1727 	}
1728 
1729 	return (0);
1730 }
1731 
1732 void
1733 qle_update_topology(struct qle_softc *sc)
1734 {
1735 	sc->sc_mbox[0] = QLE_MBOX_GET_ID;
1736 	if (qle_mbox(sc, 0x0001)) {
1737 		DPRINTF(QLE_D_PORT, "%s: unable to get loop id\n", DEVNAME(sc));
1738 		sc->sc_topology = QLE_TOPO_N_PORT_NO_TARGET;
1739 	} else {
1740 		sc->sc_topology = sc->sc_mbox[6];
1741 		sc->sc_loop_id = sc->sc_mbox[1];
1742 
1743 		switch (sc->sc_topology) {
1744 		case QLE_TOPO_NL_PORT:
1745 		case QLE_TOPO_N_PORT:
1746 			DPRINTF(QLE_D_PORT, "%s: loop id %d\n", DEVNAME(sc),
1747 			    sc->sc_loop_id);
1748 			break;
1749 
1750 		case QLE_TOPO_FL_PORT:
1751 		case QLE_TOPO_F_PORT:
1752 			sc->sc_port_id = sc->sc_mbox[2] |
1753 			    (sc->sc_mbox[3] << 16);
1754 			DPRINTF(QLE_D_PORT, "%s: fabric port id %06x\n",
1755 			    DEVNAME(sc), sc->sc_port_id);
1756 			break;
1757 
1758 		case QLE_TOPO_N_PORT_NO_TARGET:
1759 		default:
1760 			DPRINTF(QLE_D_PORT, "%s: not useful\n", DEVNAME(sc));
1761 			break;
1762 		}
1763 
1764 		switch (sc->sc_topology) {
1765 		case QLE_TOPO_NL_PORT:
1766 		case QLE_TOPO_FL_PORT:
1767 			sc->sc_loop_max_id = 126;
1768 			break;
1769 
1770 		case QLE_TOPO_N_PORT:
1771 			sc->sc_loop_max_id = 2;
1772 			break;
1773 
1774 		default:
1775 			sc->sc_loop_max_id = 0;
1776 			break;
1777 		}
1778 	}
1779 }
1780 
1781 int
1782 qle_update_fabric(struct qle_softc *sc)
1783 {
1784 	/*struct qle_sns_rft_id *rft;*/
1785 
1786 	switch (sc->sc_topology) {
1787 	case QLE_TOPO_F_PORT:
1788 	case QLE_TOPO_FL_PORT:
1789 		break;
1790 
1791 	default:
1792 		return (0);
1793 	}
1794 
1795 	/* get the name server's port db entry */
1796 	sc->sc_mbox[0] = QLE_MBOX_GET_PORT_DB;
1797 	sc->sc_mbox[1] = QLE_F_PORT_HANDLE;
1798 	qle_mbox_putaddr(sc->sc_mbox, sc->sc_scratch);
1799 	bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(sc->sc_scratch), 0,
1800 	    sizeof(struct qle_get_port_db), BUS_DMASYNC_PREREAD);
1801 	if (qle_mbox(sc, 0x00cf)) {
1802 		DPRINTF(QLE_D_PORT, "%s: get port db for SNS failed: %x\n",
1803 		    DEVNAME(sc), sc->sc_mbox[0]);
1804 		sc->sc_sns_port_name = 0;
1805 	} else {
1806 		struct qle_get_port_db *pdb;
1807 		bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(sc->sc_scratch), 0,
1808 		    sizeof(struct qle_get_port_db), BUS_DMASYNC_POSTREAD);
1809 		pdb = QLE_DMA_KVA(sc->sc_scratch);
1810 		DPRINTF(QLE_D_PORT, "%s: SNS port name %llx\n", DEVNAME(sc),
1811 		    betoh64(pdb->port_name));
1812 		sc->sc_sns_port_name = betoh64(pdb->port_name);
1813 	}
1814 
1815 	/*
1816 	 * register fc4 types with the fabric
1817 	 * some switches do this automatically, but apparently
1818 	 * some don't.
1819 	 */
1820 	/*
1821 	rft = QLE_DMA_KVA(sc->sc_scratch);
1822 	memset(rft, 0, sizeof(*rft) + sizeof(struct qle_sns_req_hdr));
1823 	htolem16(&rft->subcmd, QLE_SNS_RFT_ID);
1824 	htolem16(&rft->max_word, sizeof(struct qle_sns_req_hdr) / 4);
1825 	htolem32(&rft->port_id, sc->sc_port_id);
1826 	rft->fc4_types[0] = (1 << QLE_FC4_SCSI);
1827 	if (qle_sns_req(sc, sc->sc_scratch, sizeof(*rft))) {
1828 		printf("%s: RFT_ID failed\n", DEVNAME(sc));
1829 		/ * we might be able to continue after this fails * /
1830 	}
1831 	*/
1832 
1833 	return (1);
1834 }
1835 
1836 int
1837 qle_ct_pass_through(struct qle_softc *sc, u_int32_t port_handle,
1838     struct qle_dmamem *mem, size_t req_size, size_t resp_size)
1839 {
1840 	struct qle_iocb_ct_passthrough *iocb;
1841 	u_int16_t req;
1842 	u_int64_t offset;
1843 	int rv;
1844 
1845 	mtx_enter(&sc->sc_queue_mtx);
1846 
1847 	req = sc->sc_next_req_id++;
1848 	if (sc->sc_next_req_id == sc->sc_maxcmds)
1849 		sc->sc_next_req_id = 0;
1850 
1851 	offset = (req * QLE_QUEUE_ENTRY_SIZE);
1852 	iocb = QLE_DMA_KVA(sc->sc_requests) + offset;
1853 	bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(sc->sc_requests), offset,
1854 	    QLE_QUEUE_ENTRY_SIZE, BUS_DMASYNC_POSTWRITE);
1855 
1856 	memset(iocb, 0, QLE_QUEUE_ENTRY_SIZE);
1857 	iocb->entry_type = QLE_IOCB_CT_PASSTHROUGH;
1858 	iocb->entry_count = 1;
1859 
1860 	iocb->req_handle = 9;
1861 	htolem16(&iocb->req_nport_handle, port_handle);
1862 	htolem16(&iocb->req_dsd_count, 1);
1863 	htolem16(&iocb->req_resp_dsd_count, 1);
1864 	htolem32(&iocb->req_cmd_byte_count, req_size);
1865 	htolem32(&iocb->req_resp_byte_count, resp_size);
1866 	qle_sge(&iocb->req_cmd_seg, QLE_DMA_DVA(mem), req_size);
1867 	qle_sge(&iocb->req_resp_seg, QLE_DMA_DVA(mem) + req_size, resp_size);
1868 
1869 	bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(mem), 0, QLE_DMA_LEN(mem),
1870 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1871 	qle_write(sc, QLE_REQ_IN, sc->sc_next_req_id);
1872 	sc->sc_fabric_pending = 1;
1873 	mtx_leave(&sc->sc_queue_mtx);
1874 
1875 	/* maybe put a proper timeout on this */
1876 	rv = 0;
1877 	while (sc->sc_fabric_pending == 1) {
1878 		if (sc->sc_scsibus == NULL) {
1879 			u_int16_t isr, info;
1880 
1881 			delay(100);
1882 			if (qle_read_isr(sc, &isr, &info) != 0)
1883 				qle_handle_intr(sc, isr, info);
1884 		} else {
1885 			tsleep_nsec(sc->sc_scratch, PRIBIO, "qle_fabric",
1886 			    SEC_TO_NSEC(1));
1887 		}
1888 	}
1889 	if (rv == 0)
1890 		bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(mem), 0,
1891 		    QLE_DMA_LEN(mem), BUS_DMASYNC_POSTREAD |
1892 		    BUS_DMASYNC_POSTWRITE);
1893 
1894 	sc->sc_fabric_pending = 0;
1895 
1896 	return (rv);
1897 }
1898 
1899 struct qle_fc_port *
1900 qle_next_fabric_port(struct qle_softc *sc, u_int32_t *firstport,
1901     u_int32_t *lastport)
1902 {
1903 	struct qle_ct_ga_nxt_req *ga;
1904 	struct qle_ct_ga_nxt_resp *gar;
1905 	struct qle_fc_port *fport;
1906 	int result;
1907 
1908 	/* get the next port from the fabric nameserver */
1909 	ga = QLE_DMA_KVA(sc->sc_scratch);
1910 	memset(ga, 0, sizeof(*ga) + sizeof(*gar));
1911 	ga->header.ct_revision = 0x01;
1912 	ga->header.ct_gs_type = 0xfc;
1913 	ga->header.ct_gs_subtype = 0x02;
1914 	ga->subcmd = htobe16(QLE_SNS_GA_NXT);
1915 	ga->max_word = htobe16((sizeof(*gar) - 16) / 4);
1916 	ga->port_id = htobe32(*lastport);
1917 	result = qle_ct_pass_through(sc, QLE_SNS_HANDLE, sc->sc_scratch,
1918 	    sizeof(*ga), sizeof(*gar));
1919 	if (result) {
1920 		DPRINTF(QLE_D_PORT, "%s: GA_NXT %06x failed: %x\n", DEVNAME(sc),
1921 		    *lastport, result);
1922 		*lastport = 0xffffffff;
1923 		return (NULL);
1924 	}
1925 
1926 	gar = (struct qle_ct_ga_nxt_resp *)(ga + 1);
1927 	/* if the response is all zeroes, try again */
1928 	if (gar->port_type_id == 0 && gar->port_name == 0 &&
1929 	    gar->node_name == 0) {
1930 		DPRINTF(QLE_D_PORT, "%s: GA_NXT returned junk\n", DEVNAME(sc));
1931 		return (NULL);
1932 	}
1933 
1934 	/* are we back at the start? */
1935 	*lastport = betoh32(gar->port_type_id) & 0xffffff;
1936 	if (*lastport == *firstport) {
1937 		*lastport = 0xffffffff;
1938 		return (NULL);
1939 	}
1940 	if (*firstport == 0xffffffff)
1941 		*firstport = *lastport;
1942 
1943 	DPRINTF(QLE_D_PORT, "%s: GA_NXT: port id: %06x, wwpn %llx, wwnn %llx\n",
1944 	    DEVNAME(sc), *lastport, betoh64(gar->port_name),
1945 	    betoh64(gar->node_name));
1946 
1947 	/* don't try to log in to ourselves */
1948 	if (*lastport == sc->sc_port_id) {
1949 		return (NULL);
1950 	}
1951 
1952 	fport = malloc(sizeof(*fport), M_DEVBUF, M_ZERO | M_NOWAIT);
1953 	if (fport == NULL) {
1954 		printf("%s: failed to allocate a port struct\n",
1955 		    DEVNAME(sc));
1956 		*lastport = 0xffffffff;
1957 		return (NULL);
1958 	}
1959 	fport->port_name = betoh64(gar->port_name);
1960 	fport->node_name = betoh64(gar->node_name);
1961 	fport->location = QLE_LOCATION_PORT_ID(*lastport);
1962 	fport->portid = *lastport;
1963 	return (fport);
1964 }
1965 
1966 int
1967 qle_fabric_plogx(struct qle_softc *sc, struct qle_fc_port *port, int flags,
1968     u_int32_t *info)
1969 {
1970 	struct qle_iocb_plogx *iocb;
1971 	u_int16_t req;
1972 	u_int64_t offset;
1973 	int rv;
1974 
1975 	mtx_enter(&sc->sc_queue_mtx);
1976 
1977 	req = sc->sc_next_req_id++;
1978 	if (sc->sc_next_req_id == sc->sc_maxcmds)
1979 		sc->sc_next_req_id = 0;
1980 
1981 	offset = (req * QLE_QUEUE_ENTRY_SIZE);
1982 	iocb = QLE_DMA_KVA(sc->sc_requests) + offset;
1983 	bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(sc->sc_requests), offset,
1984 	    QLE_QUEUE_ENTRY_SIZE, BUS_DMASYNC_POSTWRITE);
1985 
1986 	memset(iocb, 0, QLE_QUEUE_ENTRY_SIZE);
1987 	iocb->entry_type = QLE_IOCB_PLOGX;
1988 	iocb->entry_count = 1;
1989 
1990 	iocb->req_handle = 7;
1991 	htolem16(&iocb->req_nport_handle, port->loopid);
1992 	htolem16(&iocb->req_port_id_lo, port->portid);
1993 	iocb->req_port_id_hi = port->portid >> 16;
1994 	htolem16(&iocb->req_flags, flags);
1995 
1996 	DPRINTF(QLE_D_PORT, "%s: plogx loop id %d port %06x, flags %x\n",
1997 	    DEVNAME(sc), port->loopid, port->portid, flags);
1998 	qle_dump_iocb(sc, iocb);
1999 
2000 	qle_write(sc, QLE_REQ_IN, sc->sc_next_req_id);
2001 	sc->sc_fabric_pending = 1;
2002 	mtx_leave(&sc->sc_queue_mtx);
2003 
2004 	/* maybe put a proper timeout on this */
2005 	rv = 0;
2006 	while (sc->sc_fabric_pending == 1) {
2007 		if (sc->sc_scsibus == NULL) {
2008 			u_int16_t isr, info;
2009 
2010 			delay(100);
2011 			if (qle_read_isr(sc, &isr, &info) != 0)
2012 				qle_handle_intr(sc, isr, info);
2013 		} else {
2014 			tsleep_nsec(sc->sc_scratch, PRIBIO, "qle_fabric",
2015 			    SEC_TO_NSEC(1));
2016 		}
2017 	}
2018 	sc->sc_fabric_pending = 0;
2019 
2020 	iocb = (struct qle_iocb_plogx *)&sc->sc_fabric_response;
2021 	rv = lemtoh16(&iocb->req_status);
2022 	if (rv == QLE_PLOGX_ERROR) {
2023 		rv = lemtoh32(&iocb->req_ioparms[0]);
2024 		*info = lemtoh32(&iocb->req_ioparms[1]);
2025 	}
2026 
2027 	return (rv);
2028 }
2029 
2030 int
2031 qle_fabric_plogi(struct qle_softc *sc, struct qle_fc_port *port)
2032 {
2033 	u_int32_t info;
2034 	int err, loopid;
2035 
2036 	loopid = 0;
2037 retry:
2038 	if (port->loopid == 0) {
2039 
2040 		mtx_enter(&sc->sc_port_mtx);
2041 		loopid = qle_get_loop_id(sc, loopid);
2042 		mtx_leave(&sc->sc_port_mtx);
2043 		if (loopid == -1) {
2044 			printf("%s: ran out of loop ids\n", DEVNAME(sc));
2045 			return (1);
2046 		}
2047 
2048 		port->loopid = loopid;
2049 	}
2050 
2051 	err = qle_fabric_plogx(sc, port, QLE_PLOGX_LOGIN, &info);
2052 	switch (err) {
2053 	case 0:
2054 		DPRINTF(QLE_D_PORT, "%s: logged in to %06x as %d\n",
2055 		    DEVNAME(sc), port->portid, port->loopid);
2056 		port->flags &= ~QLE_PORT_FLAG_NEEDS_LOGIN;
2057 		return (0);
2058 
2059 	case QLE_PLOGX_ERROR_PORT_ID_USED:
2060 		DPRINTF(QLE_D_PORT, "%s: already logged in to %06x as %d\n",
2061 		    DEVNAME(sc), port->portid, info);
2062 		port->loopid = info;
2063 		port->flags &= ~QLE_PORT_FLAG_NEEDS_LOGIN;
2064 		return (0);
2065 
2066 	case QLE_PLOGX_ERROR_HANDLE_USED:
2067 		if (qle_add_logged_in_port(sc, loopid, info)) {
2068 			return (1);
2069 		}
2070 		port->loopid = 0;
2071 		loopid++;
2072 		goto retry;
2073 
2074 	default:
2075 		DPRINTF(QLE_D_PORT, "%s: error %x logging in to port %06x\n",
2076 		    DEVNAME(sc), err, port->portid);
2077 		port->loopid = 0;
2078 		return (1);
2079 	}
2080 }
2081 
2082 void
2083 qle_fabric_plogo(struct qle_softc *sc, struct qle_fc_port *port)
2084 {
2085 	int err;
2086 	u_int32_t info;
2087 
2088 	/*
2089 	 * we only log out if we can't see the port any more, so we always
2090 	 * want to do an explicit logout and free the n-port handle.
2091 	 */
2092 	err = qle_fabric_plogx(sc, port, QLE_PLOGX_LOGOUT |
2093 	    QLE_PLOGX_LOGOUT_EXPLICIT | QLE_PLOGX_LOGOUT_FREE_HANDLE, &info);
2094 	if (err == 0) {
2095 		DPRINTF(QLE_D_PORT, "%s: logged out of port %06x\n",
2096 		    DEVNAME(sc), port->portid);
2097 	} else {
2098 		DPRINTF(QLE_D_PORT, "%s: failed to log out of port %06x: "
2099 		    "%x %x\n", DEVNAME(sc), port->portid, err, info);
2100 	}
2101 }
2102 
2103 void
2104 qle_deferred_update(void *xsc)
2105 {
2106 	struct qle_softc *sc = xsc;
2107 	task_add(sc->sc_update_taskq, &sc->sc_update_task);
2108 }
2109 
2110 void
2111 qle_do_update(void *xsc)
2112 {
2113 	struct qle_softc *sc = xsc;
2114 	int firstport, lastport;
2115 	struct qle_fc_port *port, *fport;
2116 
2117 	DPRINTF(QLE_D_PORT, "%s: updating\n", DEVNAME(sc));
2118 	while (sc->sc_update_tasks != 0) {
2119 		if (sc->sc_update_tasks & QLE_UPDATE_TASK_CLEAR_ALL) {
2120 			TAILQ_HEAD(, qle_fc_port) detach;
2121 			DPRINTF(QLE_D_PORT, "%s: detaching everything\n",
2122 			    DEVNAME(sc));
2123 
2124 			mtx_enter(&sc->sc_port_mtx);
2125 			qle_clear_port_lists(sc);
2126 			TAILQ_INIT(&detach);
2127 			while (!TAILQ_EMPTY(&sc->sc_ports)) {
2128 				port = TAILQ_FIRST(&sc->sc_ports);
2129 				TAILQ_REMOVE(&sc->sc_ports, port, ports);
2130 				TAILQ_INSERT_TAIL(&detach, port, ports);
2131 			}
2132 			mtx_leave(&sc->sc_port_mtx);
2133 
2134 			while (!TAILQ_EMPTY(&detach)) {
2135 				port = TAILQ_FIRST(&detach);
2136 				TAILQ_REMOVE(&detach, port, ports);
2137 				if (port->flags & QLE_PORT_FLAG_IS_TARGET) {
2138 					scsi_detach_target(sc->sc_scsibus,
2139 					    port->loopid, DETACH_FORCE |
2140 					    DETACH_QUIET);
2141 					sc->sc_targets[port->loopid] = NULL;
2142 				}
2143 				if (port->location & QLE_LOCATION_FABRIC)
2144 					qle_fabric_plogo(sc, port);
2145 
2146 				free(port, M_DEVBUF, sizeof *port);
2147 			}
2148 
2149 			qle_update_done(sc, QLE_UPDATE_TASK_CLEAR_ALL);
2150 			continue;
2151 		}
2152 
2153 		if (sc->sc_update_tasks & QLE_UPDATE_TASK_SOFTRESET) {
2154 			DPRINTF(QLE_D_IO, "%s: attempting softreset\n",
2155 			    DEVNAME(sc));
2156 			if (qle_softreset(sc) != 0) {
2157 				DPRINTF(QLE_D_IO, "%s: couldn't softreset\n",
2158 				    DEVNAME(sc));
2159 			}
2160 			qle_update_done(sc, QLE_UPDATE_TASK_SOFTRESET);
2161 			continue;
2162 		}
2163 
2164 		if (sc->sc_update_tasks & QLE_UPDATE_TASK_UPDATE_TOPO) {
2165 			DPRINTF(QLE_D_PORT, "%s: updating topology\n",
2166 			    DEVNAME(sc));
2167 			qle_update_topology(sc);
2168 			qle_update_done(sc, QLE_UPDATE_TASK_UPDATE_TOPO);
2169 			continue;
2170 		}
2171 
2172 		if (sc->sc_update_tasks & QLE_UPDATE_TASK_GET_PORT_LIST) {
2173 			DPRINTF(QLE_D_PORT, "%s: getting port name list\n",
2174 			    DEVNAME(sc));
2175 			mtx_enter(&sc->sc_port_mtx);
2176 			qle_clear_port_lists(sc);
2177 			mtx_leave(&sc->sc_port_mtx);
2178 
2179 			qle_get_port_name_list(sc, QLE_LOCATION_LOOP |
2180 			    QLE_LOCATION_FABRIC);
2181 			mtx_enter(&sc->sc_port_mtx);
2182 			TAILQ_FOREACH(port, &sc->sc_ports, ports) {
2183 				TAILQ_INSERT_TAIL(&sc->sc_ports_gone, port,
2184 				    update);
2185 				if (port->location & QLE_LOCATION_FABRIC) {
2186 					port->flags |=
2187 					    QLE_PORT_FLAG_NEEDS_LOGIN;
2188 				}
2189 			}
2190 
2191 			/* take care of ports that haven't changed first */
2192 			TAILQ_FOREACH(fport, &sc->sc_ports_found, update) {
2193 				port = sc->sc_targets[fport->loopid];
2194 				if (port == NULL || fport->port_name !=
2195 				    port->port_name) {
2196 					/* new or changed port, handled later */
2197 					continue;
2198 				}
2199 
2200 				/*
2201 				 * the port hasn't been logged out, which
2202 				 * means we don't need to log in again, and,
2203 				 * for loop ports, that the port still exists
2204 				 */
2205 				port->flags &= ~QLE_PORT_FLAG_NEEDS_LOGIN;
2206 				if (port->location & QLE_LOCATION_LOOP)
2207 					TAILQ_REMOVE(&sc->sc_ports_gone,
2208 					    port, update);
2209 
2210 				fport->location = 0;
2211 			}
2212 			mtx_leave(&sc->sc_port_mtx);
2213 			qle_update_start(sc, QLE_UPDATE_TASK_PORT_LIST);
2214 			qle_update_done(sc, QLE_UPDATE_TASK_GET_PORT_LIST);
2215 			continue;
2216 		}
2217 
2218 		if (sc->sc_update_tasks & QLE_UPDATE_TASK_PORT_LIST) {
2219 			mtx_enter(&sc->sc_port_mtx);
2220 			fport = TAILQ_FIRST(&sc->sc_ports_found);
2221 			if (fport != NULL) {
2222 				TAILQ_REMOVE(&sc->sc_ports_found, fport,
2223 				    update);
2224 			}
2225 			mtx_leave(&sc->sc_port_mtx);
2226 
2227 			if (fport == NULL) {
2228 				DPRINTF(QLE_D_PORT, "%s: done with ports\n",
2229 				    DEVNAME(sc));
2230 				qle_update_done(sc,
2231 				    QLE_UPDATE_TASK_PORT_LIST);
2232 				qle_update_start(sc,
2233 				    QLE_UPDATE_TASK_SCAN_FABRIC);
2234 			} else if (fport->location & QLE_LOCATION_LOOP) {
2235 				DPRINTF(QLE_D_PORT, "%s: loop port %04x\n",
2236 				    DEVNAME(sc), fport->loopid);
2237 				if (qle_add_loop_port(sc, fport) != 0)
2238 					free(fport, M_DEVBUF, sizeof *port);
2239 			} else if (fport->location & QLE_LOCATION_FABRIC) {
2240 				qle_add_fabric_port(sc, fport);
2241 			} else {
2242 				/* already processed */
2243 				free(fport, M_DEVBUF, sizeof *port);
2244 			}
2245 			continue;
2246 		}
2247 
2248 		if (sc->sc_update_tasks & QLE_UPDATE_TASK_SCAN_FABRIC) {
2249 			DPRINTF(QLE_D_PORT, "%s: starting fabric scan\n",
2250 			    DEVNAME(sc));
2251 			lastport = sc->sc_port_id;
2252 			firstport = 0xffffffff;
2253 			if (qle_update_fabric(sc))
2254 				qle_update_start(sc,
2255 				    QLE_UPDATE_TASK_SCANNING_FABRIC);
2256 			else
2257 				qle_update_start(sc,
2258 				    QLE_UPDATE_TASK_ATTACH_TARGET |
2259 				    QLE_UPDATE_TASK_DETACH_TARGET);
2260 
2261 			qle_update_done(sc, QLE_UPDATE_TASK_SCAN_FABRIC);
2262 			continue;
2263 		}
2264 
2265 		if (sc->sc_update_tasks & QLE_UPDATE_TASK_SCANNING_FABRIC) {
2266 			fport = qle_next_fabric_port(sc, &firstport, &lastport);
2267 			if (fport != NULL) {
2268 				int disp;
2269 
2270 				mtx_enter(&sc->sc_port_mtx);
2271 				disp = qle_classify_port(sc, fport->location,
2272 				    fport->port_name, fport->node_name, &port);
2273 				switch (disp) {
2274 				case QLE_PORT_DISP_CHANGED:
2275 				case QLE_PORT_DISP_MOVED:
2276 					/* we'll log out the old port later */
2277 				case QLE_PORT_DISP_NEW:
2278 					DPRINTF(QLE_D_PORT, "%s: new port "
2279 					    "%06x\n", DEVNAME(sc),
2280 					    fport->portid);
2281 					TAILQ_INSERT_TAIL(&sc->sc_ports_found,
2282 					    fport, update);
2283 					break;
2284 				case QLE_PORT_DISP_DUP:
2285 					free(fport, M_DEVBUF, sizeof *port);
2286 					break;
2287 				case QLE_PORT_DISP_SAME:
2288 					DPRINTF(QLE_D_PORT, "%s: existing port "
2289 					    " %06x\n", DEVNAME(sc),
2290 					    fport->portid);
2291 					TAILQ_REMOVE(&sc->sc_ports_gone, port,
2292 					    update);
2293 					free(fport, M_DEVBUF, sizeof *port);
2294 					break;
2295 				}
2296 				mtx_leave(&sc->sc_port_mtx);
2297 			}
2298 			if (lastport == 0xffffffff) {
2299 				DPRINTF(QLE_D_PORT, "%s: finished\n",
2300 				    DEVNAME(sc));
2301 				qle_update_done(sc,
2302 				    QLE_UPDATE_TASK_SCANNING_FABRIC);
2303 				qle_update_start(sc,
2304 				    QLE_UPDATE_TASK_FABRIC_LOGIN);
2305 			}
2306 			continue;
2307 		}
2308 
2309 		if (sc->sc_update_tasks & QLE_UPDATE_TASK_FABRIC_LOGIN) {
2310 			mtx_enter(&sc->sc_port_mtx);
2311 			port = TAILQ_FIRST(&sc->sc_ports_found);
2312 			if (port != NULL) {
2313 				TAILQ_REMOVE(&sc->sc_ports_found, port, update);
2314 			}
2315 			mtx_leave(&sc->sc_port_mtx);
2316 
2317 			if (port != NULL) {
2318 				DPRINTF(QLE_D_PORT, "%s: found port %06x\n",
2319 				    DEVNAME(sc), port->portid);
2320 				if (qle_fabric_plogi(sc, port) == 0) {
2321 					qle_add_fabric_port(sc, port);
2322 				} else {
2323 					DPRINTF(QLE_D_PORT, "%s: plogi %06x "
2324 					    "failed\n", DEVNAME(sc),
2325 					    port->portid);
2326 					free(port, M_DEVBUF, sizeof *port);
2327 				}
2328 			} else {
2329 				DPRINTF(QLE_D_PORT, "%s: done with logins\n",
2330 				    DEVNAME(sc));
2331 				qle_update_done(sc,
2332 				    QLE_UPDATE_TASK_FABRIC_LOGIN);
2333 				qle_update_start(sc,
2334 				    QLE_UPDATE_TASK_ATTACH_TARGET |
2335 				    QLE_UPDATE_TASK_DETACH_TARGET);
2336 			}
2337 			continue;
2338 		}
2339 
2340 		if (sc->sc_update_tasks & QLE_UPDATE_TASK_FABRIC_RELOGIN) {
2341 			TAILQ_FOREACH(port, &sc->sc_ports, ports) {
2342 				if (port->flags & QLE_PORT_FLAG_NEEDS_LOGIN) {
2343 					qle_fabric_plogi(sc, port);
2344 					break;
2345 				}
2346 			}
2347 
2348 			if (port == NULL)
2349 				qle_update_done(sc,
2350 				    QLE_UPDATE_TASK_FABRIC_RELOGIN);
2351 			continue;
2352 		}
2353 
2354 		if (sc->sc_update_tasks & QLE_UPDATE_TASK_DETACH_TARGET) {
2355 			mtx_enter(&sc->sc_port_mtx);
2356 			port = TAILQ_FIRST(&sc->sc_ports_gone);
2357 			if (port != NULL) {
2358 				sc->sc_targets[port->loopid] = NULL;
2359 				TAILQ_REMOVE(&sc->sc_ports_gone, port, update);
2360 				TAILQ_REMOVE(&sc->sc_ports, port, ports);
2361 			}
2362 			mtx_leave(&sc->sc_port_mtx);
2363 
2364 			if (port != NULL) {
2365 				DPRINTF(QLE_D_PORT, "%s: detaching port %06x\n",
2366 				    DEVNAME(sc), port->portid);
2367 				if (sc->sc_scsibus != NULL)
2368 					scsi_detach_target(sc->sc_scsibus,
2369 					    port->loopid, DETACH_FORCE |
2370 					    DETACH_QUIET);
2371 
2372 				if (port->location & QLE_LOCATION_FABRIC)
2373 					qle_fabric_plogo(sc, port);
2374 
2375 				free(port, M_DEVBUF, sizeof *port);
2376 			} else {
2377 				DPRINTF(QLE_D_PORT, "%s: nothing to detach\n",
2378 				    DEVNAME(sc));
2379 				qle_update_done(sc,
2380 				    QLE_UPDATE_TASK_DETACH_TARGET);
2381 			}
2382 			continue;
2383 		}
2384 
2385 		if (sc->sc_update_tasks & QLE_UPDATE_TASK_ATTACH_TARGET) {
2386 			mtx_enter(&sc->sc_port_mtx);
2387 			port = TAILQ_FIRST(&sc->sc_ports_new);
2388 			if (port != NULL) {
2389 				TAILQ_REMOVE(&sc->sc_ports_new, port, update);
2390 				TAILQ_INSERT_TAIL(&sc->sc_ports, port, ports);
2391 			}
2392 			mtx_leave(&sc->sc_port_mtx);
2393 
2394 			if (port != NULL) {
2395 				if (sc->sc_scsibus != NULL)
2396 					scsi_probe_target(sc->sc_scsibus,
2397 					    port->loopid);
2398 			} else {
2399 				qle_update_done(sc,
2400 				    QLE_UPDATE_TASK_ATTACH_TARGET);
2401 			}
2402 			continue;
2403 		}
2404 
2405 	}
2406 
2407 	DPRINTF(QLE_D_PORT, "%s: done updating\n", DEVNAME(sc));
2408 }
2409 
2410 int
2411 qle_async(struct qle_softc *sc, u_int16_t info)
2412 {
2413 	switch (info) {
2414 	case QLE_ASYNC_SYSTEM_ERROR:
2415 		qle_update_start(sc, QLE_UPDATE_TASK_SOFTRESET);
2416 		break;
2417 
2418 	case QLE_ASYNC_REQ_XFER_ERROR:
2419 		qle_update_start(sc, QLE_UPDATE_TASK_SOFTRESET);
2420 		break;
2421 
2422 	case QLE_ASYNC_RSP_XFER_ERROR:
2423 		qle_update_start(sc, QLE_UPDATE_TASK_SOFTRESET);
2424 		break;
2425 
2426 	case QLE_ASYNC_LIP_OCCURRED:
2427 		DPRINTF(QLE_D_INTR, "%s: lip occurred\n", DEVNAME(sc));
2428 		break;
2429 
2430 	case QLE_ASYNC_LOOP_UP:
2431 		DPRINTF(QLE_D_PORT, "%s: loop up\n", DEVNAME(sc));
2432 		sc->sc_loop_up = 1;
2433 		sc->sc_marker_required = 1;
2434 		qle_update_defer(sc, QLE_UPDATE_TASK_UPDATE_TOPO |
2435 		    QLE_UPDATE_TASK_GET_PORT_LIST);
2436 		break;
2437 
2438 	case QLE_ASYNC_LOOP_DOWN:
2439 		DPRINTF(QLE_D_PORT, "%s: loop down\n", DEVNAME(sc));
2440 		sc->sc_loop_up = 0;
2441 		qle_update_cancel(sc);
2442 		qle_update_start(sc, QLE_UPDATE_TASK_CLEAR_ALL);
2443 		break;
2444 
2445 	case QLE_ASYNC_LIP_RESET:
2446 		DPRINTF(QLE_D_PORT, "%s: lip reset\n", DEVNAME(sc));
2447 		sc->sc_marker_required = 1;
2448 		qle_update_defer(sc, QLE_UPDATE_TASK_FABRIC_RELOGIN);
2449 		break;
2450 
2451 	case QLE_ASYNC_PORT_DB_CHANGE:
2452 		DPRINTF(QLE_D_PORT, "%s: port db changed %x\n", DEVNAME(sc),
2453 		    qle_read_mbox(sc, 1));
2454 		qle_update_start(sc, QLE_UPDATE_TASK_GET_PORT_LIST);
2455 		break;
2456 
2457 	case QLE_ASYNC_CHANGE_NOTIFY:
2458 		DPRINTF(QLE_D_PORT, "%s: name server change (%02x:%02x)\n",
2459 		    DEVNAME(sc), qle_read_mbox(sc, 1), qle_read_mbox(sc, 2));
2460 		qle_update_start(sc, QLE_UPDATE_TASK_GET_PORT_LIST);
2461 		break;
2462 
2463 	case QLE_ASYNC_LIP_F8:
2464 		DPRINTF(QLE_D_INTR, "%s: lip f8\n", DEVNAME(sc));
2465 		break;
2466 
2467 	case QLE_ASYNC_LOOP_INIT_ERROR:
2468 		DPRINTF(QLE_D_PORT, "%s: loop initialization error: %x\n",
2469 		    DEVNAME(sc), qle_read_mbox(sc, 1));
2470 		break;
2471 
2472 	case QLE_ASYNC_POINT_TO_POINT:
2473 		DPRINTF(QLE_D_PORT, "%s: connected in point-to-point mode\n",
2474 		    DEVNAME(sc));
2475 		break;
2476 
2477 	case QLE_ASYNC_ZIO_RESP_UPDATE:
2478 		/* shouldn't happen, we don't do zio */
2479 		break;
2480 
2481 	default:
2482 		DPRINTF(QLE_D_INTR, "%s: unknown async %x\n", DEVNAME(sc), info);
2483 		break;
2484 	}
2485 	return (1);
2486 }
2487 
2488 void
2489 qle_dump_stuff(struct qle_softc *sc, void *buf, int n)
2490 {
2491 #ifdef QLE_DEBUG
2492 	u_int8_t *d = buf;
2493 	int l;
2494 
2495 	if ((qledebug & QLE_D_IOCB) == 0)
2496 		return;
2497 
2498 	printf("%s: stuff\n", DEVNAME(sc));
2499 	for (l = 0; l < n; l++) {
2500 		printf(" %2.2x", d[l]);
2501 		if (l % 16 == 15)
2502 			printf("\n");
2503 	}
2504 	if (n % 16 != 0)
2505 		printf("\n");
2506 #endif
2507 }
2508 
2509 void
2510 qle_dump_iocb(struct qle_softc *sc, void *buf)
2511 {
2512 #ifdef QLE_DEBUG
2513 	u_int8_t *iocb = buf;
2514 	int l;
2515 	int b;
2516 
2517 	if ((qledebug & QLE_D_IOCB) == 0)
2518 		return;
2519 
2520 	printf("%s: iocb:\n", DEVNAME(sc));
2521 	for (l = 0; l < 4; l++) {
2522 		for (b = 0; b < 16; b++) {
2523 			printf(" %2.2x", iocb[(l*16)+b]);
2524 		}
2525 		printf("\n");
2526 	}
2527 #endif
2528 }
2529 
2530 void
2531 qle_dump_iocb_segs(struct qle_softc *sc, void *segs, int n)
2532 {
2533 #ifdef QLE_DEBUG
2534 	u_int8_t *buf = segs;
2535 	int s, b;
2536 
2537 	if ((qledebug & QLE_D_IOCB) == 0)
2538 		return;
2539 
2540 	printf("%s: iocb segs:\n", DEVNAME(sc));
2541 	for (s = 0; s < n; s++) {
2542 		for (b = 0; b < sizeof(struct qle_iocb_seg); b++) {
2543 			printf(" %2.2x", buf[(s*(sizeof(struct qle_iocb_seg)))
2544 			    + b]);
2545 		}
2546 		printf("\n");
2547 	}
2548 #endif
2549 }
2550 
2551 void
2552 qle_put_marker(struct qle_softc *sc, void *buf)
2553 {
2554 	struct qle_iocb_marker *marker = buf;
2555 
2556 	marker->entry_type = QLE_IOCB_MARKER;
2557 	marker->entry_count = 1;
2558 	marker->seqno = 0;
2559 	marker->flags = 0;
2560 
2561 	/* could be more specific here; isp(4) isn't */
2562 	marker->target = 0;
2563 	marker->modifier = QLE_IOCB_MARKER_SYNC_ALL;
2564 }
2565 
2566 void
2567 qle_sge(struct qle_iocb_seg *seg, u_int64_t addr, u_int32_t len)
2568 {
2569 	htolem32(&seg->seg_addr_lo, addr);
2570 	htolem32(&seg->seg_addr_hi, addr >> 32);
2571 	htolem32(&seg->seg_len, len);
2572 }
2573 
2574 void
2575 qle_put_cmd(struct qle_softc *sc, void *buf, struct scsi_xfer *xs,
2576     struct qle_ccb *ccb, u_int32_t target_port)
2577 {
2578 	bus_dmamap_t dmap = ccb->ccb_dmamap;
2579 	struct qle_iocb_req6 *req = buf;
2580 	struct qle_fcp_cmnd *cmnd;
2581 	u_int64_t fcp_cmnd_offset;
2582 	u_int32_t fcp_dl;
2583 	int seg;
2584 	int target = xs->sc_link->target;
2585 	int lun = xs->sc_link->lun;
2586 	u_int16_t flags;
2587 
2588 	memset(req, 0, sizeof(*req));
2589 	req->entry_type = QLE_IOCB_CMD_TYPE_6;
2590 	req->entry_count = 1;
2591 
2592 	req->req_handle = ccb->ccb_id;
2593 	htolem16(&req->req_nport_handle, target);
2594 
2595 	/*
2596 	 * timeout is in seconds.  make sure it's at least 1 if a timeout
2597 	 * was specified in xs
2598 	 */
2599 	if (xs->timeout != 0)
2600 		htolem16(&req->req_timeout, MAX(1, xs->timeout/1000));
2601 
2602 	if (xs->datalen > 0) {
2603 		flags = (xs->flags & SCSI_DATA_IN) ?
2604 		    QLE_IOCB_CTRL_FLAG_READ : QLE_IOCB_CTRL_FLAG_WRITE;
2605 		if (dmap->dm_nsegs == 1) {
2606 			qle_sge(&req->req_data_seg, dmap->dm_segs[0].ds_addr,
2607 			    dmap->dm_segs[0].ds_len);
2608 		} else {
2609 			flags |= QLE_IOCB_CTRL_FLAG_EXT_SEG;
2610 			for (seg = 0; seg < dmap->dm_nsegs; seg++) {
2611 				qle_sge(&ccb->ccb_segs[seg],
2612 				    dmap->dm_segs[seg].ds_addr,
2613 				    dmap->dm_segs[seg].ds_len);
2614 			}
2615 			qle_sge(&ccb->ccb_segs[seg++], 0, 0);
2616 
2617 			bus_dmamap_sync(sc->sc_dmat,
2618 			    QLE_DMA_MAP(sc->sc_segments), ccb->ccb_seg_offset,
2619 			    seg * sizeof(*ccb->ccb_segs),
2620 			    BUS_DMASYNC_PREWRITE);
2621 
2622 			qle_sge(&req->req_data_seg,
2623 			    QLE_DMA_DVA(sc->sc_segments) + ccb->ccb_seg_offset,
2624 			    seg * sizeof(struct qle_iocb_seg));
2625 		}
2626 
2627 		htolem16(&req->req_data_seg_count, dmap->dm_nsegs);
2628 		htolem32(&req->req_data_len, xs->datalen);
2629 		htolem16(&req->req_ctrl_flags, flags);
2630 	}
2631 
2632 	htobem16(&req->req_fcp_lun[0], lun);
2633 	htobem16(&req->req_fcp_lun[1], lun >> 16);
2634 	htolem32(&req->req_target_id, target_port & 0xffffff);
2635 
2636 	fcp_cmnd_offset = ccb->ccb_id * sizeof(*cmnd);
2637 	/* set up FCP_CMND */
2638 	cmnd = (struct qle_fcp_cmnd *)QLE_DMA_KVA(sc->sc_fcp_cmnds) +
2639 	    ccb->ccb_id;
2640 
2641 	memset(cmnd, 0, sizeof(*cmnd));
2642 	htobem16(&cmnd->fcp_lun[0], lun);
2643 	htobem16(&cmnd->fcp_lun[1], lun >> 16);
2644 	/* cmnd->fcp_task_attr = TSK_SIMPLE; */
2645 	/* cmnd->fcp_task_mgmt = 0; */
2646 	memcpy(cmnd->fcp_cdb, xs->cmd, xs->cmdlen);
2647 
2648 	/* FCP_DL goes after the cdb */
2649 	fcp_dl = htobe32(xs->datalen);
2650 	if (xs->cmdlen > 16) {
2651 		htolem16(&req->req_fcp_cmnd_len, 12 + xs->cmdlen + 4);
2652 		cmnd->fcp_add_cdb_len = xs->cmdlen - 16;
2653 		memcpy(cmnd->fcp_cdb + xs->cmdlen, &fcp_dl, sizeof(fcp_dl));
2654 	} else {
2655 		htolem16(&req->req_fcp_cmnd_len, 12 + 16 + 4);
2656 		cmnd->fcp_add_cdb_len = 0;
2657 		memcpy(cmnd->fcp_cdb + 16, &fcp_dl, sizeof(fcp_dl));
2658 	}
2659 	if (xs->datalen > 0)
2660 		cmnd->fcp_add_cdb_len |= (xs->flags & SCSI_DATA_IN) ? 2 : 1;
2661 
2662 	bus_dmamap_sync(sc->sc_dmat,
2663 	    QLE_DMA_MAP(sc->sc_fcp_cmnds), fcp_cmnd_offset,
2664 	    sizeof(*cmnd), BUS_DMASYNC_PREWRITE);
2665 
2666 	/* link req to cmnd */
2667 	fcp_cmnd_offset += QLE_DMA_DVA(sc->sc_fcp_cmnds);
2668 	htolem32(&req->req_fcp_cmnd_addr_lo, fcp_cmnd_offset);
2669 	htolem32(&req->req_fcp_cmnd_addr_hi, fcp_cmnd_offset >> 32);
2670 }
2671 
2672 int
2673 qle_load_fwchunk(struct qle_softc *sc, struct qle_dmamem *mem,
2674     const u_int32_t *src)
2675 {
2676 	u_int32_t dest, done, total;
2677 	int i;
2678 
2679 	dest = src[2];
2680 	done = 0;
2681 	total = src[3];
2682 
2683 	while (done < total) {
2684 		u_int32_t *copy;
2685 		u_int32_t words;
2686 
2687 		/* limit transfer size otherwise it just doesn't work */
2688 		words = MIN(total - done, 1 << 10);
2689 		copy = QLE_DMA_KVA(mem);
2690 		for (i = 0; i < words; i++) {
2691 			htolem32(&copy[i], src[done++]);
2692 		}
2693 		bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(mem), 0, words * 4,
2694 		    BUS_DMASYNC_PREWRITE);
2695 
2696 		sc->sc_mbox[0] = QLE_MBOX_LOAD_RISC_RAM;
2697 		sc->sc_mbox[1] = dest;
2698 		sc->sc_mbox[4] = words >> 16;
2699 		sc->sc_mbox[5] = words & 0xffff;
2700 		sc->sc_mbox[8] = dest >> 16;
2701 		qle_mbox_putaddr(sc->sc_mbox, mem);
2702 		if (qle_mbox(sc, 0x01ff)) {
2703 			printf("firmware load failed\n");
2704 			return (1);
2705 		}
2706 		bus_dmamap_sync(sc->sc_dmat, QLE_DMA_MAP(mem), 0, words * 4,
2707 		    BUS_DMASYNC_POSTWRITE);
2708 
2709 		dest += words;
2710 	}
2711 
2712 	return (qle_verify_firmware(sc, src[2]));
2713 }
2714 
2715 int
2716 qle_load_firmware_chunks(struct qle_softc *sc, const u_int32_t *fw)
2717 {
2718 	struct qle_dmamem *mem;
2719 	int res = 0;
2720 
2721 	mem = qle_dmamem_alloc(sc, 65536);
2722 	for (;;) {
2723 		if (qle_load_fwchunk(sc, mem, fw)) {
2724 			res = 1;
2725 			break;
2726 		}
2727 		if (fw[1] == 0)
2728 			break;
2729 		fw += fw[3];
2730 	}
2731 
2732 	qle_dmamem_free(sc, mem);
2733 	return (res);
2734 }
2735 
2736 u_int32_t
2737 qle_read_ram_word(struct qle_softc *sc, u_int32_t addr)
2738 {
2739 	sc->sc_mbox[0] = QLE_MBOX_READ_RISC_RAM;
2740 	sc->sc_mbox[1] = addr & 0xffff;
2741 	sc->sc_mbox[8] = addr >> 16;
2742 	if (qle_mbox(sc, 0x0103)) {
2743 		return (0);
2744 	}
2745 	return ((sc->sc_mbox[3] << 16) | sc->sc_mbox[2]);
2746 }
2747 
2748 int
2749 qle_verify_firmware(struct qle_softc *sc, u_int32_t addr)
2750 {
2751 	/*
2752 	 * QLE_MBOX_VERIFY_CSUM requires at least the firmware header
2753 	 * to be correct, otherwise it wanders all over ISP memory and
2754 	 * gets lost.  Check that chunk address (addr+2) is right and
2755 	 * size (addr+3) is plausible first.
2756 	 */
2757 	if ((qle_read_ram_word(sc, addr+2) != addr) ||
2758 	    (qle_read_ram_word(sc, addr+3) > 0xffff)) {
2759 		return (1);
2760 	}
2761 
2762 	sc->sc_mbox[0] = QLE_MBOX_VERIFY_CSUM;
2763 	sc->sc_mbox[1] = addr >> 16;
2764 	sc->sc_mbox[2] = addr;
2765 	if (qle_mbox(sc, 0x0007)) {
2766 		return (1);
2767 	}
2768 	return (0);
2769 }
2770 
2771 int
2772 qle_read_nvram(struct qle_softc *sc)
2773 {
2774 	u_int32_t data[sizeof(sc->sc_nvram) / 4];
2775 	u_int32_t csum, tmp, v;
2776 	int i, base, l;
2777 
2778 	switch (sc->sc_isp_gen) {
2779 	case QLE_GEN_ISP24XX:
2780 		base = 0x7ffe0080;
2781 		break;
2782 	case QLE_GEN_ISP25XX:
2783 		base = 0x7ff48080;
2784 		break;
2785 	}
2786 	base += sc->sc_port * 0x100;
2787 
2788 	csum = 0;
2789 	for (i = 0; i < nitems(data); i++) {
2790 		data[i] = 0xffffffff;
2791 		qle_write(sc, QLE_FLASH_NVRAM_ADDR, base + i);
2792 		for (l = 0; l < 5000; l++) {
2793 			delay(10);
2794 			tmp = qle_read(sc, QLE_FLASH_NVRAM_ADDR);
2795 			if (tmp & (1U << 31)) {
2796 				v = qle_read(sc, QLE_FLASH_NVRAM_DATA);
2797 				csum += v;
2798 				data[i] = letoh32(v);
2799 				break;
2800 			}
2801 		}
2802 	}
2803 
2804 	bcopy(data, &sc->sc_nvram, sizeof(sc->sc_nvram));
2805 	/* id field should be 'ISP' */
2806 	if (sc->sc_nvram.id[0] != 'I' || sc->sc_nvram.id[1] != 'S' ||
2807 	    sc->sc_nvram.id[2] != 'P' || csum != 0) {
2808 		printf("%s: nvram corrupt\n", DEVNAME(sc));
2809 		return (1);
2810 	}
2811 	return (0);
2812 }
2813 
2814 struct qle_dmamem *
2815 qle_dmamem_alloc(struct qle_softc *sc, size_t size)
2816 {
2817 	struct qle_dmamem *m;
2818 	int nsegs;
2819 
2820 	m = malloc(sizeof(*m), M_DEVBUF, M_NOWAIT | M_ZERO);
2821 	if (m == NULL)
2822 		return (NULL);
2823 
2824 	m->qdm_size = size;
2825 
2826 	if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
2827 	    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &m->qdm_map) != 0)
2828 		goto qdmfree;
2829 
2830 	if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &m->qdm_seg, 1,
2831 	    &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO) != 0)
2832 		goto destroy;
2833 
2834 	if (bus_dmamem_map(sc->sc_dmat, &m->qdm_seg, nsegs, size, &m->qdm_kva,
2835 	    BUS_DMA_NOWAIT) != 0)
2836 		goto free;
2837 
2838 	if (bus_dmamap_load(sc->sc_dmat, m->qdm_map, m->qdm_kva, size, NULL,
2839 	    BUS_DMA_NOWAIT) != 0)
2840 		goto unmap;
2841 
2842 	return (m);
2843 
2844 unmap:
2845 	bus_dmamem_unmap(sc->sc_dmat, m->qdm_kva, m->qdm_size);
2846 free:
2847 	bus_dmamem_free(sc->sc_dmat, &m->qdm_seg, 1);
2848 destroy:
2849 	bus_dmamap_destroy(sc->sc_dmat, m->qdm_map);
2850 qdmfree:
2851 	free(m, M_DEVBUF, sizeof *m);
2852 
2853 	return (NULL);
2854 }
2855 
2856 void
2857 qle_dmamem_free(struct qle_softc *sc, struct qle_dmamem *m)
2858 {
2859 	bus_dmamap_unload(sc->sc_dmat, m->qdm_map);
2860 	bus_dmamem_unmap(sc->sc_dmat, m->qdm_kva, m->qdm_size);
2861 	bus_dmamem_free(sc->sc_dmat, &m->qdm_seg, 1);
2862 	bus_dmamap_destroy(sc->sc_dmat, m->qdm_map);
2863 	free(m, M_DEVBUF, sizeof *m);
2864 }
2865 
2866 int
2867 qle_alloc_ccbs(struct qle_softc *sc)
2868 {
2869 	struct qle_ccb		*ccb;
2870 	u_int8_t		*cmd;
2871 	int			i;
2872 
2873 	SIMPLEQ_INIT(&sc->sc_ccb_free);
2874 	mtx_init(&sc->sc_ccb_mtx, IPL_BIO);
2875 	mtx_init(&sc->sc_queue_mtx, IPL_BIO);
2876 	mtx_init(&sc->sc_port_mtx, IPL_BIO);
2877 	mtx_init(&sc->sc_mbox_mtx, IPL_BIO);
2878 
2879 	sc->sc_ccbs = mallocarray(sc->sc_maxcmds, sizeof(struct qle_ccb),
2880 	    M_DEVBUF, M_WAITOK | M_CANFAIL | M_ZERO);
2881 	if (sc->sc_ccbs == NULL) {
2882 		printf("%s: unable to allocate ccbs\n", DEVNAME(sc));
2883 		return (1);
2884 	}
2885 
2886 	sc->sc_requests = qle_dmamem_alloc(sc, sc->sc_maxcmds *
2887 	    QLE_QUEUE_ENTRY_SIZE);
2888 	if (sc->sc_requests == NULL) {
2889 		printf("%s: unable to allocate ccb dmamem\n", DEVNAME(sc));
2890 		goto free_ccbs;
2891 	}
2892 	sc->sc_responses = qle_dmamem_alloc(sc, sc->sc_maxcmds *
2893 	    QLE_QUEUE_ENTRY_SIZE);
2894 	if (sc->sc_responses == NULL) {
2895 		printf("%s: unable to allocate rcb dmamem\n", DEVNAME(sc));
2896 		goto free_req;
2897 	}
2898 	sc->sc_pri_requests = qle_dmamem_alloc(sc, 8 * QLE_QUEUE_ENTRY_SIZE);
2899 	if (sc->sc_pri_requests == NULL) {
2900 		printf("%s: unable to allocate pri ccb dmamem\n", DEVNAME(sc));
2901 		goto free_res;
2902 	}
2903 	sc->sc_segments = qle_dmamem_alloc(sc, sc->sc_maxcmds * QLE_MAX_SEGS *
2904 	    sizeof(struct qle_iocb_seg));
2905 	if (sc->sc_segments == NULL) {
2906 		printf("%s: unable to allocate iocb segments\n", DEVNAME(sc));
2907 		goto free_pri;
2908 	}
2909 
2910 	sc->sc_fcp_cmnds = qle_dmamem_alloc(sc, sc->sc_maxcmds *
2911 	    sizeof(struct qle_fcp_cmnd));
2912 	if (sc->sc_fcp_cmnds == NULL) {
2913 		printf("%s: unable to allocate FCP_CMNDs\n", DEVNAME(sc));
2914 		goto free_seg;
2915 	}
2916 
2917 	cmd = QLE_DMA_KVA(sc->sc_requests);
2918 	memset(cmd, 0, QLE_QUEUE_ENTRY_SIZE * sc->sc_maxcmds);
2919 	for (i = 0; i < sc->sc_maxcmds; i++) {
2920 		ccb = &sc->sc_ccbs[i];
2921 
2922 		if (bus_dmamap_create(sc->sc_dmat, MAXPHYS,
2923 		    QLE_MAX_SEGS-1, MAXPHYS, 0,
2924 		    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
2925 		    &ccb->ccb_dmamap) != 0) {
2926 			printf("%s: unable to create dma map\n", DEVNAME(sc));
2927 			goto free_maps;
2928 		}
2929 
2930 		ccb->ccb_sc = sc;
2931 		ccb->ccb_id = i;
2932 
2933 		ccb->ccb_seg_offset = i * QLE_MAX_SEGS *
2934 		    sizeof(struct qle_iocb_seg);
2935 		ccb->ccb_segs = QLE_DMA_KVA(sc->sc_segments) +
2936 		    ccb->ccb_seg_offset;
2937 
2938 		qle_put_ccb(sc, ccb);
2939 	}
2940 
2941 	scsi_iopool_init(&sc->sc_iopool, sc, qle_get_ccb, qle_put_ccb);
2942 	return (0);
2943 
2944 free_maps:
2945 	while ((ccb = qle_get_ccb(sc)) != NULL)
2946 		bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
2947 
2948 	qle_dmamem_free(sc, sc->sc_fcp_cmnds);
2949 free_seg:
2950 	qle_dmamem_free(sc, sc->sc_segments);
2951 free_pri:
2952 	qle_dmamem_free(sc, sc->sc_pri_requests);
2953 free_res:
2954 	qle_dmamem_free(sc, sc->sc_responses);
2955 free_req:
2956 	qle_dmamem_free(sc, sc->sc_requests);
2957 free_ccbs:
2958 	free(sc->sc_ccbs, M_DEVBUF, 0);
2959 
2960 	return (1);
2961 }
2962 
2963 void
2964 qle_free_ccbs(struct qle_softc *sc)
2965 {
2966 	struct qle_ccb		*ccb;
2967 
2968 	scsi_iopool_destroy(&sc->sc_iopool);
2969 	while ((ccb = qle_get_ccb(sc)) != NULL)
2970 		bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
2971 	qle_dmamem_free(sc, sc->sc_segments);
2972 	qle_dmamem_free(sc, sc->sc_responses);
2973 	qle_dmamem_free(sc, sc->sc_requests);
2974 	free(sc->sc_ccbs, M_DEVBUF, 0);
2975 }
2976 
2977 void *
2978 qle_get_ccb(void *xsc)
2979 {
2980 	struct qle_softc 	*sc = xsc;
2981 	struct qle_ccb		*ccb;
2982 
2983 	mtx_enter(&sc->sc_ccb_mtx);
2984 	ccb = SIMPLEQ_FIRST(&sc->sc_ccb_free);
2985 	if (ccb != NULL) {
2986 		SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_free, ccb_link);
2987 	}
2988 	mtx_leave(&sc->sc_ccb_mtx);
2989 	return (ccb);
2990 }
2991 
2992 void
2993 qle_put_ccb(void *xsc, void *io)
2994 {
2995 	struct qle_softc	*sc = xsc;
2996 	struct qle_ccb		*ccb = io;
2997 
2998 	ccb->ccb_xs = NULL;
2999 	mtx_enter(&sc->sc_ccb_mtx);
3000 	SIMPLEQ_INSERT_HEAD(&sc->sc_ccb_free, ccb, ccb_link);
3001 	mtx_leave(&sc->sc_ccb_mtx);
3002 }
3003