xref: /openbsd-src/sys/dev/ic/mpi.c (revision 6608091eb88af1004a9ce99e5e01d3f4513daccc)
1 /*	$OpenBSD: mpi.c,v 1.63 2006/07/15 04:09:57 dlg Exp $ */
2 
3 /*
4  * Copyright (c) 2005, 2006 David Gwynne <dlg@openbsd.org>
5  * Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/param.h>
21 #include <sys/systm.h>
22 #include <sys/buf.h>
23 #include <sys/device.h>
24 #include <sys/proc.h>
25 #include <sys/malloc.h>
26 #include <sys/kernel.h>
27 
28 #include <machine/bus.h>
29 
30 #include <scsi/scsi_all.h>
31 #include <scsi/scsiconf.h>
32 
33 #include <dev/ic/mpireg.h>
34 #include <dev/ic/mpivar.h>
35 
36 #ifdef MPI_DEBUG
37 uint32_t	mpi_debug = 0
38 /*		    | MPI_D_CMD */
39 /*		    | MPI_D_INTR */
40 /*		    | MPI_D_MISC */
41 /*		    | MPI_D_DMA */
42 /*		    | MPI_D_IOCTL */
43 /*		    | MPI_D_RW */
44 /*		    | MPI_D_MEM */
45 /*		    | MPI_D_CCB */
46 /*		    | MPI_D_PPR */
47 /*		    | MPI_D_RAID */
48 		;
49 #endif
50 
51 struct cfdriver mpi_cd = {
52 	NULL, "mpi", DV_DULL
53 };
54 
55 int			mpi_scsi_cmd(struct scsi_xfer *);
56 void			mpi_scsi_cmd_done(struct mpi_ccb *);
57 void			mpi_minphys(struct buf *bp);
58 int			mpi_scsi_ioctl(struct scsi_link *, u_long, caddr_t,
59 			    int, struct proc *);
60 
61 struct scsi_adapter mpi_switch = {
62 	mpi_scsi_cmd, mpi_minphys, NULL, NULL, mpi_scsi_ioctl
63 };
64 
65 struct scsi_device mpi_dev = {
66 	NULL, NULL, NULL, NULL
67 };
68 
69 struct mpi_dmamem	*mpi_dmamem_alloc(struct mpi_softc *, size_t);
70 void			mpi_dmamem_free(struct mpi_softc *,
71 			    struct mpi_dmamem *);
72 int			mpi_alloc_ccbs(struct mpi_softc *);
73 struct mpi_ccb		*mpi_get_ccb(struct mpi_softc *);
74 void			mpi_put_ccb(struct mpi_softc *, struct mpi_ccb *);
75 int			mpi_alloc_replies(struct mpi_softc *);
76 void			mpi_push_replies(struct mpi_softc *);
77 
78 void			mpi_start(struct mpi_softc *, struct mpi_ccb *);
79 int			mpi_complete(struct mpi_softc *, struct mpi_ccb *, int);
80 int			mpi_poll(struct mpi_softc *, struct mpi_ccb *, int);
81 
82 void			mpi_fc_print(struct mpi_softc *);
83 void			mpi_squash_ppr(struct mpi_softc *);
84 void			mpi_run_ppr(struct mpi_softc *);
85 int			mpi_ppr(struct mpi_softc *, struct scsi_link *,
86 			    struct mpi_cfg_raid_physdisk *, int, int, int);
87 int			mpi_inq(struct mpi_softc *, u_int16_t, int);
88 
89 void			mpi_timeout_xs(void *);
90 int			mpi_load_xs(struct mpi_ccb *);
91 
92 u_int32_t		mpi_read(struct mpi_softc *, bus_size_t);
93 void			mpi_write(struct mpi_softc *, bus_size_t, u_int32_t);
94 int			mpi_wait_eq(struct mpi_softc *, bus_size_t, u_int32_t,
95 			    u_int32_t);
96 int			mpi_wait_ne(struct mpi_softc *, bus_size_t, u_int32_t,
97 			    u_int32_t);
98 
99 int			mpi_init(struct mpi_softc *);
100 int			mpi_reset_soft(struct mpi_softc *);
101 int			mpi_reset_hard(struct mpi_softc *);
102 
103 int			mpi_handshake_send(struct mpi_softc *, void *, size_t);
104 int			mpi_handshake_recv_dword(struct mpi_softc *,
105 			    u_int32_t *);
106 int			mpi_handshake_recv(struct mpi_softc *, void *, size_t);
107 
108 void			mpi_empty_done(struct mpi_ccb *);
109 
110 int			mpi_iocinit(struct mpi_softc *);
111 int			mpi_iocfacts(struct mpi_softc *);
112 int			mpi_portfacts(struct mpi_softc *);
113 int			mpi_eventnotify(struct mpi_softc *);
114 void			mpi_eventnotify_done(struct mpi_ccb *);
115 int			mpi_portenable(struct mpi_softc *);
116 void			mpi_get_raid(struct mpi_softc *);
117 int			mpi_fwupload(struct mpi_softc *);
118 
119 int			mpi_cfg_header(struct mpi_softc *, u_int8_t, u_int8_t,
120 			    u_int32_t, struct mpi_cfg_hdr *);
121 int			mpi_cfg_page(struct mpi_softc *, u_int32_t,
122 			    struct mpi_cfg_hdr *, int, void *, size_t);
123 
124 #define DEVNAME(s)		((s)->sc_dev.dv_xname)
125 
126 #define	dwordsof(s)		(sizeof(s) / sizeof(u_int32_t))
127 #define	sizeofa(s)		(sizeof(s) / sizeof((s)[0]))
128 
129 #define mpi_read_db(s)		mpi_read((s), MPI_DOORBELL)
130 #define mpi_write_db(s, v)	mpi_write((s), MPI_DOORBELL, (v))
131 #define mpi_read_intr(s)	mpi_read((s), MPI_INTR_STATUS)
132 #define mpi_write_intr(s, v)	mpi_write((s), MPI_INTR_STATUS, (v))
133 #define mpi_pop_reply(s)	mpi_read((s), MPI_REPLY_QUEUE)
134 #define mpi_push_reply(s, v)	mpi_write((s), MPI_REPLY_QUEUE, (v))
135 
136 #define mpi_wait_db_int(s)	mpi_wait_ne((s), MPI_INTR_STATUS, \
137 				    MPI_INTR_STATUS_DOORBELL, 0)
138 #define mpi_wait_db_ack(s)	mpi_wait_eq((s), MPI_INTR_STATUS, \
139 				    MPI_INTR_STATUS_IOCDOORBELL, 0)
140 
141 int
142 mpi_attach(struct mpi_softc *sc)
143 {
144 	struct device			*dev;
145 	struct mpi_ccb			*ccb;
146 
147 	printf("\n");
148 
149 	/* disable interrupts */
150 	mpi_write(sc, MPI_INTR_MASK,
151 	    MPI_INTR_MASK_REPLY | MPI_INTR_MASK_DOORBELL);
152 
153 	if (mpi_init(sc) != 0) {
154 		printf("%s: unable to initialise\n", DEVNAME(sc));
155 		return (1);
156 	}
157 
158 	if (mpi_iocfacts(sc) != 0) {
159 		printf("%s: unable to get iocfacts\n", DEVNAME(sc));
160 		return (1);
161 	}
162 
163 	if (mpi_alloc_ccbs(sc) != 0) {
164 		/* error already printed */
165 		return (1);
166 	}
167 
168 	if (mpi_alloc_replies(sc) != 0) {
169 		printf("%s: unable to allocate reply space\n", DEVNAME(sc));
170 		goto free_ccbs;
171 	}
172 
173 	if (mpi_iocinit(sc) != 0) {
174 		printf("%s: unable to send iocinit\n", DEVNAME(sc));
175 		goto free_ccbs;
176 	}
177 
178 	/* spin until we're operational */
179 	if (mpi_wait_eq(sc, MPI_DOORBELL, MPI_DOORBELL_STATE,
180 	    MPI_DOORBELL_STATE_OPER) != 0) {
181 		printf("%s: state: 0x%08x\n", DEVNAME(sc),
182 		    mpi_read_db(sc) & MPI_DOORBELL_STATE);
183 		printf("%s: operational state timeout\n", DEVNAME(sc));
184 		goto free_ccbs;
185 	}
186 
187 	mpi_push_replies(sc);
188 
189 	if (mpi_portfacts(sc) != 0) {
190 		printf("%s: unable to get portfacts\n", DEVNAME(sc));
191 		goto free_replies;
192 	}
193 
194 #if notyet
195 	if (mpi_eventnotify(sc) != 0) {
196 		printf("%s: unable to get portfacts\n", DEVNAME(sc));
197 		goto free_replies;
198 	}
199 #endif
200 
201 	if (mpi_portenable(sc) != 0) {
202 		printf("%s: unable to enable port\n", DEVNAME(sc));
203 		goto free_replies;
204 	}
205 
206 	if (mpi_fwupload(sc) != 0) {
207 		printf("%s: unable to upload firmware\n", DEVNAME(sc));
208 		goto free_replies;
209 	}
210 
211 	if (sc->sc_porttype == MPI_PORTFACTS_PORTTYPE_SCSI)
212 		mpi_squash_ppr(sc);
213 
214 	/* we should be good to go now, attach scsibus */
215 	sc->sc_link.device = &mpi_dev;
216 	sc->sc_link.adapter = &mpi_switch;
217 	sc->sc_link.adapter_softc = sc;
218 	sc->sc_link.adapter_target = sc->sc_target;
219 	sc->sc_link.adapter_buswidth = sc->sc_buswidth;
220 	sc->sc_link.openings = sc->sc_maxcmds / sc->sc_buswidth;
221 
222 	config_found(&sc->sc_dev, &sc->sc_link, scsiprint);
223 
224 	/* find our scsibus */
225 	TAILQ_FOREACH(dev, &alldevs, dv_list) {
226 		if (dev->dv_parent == &sc->sc_dev)
227 			break;
228 	}
229 	sc->sc_scsibus = (struct scsibus_softc *)dev;
230 
231 	/* get raid pages */
232 	mpi_get_raid(sc);
233 
234 	/* do domain validation */
235 	if (sc->sc_porttype == MPI_PORTFACTS_PORTTYPE_SCSI)
236 		mpi_run_ppr(sc);
237 	if (sc->sc_porttype == MPI_PORTFACTS_PORTTYPE_FC)
238 		mpi_fc_print(sc);
239 
240 	/* enable interrupts */
241 	mpi_write(sc, MPI_INTR_MASK, MPI_INTR_MASK_DOORBELL);
242 
243 	return (0);
244 
245 free_replies:
246 	bus_dmamap_sync(sc->sc_dmat, MPI_DMA_MAP(sc->sc_replies),
247 	    0, PAGE_SIZE, BUS_DMASYNC_POSTREAD);
248 	mpi_dmamem_free(sc, sc->sc_replies);
249 free_ccbs:
250 	while ((ccb = mpi_get_ccb(sc)) != NULL)
251 		bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
252 	mpi_dmamem_free(sc, sc->sc_requests);
253 	free(sc->sc_ccbs, M_DEVBUF);
254 
255 	return(1);
256 }
257 
258 void
259 mpi_fc_print(struct mpi_softc *sc)
260 {
261 	struct mpi_cfg_hdr		hdr;
262 	struct mpi_cfg_fc_port_pg0	pg;
263 	struct mpi_cfg_fc_device_pg0	dpg;
264 	struct device			*dev;
265 	struct scsibus_softc		*ssc;
266 	struct scsi_link		*link;
267 	int				i;
268 	u_int32_t			btid;
269 
270 	if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_FC_PORT, 0, 0,
271 	    &hdr) != 0) {
272 		DNPRINTF(MPI_D_MISC, "%s: mpi_fc_print unable to fetch "
273 		    "FC port header 0\n", DEVNAME(sc));
274 		return;
275 	}
276 
277 	if (mpi_cfg_page(sc, 0, &hdr, 1, &pg, sizeof(pg)) != 0) {
278 		DNPRINTF(MPI_D_MISC, "%s: mpi_fc_print unable to fetch "
279 		    "FC port page 0\n",
280 		    DEVNAME(sc));
281 		return;
282 	}
283 
284 	DNPRINTF(MPI_D_MISC, "%s: at: %dGHz WWNN: %016llx WWPN: %016llx\n",
285 	    DEVNAME(sc), letoh32(pg.current_speed), letoh64(pg.wwnn),
286 	    letoh64(pg.wwpn));
287 
288 	TAILQ_FOREACH(dev, &alldevs, dv_list) {
289 		if (dev->dv_parent == &sc->sc_dev)
290 			break;
291 	}
292 
293 	/* im too nice to punish idiots who don't configure scsibus */
294 	if (dev == NULL)
295 		return;
296 
297 	ssc = (struct scsibus_softc *)dev;
298 	for (i = 0; i < sc->sc_link.adapter_buswidth; i++) {
299 
300 		link = ssc->sc_link[i][0];
301 
302 		if (link == NULL)
303 			continue;
304 
305 		btid = i | MPI_PAGE_ADDRESS_FC_BTID;
306 		if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_FC_DEV, 0,
307 		    btid, &hdr) != 0) {
308 			DNPRINTF(MPI_D_MISC, "%s: mpi_fc_print unable to fetch "
309 			    "device header 0\n", DEVNAME(sc));
310 			return;
311 		}
312 
313 		bzero(&dpg, sizeof(dpg));
314 		if (mpi_cfg_page(sc, btid, &hdr, 1, &dpg, sizeof(dpg)) != 0) {
315 			DNPRINTF(MPI_D_MISC, "%s: mpi_fc_print unable to fetch "
316 			    "device page 0\n", DEVNAME(sc));
317 			continue;
318 		}
319 
320 		link->port_wwn = letoh64(dpg.wwpn);
321 		link->node_wwn = letoh64(dpg.wwnn);
322 
323 		DNPRINTF(MPI_D_MISC, "%s: target %d WWNN: %016llx "
324 		    "WWPN: %016llx\n", DEVNAME(sc), i,
325 		    letoh64(dpg.wwnn), letoh64(dpg.wwpn));
326 	}
327 }
328 
329 void
330 mpi_squash_ppr(struct mpi_softc *sc)
331 {
332 	struct mpi_cfg_hdr		hdr;
333 	struct mpi_cfg_spi_dev_pg1	page;
334 	int				i;
335 
336 	DNPRINTF(MPI_D_PPR, "%s: mpi_squash_ppr\n", DEVNAME(sc));
337 
338 	for (i = 0; i < sc->sc_buswidth; i++) {
339 		if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_SCSI_SPI_DEV,
340 		    1, i, &hdr) != 0)
341 			return;
342 
343 		if (mpi_cfg_page(sc, i, &hdr, 1, &page, sizeof(page)) != 0)
344 			return;
345 
346 		DNPRINTF(MPI_D_PPR, "%s:  target: %d req_params1: 0x%02x "
347 		    "req_offset: 0x%02x req_period: 0x%02x "
348 		    "req_params2: 0x%02x conf: 0x%08x\n", DEVNAME(sc), i,
349 		    page.req_params1, page.req_offset, page.req_period,
350 		    page.req_params2, letoh32(page.configuration));
351 
352 		page.req_params1 = 0x0;
353 		page.req_offset = 0x0;
354 		page.req_period = 0x0;
355 		page.req_params2 = 0x0;
356 		page.configuration = htole32(0x0);
357 
358 		if (mpi_cfg_page(sc, i, &hdr, 0, &page, sizeof(page)) != 0)
359 			return;
360 	}
361 }
362 
363 void
364 mpi_run_ppr(struct mpi_softc *sc)
365 {
366 	struct mpi_cfg_hdr		hdr;
367 	struct mpi_cfg_spi_port_pg0	port_pg;
368 	struct mpi_cfg_ioc_pg3		*physdisk_pg;
369 	struct mpi_cfg_raid_physdisk	*physdisk_list, *physdisk;
370 	size_t				pagelen;
371 	struct scsi_link		*link;
372 	int				i, tries;
373 
374 	if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_SCSI_SPI_PORT, 0, 0x0,
375 	    &hdr) != 0) {
376 		DNPRINTF(MPI_D_PPR, "%s: mpi_run_ppr unable to fetch header\n",
377 		    DEVNAME(sc));
378 		return;
379 	}
380 
381 	if (mpi_cfg_page(sc, 0x0, &hdr, 1, &port_pg, sizeof(port_pg)) != 0) {
382 		DNPRINTF(MPI_D_PPR, "%s: mpi_run_ppr unable to fetch page\n",
383 		    DEVNAME(sc));
384 		return;
385 	}
386 
387 	for (i = 0; i < sc->sc_buswidth; i++) {
388 		link = sc->sc_scsibus->sc_link[i][0];
389 		if (link == NULL)
390 			continue;
391 
392 		/* do not ppr volumes */
393 		if (link->flags & SDEV_VIRTUAL)
394 			continue;
395 
396 		tries = 0;
397 		while (mpi_ppr(sc, link, NULL, port_pg.min_period,
398 		    port_pg.max_offset, tries) == EAGAIN)
399 			tries++;
400 	}
401 
402 	if ((sc->sc_flags & MPI_F_RAID) == 0)
403 		return;
404 
405 	if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_IOC, 3, 0x0,
406 	    &hdr) != 0) {
407 		DNPRINTF(MPI_D_RAID|MPI_D_PPR, "%s: mpi_run_ppr unable to "
408 		    "fetch ioc pg 3 header\n", DEVNAME(sc));
409 		return;
410 	}
411 
412 	pagelen = hdr.page_length * 4; /* dwords to bytes */
413 	physdisk_pg = malloc(pagelen, M_TEMP, M_WAITOK);
414 	if (physdisk_pg == NULL) {
415 		DNPRINTF(MPI_D_RAID|MPI_D_PPR, "%s: mpi_run_ppr unable to "
416 		    "allocate ioc pg 3\n", DEVNAME(sc));
417 		return;
418 	}
419 	physdisk_list = (struct mpi_cfg_raid_physdisk *)(physdisk_pg + 1);
420 
421 	if (mpi_cfg_page(sc, 0, &hdr, 1, physdisk_pg, pagelen) != 0) {
422 		DNPRINTF(MPI_D_PPR|MPI_D_PPR, "%s: mpi_run_ppr unable to "
423 		    "fetch ioc page 3\n", DEVNAME(sc));
424 		goto out;
425 	}
426 
427 	DNPRINTF(MPI_D_PPR|MPI_D_PPR, "%s:  no_phys_disks: %d\n", DEVNAME(sc),
428 	    physdisk_pg->no_phys_disks);
429 
430 	for (i = 0; i < physdisk_pg->no_phys_disks; i++) {
431 		physdisk = &physdisk_list[i];
432 
433 		DNPRINTF(MPI_D_PPR|MPI_D_PPR, "%s:  id: %d bus: %d ioc: %d "
434 		    "num: %d\n", DEVNAME(sc), physdisk->phys_disk_id,
435 		    physdisk->phys_disk_bus, physdisk->phys_disk_ioc,
436 		    physdisk->phys_disk_num);
437 
438 		if (physdisk->phys_disk_ioc != sc->sc_ioc_number)
439 			continue;
440 
441 		tries = 0;
442 		while (mpi_ppr(sc, NULL, physdisk, port_pg.min_period,
443 		    port_pg.max_offset, tries) == EAGAIN)
444 			tries++;
445 	}
446 
447 out:
448 	free(physdisk_pg, M_TEMP);
449 }
450 
451 int
452 mpi_ppr(struct mpi_softc *sc, struct scsi_link *link,
453     struct mpi_cfg_raid_physdisk *physdisk, int period, int offset, int try)
454 {
455 	struct mpi_cfg_hdr		hdr0, hdr1;
456 	struct mpi_cfg_spi_dev_pg0	pg0;
457 	struct mpi_cfg_spi_dev_pg1	pg1;
458 	u_int32_t			address;
459 	int				id;
460 	int				raid = 0;
461 
462 	DNPRINTF(MPI_D_PPR, "%s: mpi_ppr period: %d offset: %d try: %d "
463 	    "link quirks: 0x%x\n", DEVNAME(sc), period, offset, try,
464 	    link->quirks);
465 
466 	if (try >= 3)
467 		return (EIO);
468 
469 	if (physdisk == NULL) {
470 		if ((link->inqdata.device & SID_TYPE) == T_PROCESSOR)
471 			return (EIO);
472 
473 		address = link->target;
474 		id = link->target;
475 	} else {
476 		raid = 1;
477 		address = (physdisk->phys_disk_bus << 8) |
478 		    (physdisk->phys_disk_id);
479 		id = physdisk->phys_disk_num;
480 	}
481 
482 	if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_SCSI_SPI_DEV, 0,
483 	    address, &hdr0) != 0) {
484 		DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to fetch header 0\n",
485 		    DEVNAME(sc));
486 		return (EIO);
487 	}
488 
489 	if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_SCSI_SPI_DEV, 1,
490 	    address, &hdr1) != 0) {
491 		DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to fetch header 1\n",
492 		    DEVNAME(sc));
493 		return (EIO);
494 	}
495 
496 #ifdef MPI_DEBUG
497 	if (mpi_cfg_page(sc, address, &hdr0, 1, &pg0, sizeof(pg0)) != 0) {
498 		DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to fetch page 0\n",
499 		    DEVNAME(sc));
500 		return (EIO);
501 	}
502 
503 	DNPRINTF(MPI_D_PPR, "%s: mpi_ppr dev pg 0 neg_params1: 0x%02x "
504 	    "neg_offset: %d neg_period: 0x%02x neg_params2: 0x%02x "
505 	    "info: 0x%08x\n", DEVNAME(sc), pg0.neg_params1, pg0.neg_offset,
506 	    pg0.neg_period, pg0.neg_params2, letoh32(pg0.information));
507 #endif
508 
509 	if (mpi_cfg_page(sc, address, &hdr1, 1, &pg1, sizeof(pg1)) != 0) {
510 		DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to fetch page 1\n",
511 		    DEVNAME(sc));
512 		return (EIO);
513 	}
514 
515 	DNPRINTF(MPI_D_PPR, "%s: mpi_ppr dev pg 1 req_params1: 0x%02x "
516 	    "req_offset: 0x%02x req_period: 0x%02x req_params2: 0x%02x "
517 	    "conf: 0x%08x\n", DEVNAME(sc), pg1.req_params1, pg1.req_offset,
518 	    pg1.req_period, pg1.req_params2, letoh32(pg1.configuration));
519 
520 	pg1.req_params1 = 0;
521 	pg1.req_offset = offset;
522 	pg1.req_period = period;
523 	pg1.req_params2 &= ~MPI_CFG_SPI_DEV_1_REQPARAMS_WIDTH;
524 
525 	if (raid || !(link->quirks & SDEV_NOSYNC)) {
526 		pg1.req_params2 |= MPI_CFG_SPI_DEV_1_REQPARAMS_WIDTH_WIDE;
527 
528 		switch (try) {
529 		case 0: /* U320 */
530 			break;
531 		case 1: /* U160 */
532 			pg1.req_period = 0x09;
533 			break;
534 		case 2: /* U80 */
535 			pg1.req_period = 0x0a;
536 			break;
537 		}
538 
539 		if (pg1.req_period < 0x09) {
540 			/* Ultra320: enable QAS & PACKETIZED */
541 			pg1.req_params1 |= MPI_CFG_SPI_DEV_1_REQPARAMS_QAS |
542 			    MPI_CFG_SPI_DEV_1_REQPARAMS_PACKETIZED;
543 		}
544 		if (pg1.req_period < 0xa) {
545 			/* >= Ultra160: enable dual xfers */
546 			pg1.req_params1 |=
547 			    MPI_CFG_SPI_DEV_1_REQPARAMS_DUALXFERS;
548 		}
549 	}
550 
551 	DNPRINTF(MPI_D_PPR, "%s: mpi_ppr dev pg 1 req_params1: 0x%02x "
552 	    "req_offset: 0x%02x req_period: 0x%02x req_params2: 0x%02x "
553 	    "conf: 0x%08x\n", DEVNAME(sc), pg1.req_params1, pg1.req_offset,
554 	    pg1.req_period, pg1.req_params2, letoh32(pg1.configuration));
555 
556 	if (mpi_cfg_page(sc, address, &hdr1, 0, &pg1, sizeof(pg1)) != 0) {
557 		DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to write page 1\n",
558 		    DEVNAME(sc));
559 		return (EIO);
560 	}
561 
562 	if (mpi_cfg_page(sc, address, &hdr1, 1, &pg1, sizeof(pg1)) != 0) {
563 		DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to read page 1\n",
564 		    DEVNAME(sc));
565 		return (EIO);
566 	}
567 
568 	DNPRINTF(MPI_D_PPR, "%s: mpi_ppr dev pg 1 req_params1: 0x%02x "
569 	    "req_offset: 0x%02x req_period: 0x%02x req_params2: 0x%02x "
570 	    "conf: 0x%08x\n", DEVNAME(sc), pg1.req_params1, pg1.req_offset,
571 	    pg1.req_period, pg1.req_params2, letoh32(pg1.configuration));
572 
573 	if (mpi_inq(sc, id, raid) != 0) {
574 		DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to do inquiry against "
575 		    "target %d\n", DEVNAME(sc), link->target);
576 		return (EIO);
577 	}
578 
579 	if (mpi_cfg_page(sc, address, &hdr0, 1, &pg0, sizeof(pg0)) != 0) {
580 		DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to read page 0 after "
581 		    "inquiry\n", DEVNAME(sc));
582 		return (EIO);
583 	}
584 
585 	DNPRINTF(MPI_D_PPR, "%s: mpi_ppr dev pg 0 neg_params1: 0x%02x "
586 	    "neg_offset: %d neg_period: 0x%02x neg_params2: 0x%02x "
587 	    "info: 0x%08x\n", DEVNAME(sc), pg0.neg_params1, pg0.neg_offset,
588 	    pg0.neg_period, pg0.neg_params2, letoh32(pg0.information));
589 
590 	if (!(letoh32(pg0.information) & 0x07) && (try == 0)) {
591 		DNPRINTF(MPI_D_PPR, "%s: mpi_ppr U320 ppr rejected\n",
592 		    DEVNAME(sc));
593 		return (EAGAIN);
594 	}
595 
596 	if ((((letoh32(pg0.information) >> 8) & 0xff) > 0x09) && (try == 1)) {
597 		DNPRINTF(MPI_D_PPR, "%s: mpi_ppr U160 ppr rejected\n",
598 		    DEVNAME(sc));
599 		return (EAGAIN);
600 	}
601 
602 	if (letoh32(pg0.information) & 0x0e) {
603 		DNPRINTF(MPI_D_PPR, "%s: mpi_ppr ppr rejected: %0x\n",
604 		    DEVNAME(sc), letoh32(pg0.information));
605 		return (EAGAIN);
606 	}
607 
608 	switch(pg0.neg_period) {
609 	case 0x08:
610 		period = 160;
611 		break;
612 	case 0x09:
613 		period = 80;
614 		break;
615 	case 0x0a:
616 		period = 40;
617 		break;
618 	case 0x0b:
619 		period = 20;
620 		break;
621 	case 0x0c:
622 		period = 10;
623 		break;
624 	default:
625 		period = 0;
626 		break;
627 	}
628 
629 	printf("%s: %s %d %s at %dMHz width %dbit offset %d "
630 	    "QAS %d DT %d IU %d\n", DEVNAME(sc), raid ? "phys disk" : "target",
631 	    id, period ? "Sync" : "Async", period,
632 	    (pg0.neg_params2 & MPI_CFG_SPI_DEV_0_NEGPARAMS_WIDTH_WIDE) ? 16 : 8,
633 	    pg0.neg_offset,
634 	    (pg0.neg_params1 & MPI_CFG_SPI_DEV_0_NEGPARAMS_QAS) ? 1 : 0,
635 	    (pg0.neg_params1 & MPI_CFG_SPI_DEV_0_NEGPARAMS_DUALXFERS) ? 1 : 0,
636 	    (pg0.neg_params1 & MPI_CFG_SPI_DEV_0_NEGPARAMS_PACKETIZED) ? 1 : 0);
637 
638 	return (0);
639 }
640 
641 int
642 mpi_inq(struct mpi_softc *sc, u_int16_t target, int physdisk)
643 {
644 	struct mpi_ccb			*ccb;
645 	struct scsi_inquiry		inq;
646 	struct {
647 		struct mpi_msg_scsi_io		io;
648 		struct mpi_sge			sge;
649 		struct scsi_inquiry_data	inqbuf;
650 		struct scsi_sense_data		sense;
651 	} __packed			*bundle;
652 	struct mpi_msg_scsi_io		*io;
653 	struct mpi_sge			*sge;
654 	u_int64_t			addr;
655 
656 	DNPRINTF(MPI_D_PPR, "%s: mpi_inq\n", DEVNAME(sc));
657 
658 	bzero(&inq, sizeof(inq));
659 	inq.opcode = INQUIRY;
660 
661 	ccb = mpi_get_ccb(sc);
662 	if (ccb == NULL)
663 		return (1);
664 
665 	ccb->ccb_done = mpi_empty_done;
666 
667 	bundle = ccb->ccb_cmd;
668 	io = &bundle->io;
669 	sge = &bundle->sge;
670 
671 	io->function = physdisk ? MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH :
672 	    MPI_FUNCTION_SCSI_IO_REQUEST;
673 	/*
674 	 * bus is always 0
675 	 * io->bus = htole16(sc->sc_bus);
676 	 */
677 	io->target_id = target;
678 
679 	io->cdb_length = sizeof(inq);
680 	io->sense_buf_len = sizeof(struct scsi_sense_data);
681 	io->msg_flags = MPI_SCSIIO_SENSE_BUF_ADDR_WIDTH_64;
682 
683 	io->msg_context = htole32(ccb->ccb_id);
684 
685 	/*
686 	 * always lun 0
687 	 * io->lun[0] = htobe16(link->lun);
688 	 */
689 
690 	io->direction = MPI_SCSIIO_DIR_READ;
691 	io->tagging = MPI_SCSIIO_ATTR_NO_DISCONNECT;
692 
693 	bcopy(&inq, io->cdb, sizeof(inq));
694 
695 	io->data_length = htole32(sizeof(struct scsi_inquiry_data));
696 
697 	io->sense_buf_low_addr = htole32(ccb->ccb_cmd_dva +
698 	    ((u_int8_t *)&bundle->sense - (u_int8_t *)bundle));
699 
700 	sge->sg_hdr = htole32(MPI_SGE_FL_TYPE_SIMPLE | MPI_SGE_FL_SIZE_64 |
701 	    MPI_SGE_FL_LAST | MPI_SGE_FL_EOB | MPI_SGE_FL_EOL |
702 	    (u_int32_t)sizeof(inq));
703 
704 	addr = ccb->ccb_cmd_dva +
705 	    ((u_int8_t *)&bundle->inqbuf - (u_int8_t *)bundle);
706 	sge->sg_hi_addr = htole32((u_int32_t)(addr >> 32));
707 	sge->sg_lo_addr = htole32((u_int32_t)addr);
708 
709 	if (mpi_poll(sc, ccb, 5000) != 0)
710 		return (1);
711 
712 	if (ccb->ccb_reply != NULL)
713 		mpi_push_reply(sc, ccb->ccb_reply_dva);
714 
715 	mpi_put_ccb(sc, ccb);
716 
717 	return (0);
718 }
719 
720 void
721 mpi_detach(struct mpi_softc *sc)
722 {
723 
724 }
725 
726 int
727 mpi_intr(void *arg)
728 {
729 	struct mpi_softc		*sc = arg;
730 	struct mpi_ccb			*ccb;
731 	struct mpi_msg_reply		*reply;
732 	u_int32_t			reply_dva;
733 	char				*reply_addr;
734 	u_int32_t			reg, id;
735 	int				rv = 0;
736 
737 	while ((reg = mpi_pop_reply(sc)) != 0xffffffff) {
738 
739 		DNPRINTF(MPI_D_INTR, "%s: mpi_intr reply_queue: 0x%08x\n",
740 		    DEVNAME(sc), reg);
741 
742 		if (reg & MPI_REPLY_QUEUE_ADDRESS) {
743 			bus_dmamap_sync(sc->sc_dmat,
744 			    MPI_DMA_MAP(sc->sc_replies), 0, PAGE_SIZE,
745 			    BUS_DMASYNC_POSTREAD);
746 
747 			reply_dva = (reg & MPI_REPLY_QUEUE_ADDRESS_MASK) << 1;
748 
749 			reply_addr = MPI_DMA_KVA(sc->sc_replies);
750 			reply_addr += reply_dva -
751 			    (u_int32_t)MPI_DMA_DVA(sc->sc_replies);
752 			reply = (struct mpi_msg_reply *)reply_addr;
753 
754 			id = letoh32(reply->msg_context);
755 
756 			bus_dmamap_sync(sc->sc_dmat,
757 			    MPI_DMA_MAP(sc->sc_replies), 0, PAGE_SIZE,
758 			    BUS_DMASYNC_PREREAD);
759 		} else {
760 			switch (reg & MPI_REPLY_QUEUE_TYPE_MASK) {
761 			case MPI_REPLY_QUEUE_TYPE_INIT:
762 				id = reg & MPI_REPLY_QUEUE_CONTEXT;
763 				break;
764 
765 			default:
766 				panic("%s: unsupported context reply\n",
767 				    DEVNAME(sc));
768 			}
769 
770 			reply = NULL;
771 		}
772 
773 		DNPRINTF(MPI_D_INTR, "%s: mpi_intr id: %d reply: %p\n",
774 		    DEVNAME(sc), id, reply);
775 
776 		ccb = &sc->sc_ccbs[id];
777 
778 		bus_dmamap_sync(sc->sc_dmat, MPI_DMA_MAP(sc->sc_requests),
779 		    ccb->ccb_offset, MPI_REQUEST_SIZE,
780 		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
781 		ccb->ccb_state = MPI_CCB_READY;
782 		ccb->ccb_reply = reply;
783 		ccb->ccb_reply_dva = reply_dva;
784 
785 		ccb->ccb_done(ccb);
786 		rv = 1;
787 	}
788 
789 	return (rv);
790 }
791 
792 struct mpi_dmamem *
793 mpi_dmamem_alloc(struct mpi_softc *sc, size_t size)
794 {
795 	struct mpi_dmamem		*mdm;
796 	int				nsegs;
797 
798 	mdm = malloc(sizeof(struct mpi_dmamem), M_DEVBUF, M_NOWAIT);
799 	if (mdm == NULL)
800 		return (NULL);
801 
802 	bzero(mdm, sizeof(struct mpi_dmamem));
803 	mdm->mdm_size = size;
804 
805 	if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
806 	    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &mdm->mdm_map) != 0)
807 		goto mdmfree;
808 
809 	if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &mdm->mdm_seg,
810 	    1, &nsegs, BUS_DMA_NOWAIT) != 0)
811 		goto destroy;
812 
813 	if (bus_dmamem_map(sc->sc_dmat, &mdm->mdm_seg, nsegs, size,
814 	    &mdm->mdm_kva, BUS_DMA_NOWAIT) != 0)
815 		goto free;
816 
817 	if (bus_dmamap_load(sc->sc_dmat, mdm->mdm_map, mdm->mdm_kva, size,
818 	    NULL, BUS_DMA_NOWAIT) != 0)
819 		goto unmap;
820 
821 	bzero(mdm->mdm_kva, size);
822 
823 	DNPRINTF(MPI_D_MEM, "%s: mpi_dmamem_alloc size: %d mdm: %#x "
824 	    "map: %#x nsegs: %d segs: %#x kva: %x\n",
825 	    DEVNAME(sc), size, mdm->mdm_map, nsegs, mdm->mdm_seg, mdm->mdm_kva);
826 
827 	return (mdm);
828 
829 unmap:
830 	bus_dmamem_unmap(sc->sc_dmat, mdm->mdm_kva, size);
831 free:
832 	bus_dmamem_free(sc->sc_dmat, &mdm->mdm_seg, 1);
833 destroy:
834 	bus_dmamap_destroy(sc->sc_dmat, mdm->mdm_map);
835 mdmfree:
836 	free(mdm, M_DEVBUF);
837 
838 	return (NULL);
839 }
840 
841 void
842 mpi_dmamem_free(struct mpi_softc *sc, struct mpi_dmamem *mdm)
843 {
844 	DNPRINTF(MPI_D_MEM, "%s: mpi_dmamem_free %#x\n", DEVNAME(sc), mdm);
845 
846 	bus_dmamap_unload(sc->sc_dmat, mdm->mdm_map);
847 	bus_dmamem_unmap(sc->sc_dmat, mdm->mdm_kva, mdm->mdm_size);
848 	bus_dmamem_free(sc->sc_dmat, &mdm->mdm_seg, 1);
849 	bus_dmamap_destroy(sc->sc_dmat, mdm->mdm_map);
850 	free(mdm, M_DEVBUF);
851 }
852 
853 int
854 mpi_alloc_ccbs(struct mpi_softc *sc)
855 {
856 	struct mpi_ccb			*ccb;
857 	u_int8_t			*cmd;
858 	int				i;
859 
860 	TAILQ_INIT(&sc->sc_ccb_free);
861 
862 	sc->sc_ccbs = malloc(sizeof(struct mpi_ccb) * sc->sc_maxcmds,
863 	    M_DEVBUF, M_WAITOK);
864 	if (sc->sc_ccbs == NULL) {
865 		printf("%s: unable to allocate ccbs\n", DEVNAME(sc));
866 		return (1);
867 	}
868 	bzero(sc->sc_ccbs, sizeof(struct mpi_ccb) * sc->sc_maxcmds);
869 
870 	sc->sc_requests = mpi_dmamem_alloc(sc,
871 	    MPI_REQUEST_SIZE * sc->sc_maxcmds);
872 	if (sc->sc_requests == NULL) {
873 		printf("%s: unable to allocate ccb dmamem\n", DEVNAME(sc));
874 		goto free_ccbs;
875 	}
876 	cmd = MPI_DMA_KVA(sc->sc_requests);
877 	bzero(cmd, MPI_REQUEST_SIZE * sc->sc_maxcmds);
878 
879 	for (i = 0; i < sc->sc_maxcmds; i++) {
880 		ccb = &sc->sc_ccbs[i];
881 
882 		if (bus_dmamap_create(sc->sc_dmat, MAXPHYS,
883 		    sc->sc_max_sgl_len, MAXPHYS, 0, 0,
884 		    &ccb->ccb_dmamap) != 0) {
885 			printf("%s: unable to create dma map\n", DEVNAME(sc));
886 			goto free_maps;
887 		}
888 
889 		ccb->ccb_sc = sc;
890 		ccb->ccb_id = i;
891 		ccb->ccb_offset = MPI_REQUEST_SIZE * i;
892 
893 		ccb->ccb_cmd = &cmd[ccb->ccb_offset];
894 		ccb->ccb_cmd_dva = (u_int32_t)MPI_DMA_DVA(sc->sc_requests) +
895 		    ccb->ccb_offset;
896 
897 		DNPRINTF(MPI_D_CCB, "%s: mpi_alloc_ccbs(%d) ccb: %#x map: %#x "
898 		    "sc: %#x id: %#x offs: %#x cmd: %#x dva: %#x\n",
899 		    DEVNAME(sc), i, ccb, ccb->ccb_dmamap, ccb->ccb_sc,
900 		    ccb->ccb_id, ccb->ccb_offset, ccb->ccb_cmd,
901 		    ccb->ccb_cmd_dva);
902 
903 		mpi_put_ccb(sc, ccb);
904 	}
905 
906 	return (0);
907 
908 free_maps:
909 	while ((ccb = mpi_get_ccb(sc)) != NULL)
910 		bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
911 
912 	mpi_dmamem_free(sc, sc->sc_requests);
913 free_ccbs:
914 	free(sc->sc_ccbs, M_DEVBUF);
915 
916 	return (1);
917 }
918 
919 struct mpi_ccb *
920 mpi_get_ccb(struct mpi_softc *sc)
921 {
922 	struct mpi_ccb			*ccb;
923 
924 	ccb = TAILQ_FIRST(&sc->sc_ccb_free);
925 	if (ccb == NULL) {
926 		DNPRINTF(MPI_D_CCB, "%s: mpi_get_ccb == NULL\n", DEVNAME(sc));
927 		return (NULL);
928 	}
929 
930 	TAILQ_REMOVE(&sc->sc_ccb_free, ccb, ccb_link);
931 
932 	ccb->ccb_state = MPI_CCB_READY;
933 
934 	DNPRINTF(MPI_D_CCB, "%s: mpi_get_ccb %#x\n", DEVNAME(sc), ccb);
935 
936 	return (ccb);
937 }
938 
939 void
940 mpi_put_ccb(struct mpi_softc *sc, struct mpi_ccb *ccb)
941 {
942 	DNPRINTF(MPI_D_CCB, "%s: mpi_put_ccb %#x\n", DEVNAME(sc), ccb);
943 
944 	ccb->ccb_state = MPI_CCB_FREE;
945 	ccb->ccb_xs = NULL;
946 	ccb->ccb_done = NULL;
947 	bzero(ccb->ccb_cmd, MPI_REQUEST_SIZE);
948 	TAILQ_INSERT_TAIL(&sc->sc_ccb_free, ccb, ccb_link);
949 }
950 
951 int
952 mpi_alloc_replies(struct mpi_softc *sc)
953 {
954 	DNPRINTF(MPI_D_MISC, "%s: mpi_alloc_replies\n", DEVNAME(sc));
955 
956 	sc->sc_replies = mpi_dmamem_alloc(sc, PAGE_SIZE);
957 	if (sc->sc_replies == NULL)
958 		return (1);
959 
960 	return (0);
961 }
962 
963 void
964 mpi_push_replies(struct mpi_softc *sc)
965 {
966 	paddr_t				reply;
967 	int				i;
968 
969 	bus_dmamap_sync(sc->sc_dmat, MPI_DMA_MAP(sc->sc_replies),
970 	    0, PAGE_SIZE, BUS_DMASYNC_PREREAD);
971 
972 	for (i = 0; i < PAGE_SIZE / MPI_REPLY_SIZE; i++) {
973 		reply = (u_int32_t)MPI_DMA_DVA(sc->sc_replies) +
974 		    MPI_REPLY_SIZE * i;
975 		DNPRINTF(MPI_D_MEM, "%s: mpi_push_replies %#x\n", DEVNAME(sc),
976 		    reply);
977 		mpi_push_reply(sc, reply);
978 	}
979 }
980 
981 void
982 mpi_start(struct mpi_softc *sc, struct mpi_ccb *ccb)
983 {
984 	DNPRINTF(MPI_D_RW, "%s: mpi_start %#x\n", DEVNAME(sc),
985 	    ccb->ccb_cmd_dva);
986 
987 	bus_dmamap_sync(sc->sc_dmat, MPI_DMA_MAP(sc->sc_requests),
988 	    ccb->ccb_offset, MPI_REQUEST_SIZE,
989 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
990 
991 	ccb->ccb_state = MPI_CCB_QUEUED;
992 	mpi_write(sc, MPI_REQ_QUEUE, ccb->ccb_cmd_dva);
993 }
994 
995 int
996 mpi_complete(struct mpi_softc *sc, struct mpi_ccb *nccb, int timeout)
997 {
998 	struct mpi_ccb			*ccb;
999 	struct mpi_msg_reply		*reply;
1000 	u_int32_t			reply_dva;
1001 	char				*reply_addr;
1002 	u_int32_t			reg, id = 0xffffffff;
1003 
1004 	DNPRINTF(MPI_D_INTR, "%s: mpi_complete timeout %d\n", DEVNAME(sc),
1005 	    timeout);
1006 
1007 	do {
1008 		reg = mpi_pop_reply(sc);
1009 		if (reg == 0xffffffff) {
1010 			if (timeout-- == 0)
1011 				return (1);
1012 
1013 			delay(1000);
1014 			continue;
1015 		}
1016 
1017 		DNPRINTF(MPI_D_INTR, "%s: mpi_complete reply_queue: 0x%08x\n",
1018 		    DEVNAME(sc), reg);
1019 
1020 		if (reg & MPI_REPLY_QUEUE_ADDRESS) {
1021 			bus_dmamap_sync(sc->sc_dmat,
1022 			    MPI_DMA_MAP(sc->sc_replies), 0, PAGE_SIZE,
1023 			    BUS_DMASYNC_POSTREAD);
1024 
1025 			reply_dva = (reg & MPI_REPLY_QUEUE_ADDRESS_MASK) << 1;
1026 
1027 			reply_addr = MPI_DMA_KVA(sc->sc_replies);
1028 			reply_addr += reply_dva -
1029 			    (u_int32_t)MPI_DMA_DVA(sc->sc_replies);
1030 			reply = (struct mpi_msg_reply *)reply_addr;
1031 
1032 			id = letoh32(reply->msg_context);
1033 
1034 			bus_dmamap_sync(sc->sc_dmat,
1035 			    MPI_DMA_MAP(sc->sc_replies), 0, PAGE_SIZE,
1036 			    BUS_DMASYNC_PREREAD);
1037 		} else {
1038 			switch (reg & MPI_REPLY_QUEUE_TYPE_MASK) {
1039 			case MPI_REPLY_QUEUE_TYPE_INIT:
1040 				id = reg & MPI_REPLY_QUEUE_CONTEXT;
1041 				break;
1042 
1043 			default:
1044 				panic("%s: unsupported context reply\n",
1045 				    DEVNAME(sc));
1046 			}
1047 
1048 			reply = NULL;
1049 		}
1050 
1051 		DNPRINTF(MPI_D_INTR, "%s: mpi_complete id: %d\n",
1052 		    DEVNAME(sc), id);
1053 
1054 		ccb = &sc->sc_ccbs[id];
1055 
1056 		bus_dmamap_sync(sc->sc_dmat, MPI_DMA_MAP(sc->sc_requests),
1057 		    ccb->ccb_offset, MPI_REQUEST_SIZE,
1058 		    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
1059 		ccb->ccb_state = MPI_CCB_READY;
1060 		ccb->ccb_reply = reply;
1061 		ccb->ccb_reply_dva = reply_dva;
1062 
1063 		ccb->ccb_done(ccb);
1064 
1065 	} while (nccb->ccb_id != id);
1066 
1067 	return (0);
1068 }
1069 
1070 int
1071 mpi_poll(struct mpi_softc *sc, struct mpi_ccb *ccb, int timeout)
1072 {
1073 	int				error;
1074 	int				s;
1075 
1076 	DNPRINTF(MPI_D_CMD, "%s: mpi_poll\n", DEVNAME(sc));
1077 
1078 	s = splbio();
1079 	mpi_start(sc, ccb);
1080 	error = mpi_complete(sc, ccb, timeout);
1081 	splx(s);
1082 
1083 	return (error);
1084 }
1085 
1086 int
1087 mpi_scsi_cmd(struct scsi_xfer *xs)
1088 {
1089 	struct scsi_link		*link = xs->sc_link;
1090 	struct mpi_softc		*sc = link->adapter_softc;
1091 	struct mpi_ccb			*ccb;
1092 	struct mpi_ccb_bundle		*mcb;
1093 	struct mpi_msg_scsi_io		*io;
1094 	int				s;
1095 
1096 	DNPRINTF(MPI_D_CMD, "%s: mpi_scsi_cmd\n", DEVNAME(sc));
1097 
1098 	if (xs->cmdlen > MPI_CDB_LEN) {
1099 		DNPRINTF(MPI_D_CMD, "%s: CBD too big %d\n",
1100 		    DEVNAME(sc), xs->cmdlen);
1101 		bzero(&xs->sense, sizeof(xs->sense));
1102 		xs->sense.error_code = SSD_ERRCODE_VALID | 0x70;
1103 		xs->sense.flags = SKEY_ILLEGAL_REQUEST;
1104 		xs->sense.add_sense_code = 0x20;
1105 		xs->error = XS_SENSE;
1106 		scsi_done(xs);
1107 		return (COMPLETE);
1108 	}
1109 
1110 	s = splbio();
1111 	ccb = mpi_get_ccb(sc);
1112 	splx(s);
1113 	if (ccb == NULL) {
1114 		xs->error = XS_DRIVER_STUFFUP;
1115 		scsi_done(xs);
1116 		return (COMPLETE);
1117 	}
1118 	DNPRINTF(MPI_D_CMD, "%s: ccb_id: %d xs->flags: 0x%x\n",
1119 	    DEVNAME(sc), ccb->ccb_id, xs->flags);
1120 
1121 	ccb->ccb_xs = xs;
1122 	ccb->ccb_done = mpi_scsi_cmd_done;
1123 
1124 	mcb = ccb->ccb_cmd;
1125 	io = &mcb->mcb_io;
1126 
1127 	io->function = MPI_FUNCTION_SCSI_IO_REQUEST;
1128 	/*
1129 	 * bus is always 0
1130 	 * io->bus = htole16(sc->sc_bus);
1131 	 */
1132 	io->target_id = link->target;
1133 
1134 	io->cdb_length = xs->cmdlen;
1135 	io->sense_buf_len = sizeof(xs->sense);
1136 	io->msg_flags = MPI_SCSIIO_SENSE_BUF_ADDR_WIDTH_64;
1137 
1138 	io->msg_context = htole32(ccb->ccb_id);
1139 
1140 	io->lun[0] = htobe16(link->lun);
1141 
1142 	switch (xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) {
1143 	case SCSI_DATA_IN:
1144 		io->direction = MPI_SCSIIO_DIR_READ;
1145 		break;
1146 	case SCSI_DATA_OUT:
1147 		io->direction = MPI_SCSIIO_DIR_WRITE;
1148 		break;
1149 	default:
1150 		io->direction = MPI_SCSIIO_DIR_NONE;
1151 		break;
1152 	}
1153 
1154 	if (link->quirks & SDEV_NOTAGS)
1155 		io->tagging = MPI_SCSIIO_ATTR_UNTAGGED;
1156 	else
1157 		io->tagging = MPI_SCSIIO_ATTR_SIMPLE_Q;
1158 
1159 	bcopy(xs->cmd, io->cdb, xs->cmdlen);
1160 
1161 	io->data_length = htole32(xs->datalen);
1162 
1163 	io->sense_buf_low_addr = htole32(ccb->ccb_cmd_dva +
1164 	    ((u_int8_t *)&mcb->mcb_sense - (u_int8_t *)mcb));
1165 
1166 	if (mpi_load_xs(ccb) != 0) {
1167 		s = splbio();
1168 		mpi_put_ccb(sc, ccb);
1169 		splx(s);
1170 		xs->error = XS_DRIVER_STUFFUP;
1171 		scsi_done(xs);
1172 		return (COMPLETE);
1173 	}
1174 
1175 	timeout_set(&xs->stimeout, mpi_timeout_xs, ccb);
1176 
1177 	if (xs->flags & SCSI_POLL) {
1178 		if (mpi_poll(sc, ccb, xs->timeout) != 0)
1179 			xs->error = XS_DRIVER_STUFFUP;
1180 		return (COMPLETE);
1181 	}
1182 
1183 	mpi_start(sc, ccb);
1184 	return (SUCCESSFULLY_QUEUED);
1185 }
1186 
1187 void
1188 mpi_scsi_cmd_done(struct mpi_ccb *ccb)
1189 {
1190 	struct mpi_softc		*sc = ccb->ccb_sc;
1191 	struct scsi_xfer		*xs = ccb->ccb_xs;
1192 	struct mpi_ccb_bundle		*mcb = ccb->ccb_cmd;
1193 	bus_dmamap_t			dmap = ccb->ccb_dmamap;
1194 	struct mpi_msg_scsi_io_error	*sie = ccb->ccb_reply;
1195 
1196 	if (xs->datalen != 0) {
1197 		bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
1198 		    (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
1199 		    BUS_DMASYNC_POSTWRITE);
1200 
1201 		bus_dmamap_unload(sc->sc_dmat, dmap);
1202 	}
1203 
1204 	/* timeout_del */
1205 	xs->error = XS_NOERROR;
1206 	xs->resid = 0;
1207 	xs->flags |= ITSDONE;
1208 
1209 	if (sie == NULL) {
1210 		/* no scsi error, we're ok so drop out early */
1211 		xs->status = SCSI_OK;
1212 		mpi_put_ccb(sc, ccb);
1213 		scsi_done(xs);
1214 		return;
1215 	}
1216 
1217 	xs->status = sie->scsi_status;
1218 	switch (letoh16(sie->ioc_status)) {
1219 	case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:
1220 		xs->error = XS_DRIVER_STUFFUP;
1221 		break;
1222 
1223 	case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:
1224 		/*
1225 		 * Yikes!  Tagged queue full comes through this path!
1226 		 *
1227 		 * So we'll change it to a status error and anything
1228 		 * that returns status should probably be a status
1229 		 * error as well.
1230 		 */
1231 		xs->resid = xs->datalen - letoh32(sie->transfer_count);
1232 		if (sie->scsi_state & MPI_SCSIIO_ERR_STATE_NO_SCSI_STATUS) {
1233 			xs->error = XS_DRIVER_STUFFUP;
1234 			break;
1235 		}
1236 		/* FALLTHROUGH */
1237 	case MPI_IOCSTATUS_SUCCESS:
1238 	case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:
1239 		switch (xs->status) {
1240 		case SCSI_OK:
1241 			xs->resid = 0;
1242 			break;
1243 
1244 		case SCSI_CHECK:
1245 			xs->error = XS_SENSE;
1246 			break;
1247 
1248 		case SCSI_BUSY:
1249 			xs->error = XS_BUSY;
1250 			break;
1251 
1252 		case SCSI_QUEUE_FULL:
1253 			xs->error = XS_TIMEOUT;
1254 			xs->retries++;
1255 			break;
1256 		default:
1257 			printf("%s: invalid status code %d\n",
1258 			    DEVNAME(sc), xs->status);
1259 			xs->error = XS_DRIVER_STUFFUP;
1260 			break;
1261 		}
1262 		break;
1263 
1264 	case MPI_IOCSTATUS_BUSY:
1265 	case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:
1266 		xs->error = XS_BUSY;
1267 		break;
1268 
1269 	case MPI_IOCSTATUS_SCSI_INVALID_BUS:
1270 	case MPI_IOCSTATUS_SCSI_INVALID_TARGETID:
1271 	case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
1272 		xs->error = XS_SELTIMEOUT;
1273 		break;
1274 
1275 	case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
1276 		xs->error = XS_DRIVER_STUFFUP;
1277 		break;
1278 
1279 	case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:
1280 		xs->error = XS_DRIVER_STUFFUP;
1281 		break;
1282 
1283 	case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
1284 		/* XXX */
1285 		xs->error = XS_DRIVER_STUFFUP;
1286 		break;
1287 
1288 	case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:
1289 		/* XXX */
1290 		xs->error = XS_DRIVER_STUFFUP;
1291 		break;
1292 
1293 	case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:
1294 		/* XXX This is a bus-reset */
1295 		xs->error = XS_DRIVER_STUFFUP;
1296 		break;
1297 
1298 	default:
1299 		/* XXX unrecognized HBA error */
1300 		xs->error = XS_DRIVER_STUFFUP;
1301 		break;
1302 	}
1303 
1304 	if (sie->scsi_state & MPI_SCSIIO_ERR_STATE_AUTOSENSE_VALID)
1305 		bcopy(&mcb->mcb_sense, &xs->sense, sizeof(xs->sense));
1306 	else if (sie->scsi_state & MPI_SCSIIO_ERR_STATE_AUTOSENSE_FAILED) {
1307 		/* This will cause the scsi layer to issue a REQUEST SENSE */
1308 		if (xs->status == SCSI_CHECK)
1309 			xs->error = XS_BUSY;
1310 	}
1311 
1312 	if (xs->error != XS_NOERROR && !cold) {
1313 		printf("%s:  xs cmd: 0x%02x len: %d error: 0x%02x "
1314 		    "flags 0x%x\n", DEVNAME(sc), xs->cmd->opcode, xs->datalen,
1315 		    xs->error, xs->flags);
1316 		printf("%s:  target_id: %d bus: %d msg_length: %d "
1317 		    "function: 0x%02x\n", DEVNAME(sc), sie->target_id,
1318 		    sie->bus, sie->msg_length, sie->function);
1319 		printf("%s:  cdb_length: %d sense_buf_length: %d "
1320 		    "msg_flags: 0x%02x\n", DEVNAME(sc), sie->cdb_length,
1321 		    sie->bus, sie->msg_flags);
1322 		printf("%s:  msg_context: 0x%08x\n", DEVNAME(sc),
1323 		    letoh32(sie->msg_context));
1324 		printf("%s:  scsi_status: 0x%02x scsi_state: 0x%02x "
1325 		    "ioc_status: 0x%04x\n", DEVNAME(sc), sie->scsi_status,
1326 		    sie->scsi_state, letoh16(sie->ioc_status));
1327 		printf("%s:  ioc_loginfo: 0x%08x\n", DEVNAME(sc),
1328 		    letoh32(sie->ioc_loginfo));
1329 		printf("%s:  transfer_count: %d\n", DEVNAME(sc),
1330 		    letoh32(sie->transfer_count));
1331 		printf("%s:  sense_count: %d\n", DEVNAME(sc),
1332 		    letoh32(sie->sense_count));
1333 		printf("%s:  response_info: 0x%08x\n", DEVNAME(sc),
1334 		    letoh32(sie->response_info));
1335 		printf("%s:  tag: 0x%04x\n", DEVNAME(sc),
1336 		    letoh16(sie->tag));
1337 		printf("%s:  xs error: 0x%02x xs status: %d\n", DEVNAME(sc),
1338 		    xs->error, xs->status);
1339 	}
1340 
1341 	mpi_push_reply(sc, ccb->ccb_reply_dva);
1342 	mpi_put_ccb(sc, ccb);
1343 	scsi_done(xs);
1344 }
1345 
1346 void
1347 mpi_timeout_xs(void *arg)
1348 {
1349 	/* XXX */
1350 }
1351 
1352 int
1353 mpi_load_xs(struct mpi_ccb *ccb)
1354 {
1355 	struct mpi_softc		*sc = ccb->ccb_sc;
1356 	struct scsi_xfer		*xs = ccb->ccb_xs;
1357 	struct mpi_ccb_bundle		*mcb = ccb->ccb_cmd;
1358 	struct mpi_msg_scsi_io		*io = &mcb->mcb_io;
1359 	struct mpi_sge			*sge, *nsge = &mcb->mcb_sgl[0];
1360 	struct mpi_sge			*ce = NULL, *nce;
1361 	u_int64_t			ce_dva;
1362 	bus_dmamap_t			dmap = ccb->ccb_dmamap;
1363 	u_int32_t			addr, flags;
1364 	int				i, error;
1365 
1366 	if (xs->datalen == 0) {
1367 		nsge->sg_hdr = htole32(MPI_SGE_FL_TYPE_SIMPLE |
1368 		    MPI_SGE_FL_LAST | MPI_SGE_FL_EOB | MPI_SGE_FL_EOL);
1369 		return (0);
1370 	}
1371 
1372 	error = bus_dmamap_load(sc->sc_dmat, dmap,
1373 	    xs->data, xs->datalen, NULL,
1374 	    (xs->flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
1375 	if (error) {
1376 		printf("%s: error %d loading dmamap\n", DEVNAME(sc), error);
1377 		return (1);
1378 	}
1379 
1380 	flags = MPI_SGE_FL_TYPE_SIMPLE | MPI_SGE_FL_SIZE_64;
1381 	if (xs->flags & SCSI_DATA_OUT)
1382 		flags |= MPI_SGE_FL_DIR_OUT;
1383 
1384 	if (dmap->dm_nsegs > sc->sc_first_sgl_len) {
1385 		ce = &mcb->mcb_sgl[sc->sc_first_sgl_len - 1];
1386 		io->chain_offset = ((u_int8_t *)ce - (u_int8_t *)io) / 4;
1387 	}
1388 
1389 	for (i = 0; i < dmap->dm_nsegs; i++) {
1390 
1391 		if (nsge == ce) {
1392 			nsge++;
1393 			sge->sg_hdr |= htole32(MPI_SGE_FL_LAST);
1394 
1395 			DNPRINTF(MPI_D_DMA, "%s:   - 0x%08x 0x%08x 0x%08x\n",
1396 			    DEVNAME(sc), sge->sg_hdr,
1397 			    sge->sg_hi_addr, sge->sg_lo_addr);
1398 
1399 			if ((dmap->dm_nsegs - i) > sc->sc_chain_len) {
1400 				nce = &nsge[sc->sc_chain_len - 1];
1401 				addr = ((u_int8_t *)nce - (u_int8_t *)nsge) / 4;
1402 				addr = addr << 16 |
1403 				    sizeof(struct mpi_sge) * sc->sc_chain_len;
1404 			} else {
1405 				nce = NULL;
1406 				addr = sizeof(struct mpi_sge) *
1407 				    (dmap->dm_nsegs - i);
1408 			}
1409 
1410 			ce->sg_hdr = htole32(MPI_SGE_FL_TYPE_CHAIN |
1411 			    MPI_SGE_FL_SIZE_64 | addr);
1412 
1413 			ce_dva = ccb->ccb_cmd_dva +
1414 			    ((u_int8_t *)nsge - (u_int8_t *)mcb);
1415 
1416 			addr = (u_int32_t)(ce_dva >> 32);
1417 			ce->sg_hi_addr = htole32(addr);
1418 			addr = (u_int32_t)ce_dva;
1419 			ce->sg_lo_addr = htole32(addr);
1420 
1421 			DNPRINTF(MPI_D_DMA, "%s:  ce: 0x%08x 0x%08x 0x%08x\n",
1422 			    DEVNAME(sc), ce->sg_hdr, ce->sg_hi_addr,
1423 			    ce->sg_lo_addr);
1424 
1425 			ce = nce;
1426 		}
1427 
1428 		DNPRINTF(MPI_D_DMA, "%s:  %d: %d 0x%016llx\n", DEVNAME(sc),
1429 		    i, dmap->dm_segs[i].ds_len,
1430 		    (u_int64_t)dmap->dm_segs[i].ds_addr);
1431 
1432 		sge = nsge;
1433 
1434 		sge->sg_hdr = htole32(flags | dmap->dm_segs[i].ds_len);
1435 		addr = (u_int32_t)((u_int64_t)dmap->dm_segs[i].ds_addr >> 32);
1436 		sge->sg_hi_addr = htole32(addr);
1437 		addr = (u_int32_t)dmap->dm_segs[i].ds_addr;
1438 		sge->sg_lo_addr = htole32(addr);
1439 
1440 		DNPRINTF(MPI_D_DMA, "%s:  %d: 0x%08x 0x%08x 0x%08x\n",
1441 		    DEVNAME(sc), i, sge->sg_hdr, sge->sg_hi_addr,
1442 		    sge->sg_lo_addr);
1443 
1444 		nsge = sge + 1;
1445 	}
1446 
1447 	/* terminate list */
1448 	sge->sg_hdr |= htole32(MPI_SGE_FL_LAST | MPI_SGE_FL_EOB |
1449 	    MPI_SGE_FL_EOL);
1450 
1451 	bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
1452 	    (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
1453 	    BUS_DMASYNC_PREWRITE);
1454 
1455 	return (0);
1456 }
1457 
1458 void
1459 mpi_minphys(struct buf *bp)
1460 {
1461 	/* XXX */
1462 	if (bp->b_bcount > MAXPHYS)
1463 		bp->b_bcount = MAXPHYS;
1464 	minphys(bp);
1465 }
1466 
1467 int
1468 mpi_scsi_ioctl(struct scsi_link *a, u_long b, caddr_t c, int d, struct proc *e)
1469 {
1470 	return (0);
1471 }
1472 
1473 u_int32_t
1474 mpi_read(struct mpi_softc *sc, bus_size_t r)
1475 {
1476 	u_int32_t			rv;
1477 
1478 	bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4,
1479 	    BUS_SPACE_BARRIER_READ);
1480 	rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, r);
1481 
1482 	DNPRINTF(MPI_D_RW, "%s: mpi_read %#x %#x\n", DEVNAME(sc), r, rv);
1483 
1484 	return (rv);
1485 }
1486 
1487 void
1488 mpi_write(struct mpi_softc *sc, bus_size_t r, u_int32_t v)
1489 {
1490 	DNPRINTF(MPI_D_RW, "%s: mpi_write %#x %#x\n", DEVNAME(sc), r, v);
1491 
1492 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, r, v);
1493 	bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4,
1494 	    BUS_SPACE_BARRIER_WRITE);
1495 }
1496 
1497 int
1498 mpi_wait_eq(struct mpi_softc *sc, bus_size_t r, u_int32_t mask,
1499     u_int32_t target)
1500 {
1501 	int				i;
1502 
1503 	DNPRINTF(MPI_D_RW, "%s: mpi_wait_eq %#x %#x %#x\n", DEVNAME(sc), r,
1504 	    mask, target);
1505 
1506 	for (i = 0; i < 10000; i++) {
1507 		if ((mpi_read(sc, r) & mask) == target)
1508 			return (0);
1509 		delay(1000);
1510 	}
1511 
1512 	return (1);
1513 }
1514 
1515 int
1516 mpi_wait_ne(struct mpi_softc *sc, bus_size_t r, u_int32_t mask,
1517     u_int32_t target)
1518 {
1519 	int				i;
1520 
1521 	DNPRINTF(MPI_D_RW, "%s: mpi_wait_ne %#x %#x %#x\n", DEVNAME(sc), r,
1522 	    mask, target);
1523 
1524 	for (i = 0; i < 10000; i++) {
1525 		if ((mpi_read(sc, r) & mask) != target)
1526 			return (0);
1527 		delay(1000);
1528 	}
1529 
1530 	return (1);
1531 }
1532 
1533 int
1534 mpi_init(struct mpi_softc *sc)
1535 {
1536 	u_int32_t			db;
1537 	int				i;
1538 
1539 	/* spin until the IOC leaves the RESET state */
1540 	if (mpi_wait_ne(sc, MPI_DOORBELL, MPI_DOORBELL_STATE,
1541 	    MPI_DOORBELL_STATE_RESET) != 0) {
1542 		DNPRINTF(MPI_D_MISC, "%s: mpi_init timeout waiting to leave "
1543 		    "reset state\n", DEVNAME(sc));
1544 		return (1);
1545 	}
1546 
1547 	/* check current ownership */
1548 	db = mpi_read_db(sc);
1549 	if ((db & MPI_DOORBELL_WHOINIT) == MPI_DOORBELL_WHOINIT_PCIPEER) {
1550 		DNPRINTF(MPI_D_MISC, "%s: mpi_init initialised by pci peer\n",
1551 		    DEVNAME(sc));
1552 		return (0);
1553 	}
1554 
1555 	for (i = 0; i < 5; i++) {
1556 		switch (db & MPI_DOORBELL_STATE) {
1557 		case MPI_DOORBELL_STATE_READY:
1558 			DNPRINTF(MPI_D_MISC, "%s: mpi_init ioc is ready\n",
1559 			    DEVNAME(sc));
1560 			return (0);
1561 
1562 		case MPI_DOORBELL_STATE_OPER:
1563 		case MPI_DOORBELL_STATE_FAULT:
1564 			DNPRINTF(MPI_D_MISC, "%s: mpi_init ioc is being "
1565 			    "reset\n" , DEVNAME(sc));
1566 			if (mpi_reset_soft(sc) != 0)
1567 				mpi_reset_hard(sc);
1568 			break;
1569 
1570 		case MPI_DOORBELL_STATE_RESET:
1571 			DNPRINTF(MPI_D_MISC, "%s: mpi_init waiting to come "
1572 			    "out of reset\n", DEVNAME(sc));
1573 			if (mpi_wait_ne(sc, MPI_DOORBELL, MPI_DOORBELL_STATE,
1574 			    MPI_DOORBELL_STATE_RESET) != 0)
1575 				return (1);
1576 			break;
1577 		}
1578 		db = mpi_read_db(sc);
1579 	}
1580 
1581 	return (1);
1582 }
1583 
1584 int
1585 mpi_reset_soft(struct mpi_softc *sc)
1586 {
1587 	DNPRINTF(MPI_D_MISC, "%s: mpi_reset_soft\n", DEVNAME(sc));
1588 
1589 	if (mpi_read_db(sc) & MPI_DOORBELL_INUSE)
1590 		return (1);
1591 
1592 	mpi_write_db(sc,
1593 	    MPI_DOORBELL_FUNCTION(MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET));
1594 	if (mpi_wait_eq(sc, MPI_INTR_STATUS,
1595 	    MPI_INTR_STATUS_IOCDOORBELL, 0) != 0)
1596 		return (1);
1597 
1598 	if (mpi_wait_eq(sc, MPI_DOORBELL, MPI_DOORBELL_STATE,
1599 	    MPI_DOORBELL_STATE_READY) != 0)
1600 		return (1);
1601 
1602 	return (0);
1603 }
1604 
1605 int
1606 mpi_reset_hard(struct mpi_softc *sc)
1607 {
1608 	DNPRINTF(MPI_D_MISC, "%s: mpi_reset_hard\n", DEVNAME(sc));
1609 
1610 	/* enable diagnostic register */
1611 	mpi_write(sc, MPI_WRITESEQ, 0xff);
1612 	mpi_write(sc, MPI_WRITESEQ, MPI_WRITESEQ_1);
1613 	mpi_write(sc, MPI_WRITESEQ, MPI_WRITESEQ_2);
1614 	mpi_write(sc, MPI_WRITESEQ, MPI_WRITESEQ_3);
1615 	mpi_write(sc, MPI_WRITESEQ, MPI_WRITESEQ_4);
1616 	mpi_write(sc, MPI_WRITESEQ, MPI_WRITESEQ_5);
1617 
1618 	/* reset ioc */
1619 	mpi_write(sc, MPI_HOSTDIAG, MPI_HOSTDIAG_RESET_ADAPTER);
1620 
1621 	delay(10000);
1622 
1623 	/* disable diagnostic register */
1624 	mpi_write(sc, MPI_WRITESEQ, 0xff);
1625 
1626 	/* restore pci bits? */
1627 
1628 	/* firmware bits? */
1629 	return (0);
1630 }
1631 
1632 int
1633 mpi_handshake_send(struct mpi_softc *sc, void *buf, size_t dwords)
1634 {
1635 	u_int32_t				*query = buf;
1636 	int					i;
1637 
1638 	/* make sure the doorbell is not in use. */
1639 	if (mpi_read_db(sc) & MPI_DOORBELL_INUSE)
1640 		return (1);
1641 
1642 	/* clear pending doorbell interrupts */
1643 	if (mpi_read_intr(sc) & MPI_INTR_STATUS_DOORBELL)
1644 		mpi_write_intr(sc, 0);
1645 
1646 	/*
1647 	 * first write the doorbell with the handshake function and the
1648 	 * dword count.
1649 	 */
1650 	mpi_write_db(sc, MPI_DOORBELL_FUNCTION(MPI_FUNCTION_HANDSHAKE) |
1651 	    MPI_DOORBELL_DWORDS(dwords));
1652 
1653 	/*
1654 	 * the doorbell used bit will be set because a doorbell function has
1655 	 * started. Wait for the interrupt and then ack it.
1656 	 */
1657 	if (mpi_wait_db_int(sc) != 0)
1658 		return (1);
1659 	mpi_write_intr(sc, 0);
1660 
1661 	/* poll for the acknowledgement. */
1662 	if (mpi_wait_db_ack(sc) != 0)
1663 		return (1);
1664 
1665 	/* write the query through the doorbell. */
1666 	for (i = 0; i < dwords; i++) {
1667 		mpi_write_db(sc, htole32(query[i]));
1668 		if (mpi_wait_db_ack(sc) != 0)
1669 			return (1);
1670 	}
1671 
1672 	return (0);
1673 }
1674 
1675 int
1676 mpi_handshake_recv_dword(struct mpi_softc *sc, u_int32_t *dword)
1677 {
1678 	u_int16_t				*words = (u_int16_t *)dword;
1679 	int					i;
1680 
1681 	for (i = 0; i < 2; i++) {
1682 		if (mpi_wait_db_int(sc) != 0)
1683 			return (1);
1684 		words[i] = letoh16(mpi_read_db(sc) & MPI_DOORBELL_DATA_MASK);
1685 		mpi_write_intr(sc, 0);
1686 	}
1687 
1688 	return (0);
1689 }
1690 
1691 int
1692 mpi_handshake_recv(struct mpi_softc *sc, void *buf, size_t dwords)
1693 {
1694 	struct mpi_msg_reply			*reply = buf;
1695 	u_int32_t				*dbuf = buf, dummy;
1696 	int					i;
1697 
1698 	/* get the first dword so we can read the length out of the header. */
1699 	if (mpi_handshake_recv_dword(sc, &dbuf[0]) != 0)
1700 		return (1);
1701 
1702 	DNPRINTF(MPI_D_CMD, "%s: mpi_handshake_recv dwords: %d reply: %d\n",
1703 	    DEVNAME(sc), dwords, reply->msg_length);
1704 
1705 	/*
1706 	 * the total length, in dwords, is in the message length field of the
1707 	 * reply header.
1708 	 */
1709 	for (i = 1; i < MIN(dwords, reply->msg_length); i++) {
1710 		if (mpi_handshake_recv_dword(sc, &dbuf[i]) != 0)
1711 			return (1);
1712 	}
1713 
1714 	/* if there's extra stuff to come off the ioc, discard it */
1715 	while (i++ < reply->msg_length) {
1716 		if (mpi_handshake_recv_dword(sc, &dummy) != 0)
1717 			return (1);
1718 		DNPRINTF(MPI_D_CMD, "%s: mpi_handshake_recv dummy read: "
1719 		    "0x%08x\n", DEVNAME(sc), dummy);
1720 	}
1721 
1722 	/* wait for the doorbell used bit to be reset and clear the intr */
1723 	if (mpi_wait_db_int(sc) != 0)
1724 		return (1);
1725 	mpi_write_intr(sc, 0);
1726 
1727 	return (0);
1728 }
1729 
1730 void
1731 mpi_empty_done(struct mpi_ccb *ccb)
1732 {
1733 	/* nothing to do */
1734 }
1735 
1736 int
1737 mpi_iocfacts(struct mpi_softc *sc)
1738 {
1739 	struct mpi_msg_iocfacts_request		ifq;
1740 	struct mpi_msg_iocfacts_reply		ifp;
1741 
1742 	DNPRINTF(MPI_D_MISC, "%s: mpi_iocfacts\n", DEVNAME(sc));
1743 
1744 	bzero(&ifq, sizeof(ifq));
1745 	bzero(&ifp, sizeof(ifp));
1746 
1747 	ifq.function = MPI_FUNCTION_IOC_FACTS;
1748 	ifq.chain_offset = 0;
1749 	ifq.msg_flags = 0;
1750 	ifq.msg_context = htole32(0xdeadbeef);
1751 
1752 	if (mpi_handshake_send(sc, &ifq, dwordsof(ifq)) != 0) {
1753 		DNPRINTF(MPI_D_MISC, "%s: mpi_iocfacts send failed\n",
1754 		    DEVNAME(sc));
1755 		return (1);
1756 	}
1757 
1758 	if (mpi_handshake_recv(sc, &ifp, dwordsof(ifp)) != 0) {
1759 		DNPRINTF(MPI_D_MISC, "%s: mpi_iocfacts recv failed\n",
1760 		    DEVNAME(sc));
1761 		return (1);
1762 	}
1763 
1764 	DNPRINTF(MPI_D_MISC, "%s:  func: 0x%02x len: %d msgver: %d.%d\n",
1765 	    DEVNAME(sc), ifp.function, ifp.msg_length,
1766 	    ifp.msg_version_maj, ifp.msg_version_min);
1767 	DNPRINTF(MPI_D_MISC, "%s:  msgflags: 0x%02x iocnumber: 0x%02x "
1768 	    "hdrver: %d.%d\n", DEVNAME(sc), ifp.msg_flags,
1769 	    ifp.ioc_number, ifp.header_version_maj,
1770 	    ifp.header_version_min);
1771 	DNPRINTF(MPI_D_MISC, "%s:  message context: 0x%08x\n", DEVNAME(sc),
1772 	    letoh32(ifp.msg_context));
1773 	DNPRINTF(MPI_D_MISC, "%s:  iocstatus: 0x%04x ioexcept: 0x%04x\n",
1774 	    DEVNAME(sc), letoh16(ifp.ioc_status),
1775 	    letoh16(ifp.ioc_exceptions));
1776 	DNPRINTF(MPI_D_MISC, "%s:  iocloginfo: 0x%08x\n", DEVNAME(sc),
1777 	    letoh32(ifp.ioc_loginfo));
1778 	DNPRINTF(MPI_D_MISC, "%s:  flags: 0x%02x blocksize: %d whoinit: 0x%02x "
1779 	    "maxchdepth: %d\n", DEVNAME(sc), ifp.flags,
1780 	    ifp.block_size, ifp.whoinit, ifp.max_chain_depth);
1781 	DNPRINTF(MPI_D_MISC, "%s:  reqfrsize: %d replyqdepth: %d\n",
1782 	    DEVNAME(sc), letoh16(ifp.request_frame_size),
1783 	    letoh16(ifp.reply_queue_depth));
1784 	DNPRINTF(MPI_D_MISC, "%s:  productid: 0x%04x\n", DEVNAME(sc),
1785 	    letoh16(ifp.product_id));
1786 	DNPRINTF(MPI_D_MISC, "%s:  hostmfahiaddr: 0x%08x\n", DEVNAME(sc),
1787 	    letoh32(ifp.current_host_mfa_hi_addr));
1788 	DNPRINTF(MPI_D_MISC, "%s:  event_state: 0x%02x number_of_ports: %d "
1789 	    "global_credits: %d\n",
1790 	    DEVNAME(sc), ifp.event_state, ifp.number_of_ports,
1791 	    letoh16(ifp.global_credits));
1792 	DNPRINTF(MPI_D_MISC, "%s:  sensebufhiaddr: 0x%08x\n", DEVNAME(sc),
1793 	    letoh32(ifp.current_sense_buffer_hi_addr));
1794 	DNPRINTF(MPI_D_MISC, "%s:  maxbus: %d maxdev: %d replyfrsize: %d\n",
1795 	    DEVNAME(sc), ifp.max_buses, ifp.max_devices,
1796 	    letoh16(ifp.current_reply_frame_size));
1797 	DNPRINTF(MPI_D_MISC, "%s:  fw_image_size: %d\n", DEVNAME(sc),
1798 	    letoh32(ifp.fw_image_size));
1799 	DNPRINTF(MPI_D_MISC, "%s:  ioc_capabilities: 0x%08x\n", DEVNAME(sc),
1800 	    letoh32(ifp.ioc_capabilities));
1801 	DNPRINTF(MPI_D_MISC, "%s:  fw_version: %d.%d fw_version_unit: 0x%02x "
1802 	    "fw_version_dev: 0x%02x\n", DEVNAME(sc),
1803 	    ifp.fw_version_maj, ifp.fw_version_min,
1804 	    ifp.fw_version_unit, ifp.fw_version_dev);
1805 	DNPRINTF(MPI_D_MISC, "%s:  hi_priority_queue_depth: 0x%04x\n",
1806 	    DEVNAME(sc), letoh16(ifp.hi_priority_queue_depth));
1807 	DNPRINTF(MPI_D_MISC, "%s:  host_page_buffer_sge: hdr: 0x%08x "
1808 	    "addr 0x%08x %08x\n", DEVNAME(sc),
1809 	    letoh32(ifp.host_page_buffer_sge.sg_hdr),
1810 	    letoh32(ifp.host_page_buffer_sge.sg_hi_addr),
1811 	    letoh32(ifp.host_page_buffer_sge.sg_lo_addr));
1812 
1813 	sc->sc_maxcmds = letoh16(ifp.global_credits);
1814 	sc->sc_maxchdepth = ifp.max_chain_depth;
1815 	sc->sc_ioc_number = ifp.ioc_number;
1816 	if (sc->sc_flags & MPI_F_VMWARE)
1817 		sc->sc_buswidth = 16;
1818 	else
1819 		sc->sc_buswidth =
1820 		    (ifp.max_devices == 0) ? 256 : ifp.max_devices;
1821 	if (ifp.flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
1822 		sc->sc_fw_len = letoh32(ifp.fw_image_size);
1823 
1824 	/*
1825 	 * you can fit sg elements on the end of the io cmd if they fit in the
1826 	 * request frame size.
1827 	 */
1828 	sc->sc_first_sgl_len = ((letoh16(ifp.request_frame_size) * 4) -
1829 	    sizeof(struct mpi_msg_scsi_io)) / sizeof(struct mpi_sge);
1830 	DNPRINTF(MPI_D_MISC, "%s:   first sgl len: %d\n", DEVNAME(sc),
1831 	    sc->sc_first_sgl_len);
1832 
1833 	sc->sc_chain_len = (letoh16(ifp.request_frame_size) * 4) /
1834 	    sizeof(struct mpi_sge);
1835 	DNPRINTF(MPI_D_MISC, "%s:   chain len: %d\n", DEVNAME(sc),
1836 	    sc->sc_chain_len);
1837 
1838 	/* the sgl tailing the io cmd loses an entry to the chain element. */
1839 	sc->sc_max_sgl_len = MPI_MAX_SGL - 1;
1840 	/* the sgl chains lose an entry for each chain element */
1841 	sc->sc_max_sgl_len -= (MPI_MAX_SGL - sc->sc_first_sgl_len) /
1842 	    sc->sc_chain_len;
1843 	DNPRINTF(MPI_D_MISC, "%s:   max sgl len: %d\n", DEVNAME(sc),
1844 	    sc->sc_max_sgl_len);
1845 
1846 	/* XXX we're ignoring the max chain depth */
1847 
1848 	return (0);
1849 }
1850 
1851 int
1852 mpi_iocinit(struct mpi_softc *sc)
1853 {
1854 	struct mpi_msg_iocinit_request		iiq;
1855 	struct mpi_msg_iocinit_reply		iip;
1856 	u_int32_t				hi_addr;
1857 
1858 	DNPRINTF(MPI_D_MISC, "%s: mpi_iocinit\n", DEVNAME(sc));
1859 
1860 	bzero(&iiq, sizeof(iiq));
1861 	bzero(&iip, sizeof(iip));
1862 
1863 	iiq.function = MPI_FUNCTION_IOC_INIT;
1864 	iiq.whoinit = MPI_WHOINIT_HOST_DRIVER;
1865 
1866 	iiq.max_devices = (sc->sc_buswidth == 256) ? 0 : sc->sc_buswidth;
1867 	iiq.max_buses = 1;
1868 
1869 	iiq.msg_context = htole32(0xd00fd00f);
1870 
1871 	iiq.reply_frame_size = htole16(MPI_REPLY_SIZE);
1872 
1873 	hi_addr = (u_int32_t)((u_int64_t)MPI_DMA_DVA(sc->sc_requests) >> 32);
1874 	iiq.host_mfa_hi_addr = htole32(hi_addr);
1875 	iiq.sense_buffer_hi_addr = htole32(hi_addr);
1876 
1877 	hi_addr = (u_int32_t)((u_int64_t)MPI_DMA_DVA(sc->sc_replies) >> 32);
1878 	iiq.reply_fifo_host_signalling_addr = htole32(hi_addr);
1879 
1880 	iiq.msg_version_maj = 0x01;
1881 	iiq.msg_version_min = 0x02;
1882 
1883 	iiq.hdr_version_unit = 0x0d;
1884 	iiq.hdr_version_dev = 0x00;
1885 
1886 	if (mpi_handshake_send(sc, &iiq, dwordsof(iiq)) != 0) {
1887 		DNPRINTF(MPI_D_MISC, "%s: mpi_iocinit send failed\n",
1888 		    DEVNAME(sc));
1889 		return (1);
1890 	}
1891 
1892 	if (mpi_handshake_recv(sc, &iip, dwordsof(iip)) != 0) {
1893 		DNPRINTF(MPI_D_MISC, "%s: mpi_iocinit recv failed\n",
1894 		    DEVNAME(sc));
1895 		return (1);
1896 	}
1897 
1898 	DNPRINTF(MPI_D_MISC, "%s:  function: 0x%02x msg_length: %d "
1899 	    "whoinit: 0x%02x\n", DEVNAME(sc), iip.function,
1900 	    iip.msg_length, iip.whoinit);
1901 	DNPRINTF(MPI_D_MISC, "%s:  msg_flags: 0x%02x max_buses: %d "
1902 	    "max_devices: %d flags: 0x%02x\n", DEVNAME(sc), iip.msg_flags,
1903 	    iip.max_buses, iip.max_devices, iip.flags);
1904 	DNPRINTF(MPI_D_MISC, "%s:  msg_context: 0x%08x\n", DEVNAME(sc),
1905 	    letoh32(iip.msg_context));
1906 	DNPRINTF(MPI_D_MISC, "%s:  ioc_status: 0x%04x\n", DEVNAME(sc),
1907 	    letoh16(iip.ioc_status));
1908 	DNPRINTF(MPI_D_MISC, "%s:  ioc_loginfo: 0x%08x\n", DEVNAME(sc),
1909 	    letoh32(iip.ioc_loginfo));
1910 
1911 	return (0);
1912 }
1913 
1914 int
1915 mpi_portfacts(struct mpi_softc *sc)
1916 {
1917 	struct mpi_ccb				*ccb;
1918 	struct mpi_msg_portfacts_request	*pfq;
1919 	volatile struct mpi_msg_portfacts_reply	*pfp;
1920 	int					s, rv = 1;
1921 
1922 	DNPRINTF(MPI_D_MISC, "%s: mpi_portfacts\n", DEVNAME(sc));
1923 
1924 	s = splbio();
1925 	ccb = mpi_get_ccb(sc);
1926 	splx(s);
1927 	if (ccb == NULL) {
1928 		DNPRINTF(MPI_D_MISC, "%s: mpi_portfacts ccb_get\n",
1929 		    DEVNAME(sc));
1930 		return (rv);
1931 	}
1932 
1933 	ccb->ccb_done = mpi_empty_done;
1934 	pfq = ccb->ccb_cmd;
1935 
1936 	pfq->function = MPI_FUNCTION_PORT_FACTS;
1937 	pfq->chain_offset = 0;
1938 	pfq->msg_flags = 0;
1939 	pfq->port_number = 0;
1940 	pfq->msg_context = htole32(ccb->ccb_id);
1941 
1942 	if (mpi_poll(sc, ccb, 50000) != 0) {
1943 		DNPRINTF(MPI_D_MISC, "%s: mpi_portfacts poll\n", DEVNAME(sc));
1944 		goto err;
1945 	}
1946 
1947 	pfp = ccb->ccb_reply;
1948 	if (pfp == NULL) {
1949 		DNPRINTF(MPI_D_MISC, "%s: empty portfacts reply\n",
1950 		    DEVNAME(sc));
1951 		goto err;
1952 	}
1953 
1954 	DNPRINTF(MPI_D_MISC, "%s:  function: 0x%02x msg_length: %d\n",
1955 	    DEVNAME(sc), pfp->function, pfp->msg_length);
1956 	DNPRINTF(MPI_D_MISC, "%s:  msg_flags: 0x%02x port_number: %d\n",
1957 	    DEVNAME(sc), pfp->msg_flags, pfp->port_number);
1958 	DNPRINTF(MPI_D_MISC, "%s:  msg_context: 0x%08x\n", DEVNAME(sc),
1959 	    letoh32(pfp->msg_context));
1960 	DNPRINTF(MPI_D_MISC, "%s:  ioc_status: 0x%04x\n", DEVNAME(sc),
1961 	    letoh16(pfp->ioc_status));
1962 	DNPRINTF(MPI_D_MISC, "%s:  ioc_loginfo: 0x%08x\n", DEVNAME(sc),
1963 	    letoh32(pfp->ioc_loginfo));
1964 	DNPRINTF(MPI_D_MISC, "%s:  max_devices: %d port_type: 0x%02x\n",
1965 	    DEVNAME(sc), letoh16(pfp->max_devices), pfp->port_type);
1966 	DNPRINTF(MPI_D_MISC, "%s:  protocol_flags: 0x%04x port_scsi_id: %d\n",
1967 	    DEVNAME(sc), letoh16(pfp->protocol_flags),
1968 	    letoh16(pfp->port_scsi_id));
1969 	DNPRINTF(MPI_D_MISC, "%s:  max_persistent_ids: %d "
1970 	    "max_posted_cmd_buffers: %d\n", DEVNAME(sc),
1971 	    letoh16(pfp->max_persistent_ids),
1972 	    letoh16(pfp->max_posted_cmd_buffers));
1973 	DNPRINTF(MPI_D_MISC, "%s:  max_lan_buckets: %d\n", DEVNAME(sc),
1974 	    letoh16(pfp->max_lan_buckets));
1975 
1976 	sc->sc_porttype = pfp->port_type;
1977 	sc->sc_target = letoh16(pfp->port_scsi_id);
1978 
1979 	mpi_push_reply(sc, ccb->ccb_reply_dva);
1980 	rv = 0;
1981 err:
1982 	mpi_put_ccb(sc, ccb);
1983 
1984 	return (rv);
1985 }
1986 
1987 int
1988 mpi_eventnotify(struct mpi_softc *sc)
1989 {
1990 	struct mpi_ccb				*ccb;
1991 	struct mpi_msg_event_request		*enq;
1992 	int					s;
1993 
1994 	s = splbio();
1995 	ccb = mpi_get_ccb(sc);
1996 	splx(s);
1997 	if (ccb == NULL) {
1998 		DNPRINTF(MPI_D_MISC, "%s: mpi_eventnotify ccb_get\n",
1999 		    DEVNAME(sc));
2000 		return (1);
2001 	}
2002 
2003 	ccb->ccb_done = mpi_eventnotify_done;
2004 	enq = ccb->ccb_cmd;
2005 
2006 	enq->function = MPI_FUNCTION_EVENT_NOTIFICATION;
2007 	enq->chain_offset = 0;
2008 	enq->ev_switch = 1;
2009 	enq->msg_context = htole32(ccb->ccb_id);
2010 
2011 	mpi_start(sc, ccb);
2012 
2013 	return (0);
2014 }
2015 
2016 void
2017 mpi_eventnotify_done(struct mpi_ccb *ccb)
2018 {
2019 	struct mpi_softc			*sc = ccb->ccb_sc;
2020 	struct mpi_msg_event_reply		*enp = ccb->ccb_reply;
2021 	u_int32_t				*data;
2022 	int					i;
2023 
2024 	printf("%s: %s\n", DEVNAME(sc), __func__);
2025 
2026 	printf("%s:  function: 0x%02x msg_length: %d data_length: %d\n",
2027 	    DEVNAME(sc), enp->function, enp->msg_length,
2028 	    letoh16(enp->data_length));
2029 
2030 	printf("%s:  ack_required: %d msg_flags 0x%02x\n", DEVNAME(sc),
2031 	    enp->msg_flags, enp->msg_flags);
2032 
2033 	printf("%s:  msg_context: 0x%08x\n", DEVNAME(sc),
2034 	    letoh32(enp->msg_context));
2035 
2036 	printf("%s:  ioc_status: 0x%04x\n", DEVNAME(sc),
2037 	    letoh16(enp->ioc_status));
2038 
2039 	printf("%s:  ioc_loginfo: 0x%08x\n", DEVNAME(sc),
2040 	    letoh32(enp->ioc_loginfo));
2041 
2042 	data = ccb->ccb_reply;
2043 	data += dwordsof(struct mpi_msg_event_reply);
2044 	for (i = 0; i < letoh16(enp->data_length); i++) {
2045 		printf("%s:  data[%d]: 0x%08x\n", DEVNAME(sc), i, data[i]);
2046 	}
2047 }
2048 
2049 int
2050 mpi_portenable(struct mpi_softc *sc)
2051 {
2052 	struct mpi_ccb				*ccb;
2053 	struct mpi_msg_portenable_request	*peq;
2054 	struct mpi_msg_portenable_repy		*pep;
2055 	int					s;
2056 
2057 	DNPRINTF(MPI_D_MISC, "%s: mpi_portenable\n", DEVNAME(sc));
2058 
2059 	s = splbio();
2060 	ccb = mpi_get_ccb(sc);
2061 	splx(s);
2062 	if (ccb == NULL) {
2063 		DNPRINTF(MPI_D_MISC, "%s: mpi_portenable ccb_get\n",
2064 		    DEVNAME(sc));
2065 		return (1);
2066 	}
2067 
2068 	ccb->ccb_done = mpi_empty_done;
2069 	peq = ccb->ccb_cmd;
2070 
2071 	peq->function = MPI_FUNCTION_PORT_ENABLE;
2072 	peq->port_number = 0;
2073 	peq->msg_context = htole32(ccb->ccb_id);
2074 
2075 	if (mpi_poll(sc, ccb, 50000) != 0) {
2076 		DNPRINTF(MPI_D_MISC, "%s: mpi_portenable poll\n", DEVNAME(sc));
2077 		return (1);
2078 	}
2079 
2080 	pep = ccb->ccb_reply;
2081 	if (pep == NULL) {
2082 		DNPRINTF(MPI_D_MISC, "%s: empty portenable reply\n",
2083 		    DEVNAME(sc));
2084 		return (1);
2085 	}
2086 
2087 	mpi_push_reply(sc, ccb->ccb_reply_dva);
2088 	mpi_put_ccb(sc, ccb);
2089 
2090 	return (0);
2091 }
2092 
2093 int
2094 mpi_fwupload(struct mpi_softc *sc)
2095 {
2096 	struct mpi_ccb				*ccb;
2097 	struct {
2098 		struct mpi_msg_fwupload_request		req;
2099 		struct mpi_sge				sge;
2100 	} __packed				*bundle;
2101 	struct mpi_msg_fwupload_reply		*upp;
2102 	u_int64_t				addr;
2103 	int					s;
2104 	int					rv = 0;
2105 
2106 	if (sc->sc_fw_len == 0)
2107 		return (0);
2108 
2109 	DNPRINTF(MPI_D_MISC, "%s: mpi_fwupload\n", DEVNAME(sc));
2110 
2111 	sc->sc_fw = mpi_dmamem_alloc(sc, sc->sc_fw_len);
2112 	if (sc->sc_fw == NULL) {
2113 		DNPRINTF(MPI_D_MISC, "%s: mpi_fwupload unable to allocate %d\n",
2114 		    DEVNAME(sc), sc->sc_fw_len);
2115 		return (1);
2116 	}
2117 
2118 	s = splbio();
2119 	ccb = mpi_get_ccb(sc);
2120 	splx(s);
2121 	if (ccb == NULL) {
2122 		DNPRINTF(MPI_D_MISC, "%s: mpi_fwupload ccb_get\n",
2123 		    DEVNAME(sc));
2124 		goto err;
2125 	}
2126 
2127 	ccb->ccb_done = mpi_empty_done;
2128 	bundle = ccb->ccb_cmd;
2129 
2130 	bundle->req.function = MPI_FUNCTION_FW_UPLOAD;
2131 	bundle->req.msg_context = htole32(ccb->ccb_id);
2132 
2133 	bundle->req.image_type = MPI_FWUPLOAD_IMAGETYPE_IOC_FW;
2134 
2135 	bundle->req.tce.details_length = 12;
2136 	bundle->req.tce.image_size = htole32(sc->sc_fw_len);
2137 
2138 	bundle->sge.sg_hdr = htole32(MPI_SGE_FL_TYPE_SIMPLE |
2139 	    MPI_SGE_FL_SIZE_64 | MPI_SGE_FL_LAST | MPI_SGE_FL_EOB |
2140 	    MPI_SGE_FL_EOL | (u_int32_t)sc->sc_fw_len);
2141 	addr = MPI_DMA_DVA(sc->sc_fw);
2142 	bundle->sge.sg_hi_addr = htole32((u_int32_t)(addr >> 32));
2143 	bundle->sge.sg_lo_addr = htole32((u_int32_t)addr);
2144 
2145 	if (mpi_poll(sc, ccb, 50000) != 0) {
2146 		DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_header poll\n", DEVNAME(sc));
2147 		goto err;
2148 	}
2149 
2150 	upp = ccb->ccb_reply;
2151 	if (upp == NULL)
2152 		panic("%s: unable to do fw upload\n", DEVNAME(sc));
2153 
2154 	if (letoh16(upp->ioc_status) != MPI_IOCSTATUS_SUCCESS)
2155 		rv = 1;
2156 
2157 	mpi_push_reply(sc, ccb->ccb_reply_dva);
2158 	mpi_put_ccb(sc, ccb);
2159 
2160 	return (rv);
2161 
2162 err:
2163 	mpi_dmamem_free(sc, sc->sc_fw);
2164 	return (1);
2165 }
2166 
2167 void
2168 mpi_get_raid(struct mpi_softc *sc)
2169 {
2170 	struct mpi_cfg_hdr		hdr;
2171 	struct mpi_cfg_ioc_pg2		*vol_page;
2172 	struct mpi_cfg_raid_vol		*vol_list, *vol;
2173 	size_t				pagelen;
2174 	u_int32_t			capabilities;
2175 	struct scsi_link		*link;
2176 	int				i;
2177 
2178 	DNPRINTF(MPI_D_RAID, "%s: mpi_get_raid\n", DEVNAME(sc));
2179 
2180 	if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_IOC, 2, 0, &hdr) != 0) {
2181 		DNPRINTF(MPI_D_RAID, "%s: mpi_get_raid unable to fetch header"
2182 		    "for IOC page 2\n", DEVNAME(sc));
2183 		return;
2184 	}
2185 
2186 	pagelen = hdr.page_length * 4; /* dwords to bytes */
2187 	vol_page = malloc(pagelen, M_TEMP, M_WAITOK);
2188 	if (vol_page == NULL) {
2189 		DNPRINTF(MPI_D_RAID, "%s: mpi_get_raid unable to allocate "
2190 		    "space for ioc config page 2\n", DEVNAME(sc));
2191 		return;
2192 	}
2193 	vol_list = (struct mpi_cfg_raid_vol *)(vol_page + 1);
2194 
2195 	if (mpi_cfg_page(sc, 0, &hdr, 1, vol_page, pagelen) != 0) {
2196 		DNPRINTF(MPI_D_RAID, "%s: mpi_get_raid unable to fetch IOC "
2197 		    "page 2\n", DEVNAME(sc));
2198 		goto out;
2199 	}
2200 
2201 	capabilities = letoh32(vol_page->capabilities);
2202 
2203 	DNPRINTF(MPI_D_RAID, "%s:  capabilities: 0x08%x\n", DEVNAME(sc),
2204 	    letoh32(vol_page->capabilities));
2205 	DNPRINTF(MPI_D_RAID, "%s:  active_vols: %d max_vols: %d "
2206 	    "active_physdisks: %d max_physdisks: %d\n", DEVNAME(sc),
2207 	    vol_page->active_vols, vol_page->max_vols,
2208 	    vol_page->active_physdisks, vol_page->max_physdisks);
2209 
2210 	/* don't walk list if there are no RAID capability */
2211 	if (capabilities == 0xdeadbeef) {
2212 		printf("%s: deadbeef in raid configuration\n", DEVNAME(sc));
2213 		goto out;
2214 	}
2215 
2216 	if ((capabilities & MPI_CFG_IOC_2_CAPABILITIES_RAID) == 0 ||
2217 	    (vol_page->active_vols == 0))
2218 		goto out;
2219 
2220 	sc->sc_flags |= MPI_F_RAID;
2221 
2222 	for (i = 0; i < vol_page->active_vols; i++) {
2223 		vol = &vol_list[i];
2224 
2225 		DNPRINTF(MPI_D_RAID, "%s:   id: %d bus: %d ioc: %d pg: %d\n",
2226 		    DEVNAME(sc), vol->vol_id, vol->vol_bus, vol->vol_ioc,
2227 		    vol->vol_page);
2228 		DNPRINTF(MPI_D_RAID, "%s:   type: 0x%02x flags: 0x%02x\n",
2229 		    DEVNAME(sc), vol->vol_type, vol->flags);
2230 
2231 		if (vol->vol_ioc != sc->sc_ioc_number || vol->vol_bus != 0)
2232 			continue;
2233 
2234 		link = sc->sc_scsibus->sc_link[vol->vol_id][0];
2235 		if (link == NULL)
2236 			continue;
2237 
2238 		link->flags |= SDEV_VIRTUAL;
2239 	}
2240 
2241 out:
2242 	free(vol_page, M_TEMP);
2243 }
2244 
2245 int
2246 mpi_cfg_header(struct mpi_softc *sc, u_int8_t type, u_int8_t number,
2247     u_int32_t address, struct mpi_cfg_hdr *hdr)
2248 {
2249 	struct mpi_ccb				*ccb;
2250 	struct mpi_msg_config_request		*cq;
2251 	struct mpi_msg_config_reply		*cp;
2252 	int					rv = 0;
2253 	int					s;
2254 
2255 	DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_header type: %#x number: %x "
2256 	    "address: %d\n", DEVNAME(sc), type, number, address);
2257 
2258 	s = splbio();
2259 	ccb = mpi_get_ccb(sc);
2260 	splx(s);
2261 	if (ccb == NULL) {
2262 		DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_header ccb_get\n",
2263 		    DEVNAME(sc));
2264 		return (1);
2265 	}
2266 
2267 	ccb->ccb_done = mpi_empty_done;
2268 	cq = ccb->ccb_cmd;
2269 
2270 	cq->function = MPI_FUNCTION_CONFIG;
2271 	cq->msg_context = htole32(ccb->ccb_id);
2272 
2273 	cq->action = MPI_CONFIG_REQ_ACTION_PAGE_HEADER;
2274 
2275 	cq->config_header.page_number = number;
2276 	cq->config_header.page_type = type;
2277 	cq->page_address = htole32(address);
2278 	cq->page_buffer.sg_hdr = htole32(MPI_SGE_FL_TYPE_SIMPLE |
2279 	    MPI_SGE_FL_LAST | MPI_SGE_FL_EOB | MPI_SGE_FL_EOL);
2280 
2281 	if (mpi_poll(sc, ccb, 50000) != 0) {
2282 		DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_header poll\n", DEVNAME(sc));
2283 		return (1);
2284 	}
2285 
2286 	cp = ccb->ccb_reply;
2287 	if (cp == NULL)
2288 		panic("%s: unable to fetch config header\n", DEVNAME(sc));
2289 
2290 	DNPRINTF(MPI_D_MISC, "%s:  action: 0x%02x msg_length: %d function: "
2291 	    "0x%02x\n", DEVNAME(sc), cp->action, cp->msg_length, cp->function);
2292 	DNPRINTF(MPI_D_MISC, "%s:  ext_page_length: %d ext_page_type: 0x%02x "
2293 	    "msg_flags: 0x%02x\n", DEVNAME(sc),
2294 	    letoh16(cp->ext_page_length), cp->ext_page_type,
2295 	    cp->msg_flags);
2296 	DNPRINTF(MPI_D_MISC, "%s:  msg_context: 0x%08x\n", DEVNAME(sc),
2297 	    letoh32(cp->msg_context));
2298 	DNPRINTF(MPI_D_MISC, "%s:  ioc_status: 0x%04x\n", DEVNAME(sc),
2299 	    letoh16(cp->ioc_status));
2300 	DNPRINTF(MPI_D_MISC, "%s:  ioc_loginfo: 0x%08x\n", DEVNAME(sc),
2301 	    letoh32(cp->ioc_loginfo));
2302 	DNPRINTF(MPI_D_MISC, "%s:  page_version: 0x%02x page_length: %d "
2303 	    "page_number: 0x%02x page_type: 0x%02x\n", DEVNAME(sc),
2304 	    cp->config_header.page_version,
2305 	    cp->config_header.page_length,
2306 	    cp->config_header.page_number,
2307 	    cp->config_header.page_type);
2308 
2309 	if (letoh16(cp->ioc_status) != MPI_IOCSTATUS_SUCCESS)
2310 		rv = 1;
2311 	else
2312 		*hdr = cp->config_header;
2313 
2314 	mpi_push_reply(sc, ccb->ccb_reply_dva);
2315 	mpi_put_ccb(sc, ccb);
2316 
2317 	return (rv);
2318 }
2319 
2320 int
2321 mpi_cfg_page(struct mpi_softc *sc, u_int32_t address, struct mpi_cfg_hdr *hdr,
2322     int read, void *page, size_t len)
2323 {
2324 	struct mpi_ccb				*ccb;
2325 	struct mpi_msg_config_request		*cq;
2326 	struct mpi_msg_config_reply		*cp;
2327 	u_int64_t				dva;
2328 	char					*kva;
2329 	int					rv = 0;
2330 	int					s;
2331 
2332 	DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_page address: %d read: %d type: %x\n",
2333 	    DEVNAME(sc), address, read, hdr->page_type);
2334 
2335 	if (len > MPI_REQUEST_SIZE - sizeof(struct mpi_msg_config_request) ||
2336 	    len < hdr->page_length * 4)
2337 		return (1);
2338 
2339 	s = splbio();
2340 	ccb = mpi_get_ccb(sc);
2341 	splx(s);
2342 	if (ccb == NULL) {
2343 		DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_page ccb_get\n", DEVNAME(sc));
2344 		return (1);
2345 	}
2346 
2347 	ccb->ccb_done = mpi_empty_done;
2348 	cq = ccb->ccb_cmd;
2349 
2350 	cq->function = MPI_FUNCTION_CONFIG;
2351 	cq->msg_context = htole32(ccb->ccb_id);
2352 
2353 	cq->action = (read ? MPI_CONFIG_REQ_ACTION_PAGE_READ_CURRENT :
2354 	    MPI_CONFIG_REQ_ACTION_PAGE_WRITE_CURRENT);
2355 
2356 	cq->config_header = *hdr;
2357 	cq->config_header.page_type &= MPI_CONFIG_REQ_PAGE_TYPE_MASK;
2358 	cq->page_address = htole32(address);
2359 	cq->page_buffer.sg_hdr = htole32(MPI_SGE_FL_TYPE_SIMPLE |
2360 	    MPI_SGE_FL_LAST | MPI_SGE_FL_EOB | MPI_SGE_FL_EOL |
2361 	    (hdr->page_length * 4) |
2362 	    (read ? MPI_SGE_FL_DIR_IN : MPI_SGE_FL_DIR_OUT));
2363 
2364 	/* bounce the page via the request space to avoid more bus_dma games */
2365 	dva = ccb->ccb_cmd_dva + sizeof(struct mpi_msg_config_request);
2366 
2367 	cq->page_buffer.sg_hi_addr = htole32((u_int32_t)(dva >> 32));
2368 	cq->page_buffer.sg_lo_addr = htole32((u_int32_t)dva);
2369 
2370 	kva = ccb->ccb_cmd;
2371 	kva += sizeof(struct mpi_msg_config_request);
2372 	if (!read)
2373 		bcopy(page, kva, len);
2374 
2375 	if (mpi_poll(sc, ccb, 50000) != 0) {
2376 		DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_page poll\n", DEVNAME(sc));
2377 		return (1);
2378 	}
2379 
2380 	cp = ccb->ccb_reply;
2381 	if (cp == NULL) {
2382 		mpi_put_ccb(sc, ccb);
2383 		return (1);
2384 	}
2385 
2386 	DNPRINTF(MPI_D_MISC, "%s:  action: 0x%02x msg_length: %d function: "
2387 	    "0x%02x\n", DEVNAME(sc), cp->action, cp->msg_length, cp->function);
2388 	DNPRINTF(MPI_D_MISC, "%s:  ext_page_length: %d ext_page_type: 0x%02x "
2389 	    "msg_flags: 0x%02x\n", DEVNAME(sc),
2390 	    letoh16(cp->ext_page_length), cp->ext_page_type,
2391 	    cp->msg_flags);
2392 	DNPRINTF(MPI_D_MISC, "%s:  msg_context: 0x%08x\n", DEVNAME(sc),
2393 	    letoh32(cp->msg_context));
2394 	DNPRINTF(MPI_D_MISC, "%s:  ioc_status: 0x%04x\n", DEVNAME(sc),
2395 	    letoh16(cp->ioc_status));
2396 	DNPRINTF(MPI_D_MISC, "%s:  ioc_loginfo: 0x%08x\n", DEVNAME(sc),
2397 	    letoh32(cp->ioc_loginfo));
2398 	DNPRINTF(MPI_D_MISC, "%s:  page_version: 0x%02x page_length: %d "
2399 	    "page_number: 0x%02x page_type: 0x%02x\n", DEVNAME(sc),
2400 	    cp->config_header.page_version,
2401 	    cp->config_header.page_length,
2402 	    cp->config_header.page_number,
2403 	    cp->config_header.page_type);
2404 
2405 	if (letoh16(cp->ioc_status) != MPI_IOCSTATUS_SUCCESS)
2406 		rv = 1;
2407 	else if (read)
2408 		bcopy(kva, page, len);
2409 
2410 	mpi_push_reply(sc, ccb->ccb_reply_dva);
2411 	mpi_put_ccb(sc, ccb);
2412 
2413 	return (rv);
2414 }
2415