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