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