xref: /openbsd-src/sys/dev/ic/mpi.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
1 /*	$OpenBSD: mpi.c,v 1.110 2009/03/06 01:28:44 krw 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 "bio.h"
21 
22 #include <sys/param.h>
23 #include <sys/systm.h>
24 #include <sys/buf.h>
25 #include <sys/device.h>
26 #include <sys/ioctl.h>
27 #include <sys/proc.h>
28 #include <sys/malloc.h>
29 #include <sys/kernel.h>
30 #include <sys/rwlock.h>
31 #include <sys/sensors.h>
32 
33 #include <machine/bus.h>
34 
35 #include <scsi/scsi_all.h>
36 #include <scsi/scsiconf.h>
37 
38 #include <dev/biovar.h>
39 #include <dev/ic/mpireg.h>
40 #include <dev/ic/mpivar.h>
41 
42 #ifdef MPI_DEBUG
43 uint32_t	mpi_debug = 0
44 /*		    | MPI_D_CMD */
45 /*		    | MPI_D_INTR */
46 /*		    | MPI_D_MISC */
47 /*		    | MPI_D_DMA */
48 /*		    | MPI_D_IOCTL */
49 /*		    | MPI_D_RW */
50 /*		    | MPI_D_MEM */
51 /*		    | MPI_D_CCB */
52 /*		    | MPI_D_PPR */
53 /*		    | MPI_D_RAID */
54 /*		    | MPI_D_EVT */
55 		;
56 #endif
57 
58 struct cfdriver mpi_cd = {
59 	NULL,
60 	"mpi",
61 	DV_DULL
62 };
63 
64 int			mpi_scsi_cmd(struct scsi_xfer *);
65 void			mpi_scsi_cmd_done(struct mpi_ccb *);
66 void			mpi_minphys(struct buf *bp, struct scsi_link *sl);
67 int			mpi_scsi_probe(struct scsi_link *);
68 int			mpi_scsi_ioctl(struct scsi_link *, u_long, caddr_t,
69 			    int, struct proc *);
70 
71 struct scsi_adapter mpi_switch = {
72 	mpi_scsi_cmd,
73 	mpi_minphys,
74 	mpi_scsi_probe,
75 	NULL,
76 	mpi_scsi_ioctl
77 };
78 
79 struct scsi_device mpi_dev = {
80 	NULL,
81 	NULL,
82 	NULL,
83 	NULL
84 };
85 
86 struct mpi_dmamem	*mpi_dmamem_alloc(struct mpi_softc *, size_t);
87 void			mpi_dmamem_free(struct mpi_softc *,
88 			    struct mpi_dmamem *);
89 int			mpi_alloc_ccbs(struct mpi_softc *);
90 struct mpi_ccb		*mpi_get_ccb(struct mpi_softc *);
91 void			mpi_put_ccb(struct mpi_softc *, struct mpi_ccb *);
92 int			mpi_alloc_replies(struct mpi_softc *);
93 void			mpi_push_replies(struct mpi_softc *);
94 
95 void			mpi_start(struct mpi_softc *, struct mpi_ccb *);
96 int			mpi_complete(struct mpi_softc *, struct mpi_ccb *, int);
97 int			mpi_poll(struct mpi_softc *, struct mpi_ccb *, int);
98 int			mpi_reply(struct mpi_softc *, u_int32_t);
99 
100 int			mpi_cfg_spi_port(struct mpi_softc *);
101 void			mpi_squash_ppr(struct mpi_softc *);
102 void			mpi_run_ppr(struct mpi_softc *);
103 int			mpi_ppr(struct mpi_softc *, struct scsi_link *,
104 			    struct mpi_cfg_raid_physdisk *, int, int, int);
105 int			mpi_inq(struct mpi_softc *, u_int16_t, int);
106 
107 void			mpi_timeout_xs(void *);
108 int			mpi_load_xs(struct mpi_ccb *);
109 
110 u_int32_t		mpi_read(struct mpi_softc *, bus_size_t);
111 void			mpi_write(struct mpi_softc *, bus_size_t, u_int32_t);
112 int			mpi_wait_eq(struct mpi_softc *, bus_size_t, u_int32_t,
113 			    u_int32_t);
114 int			mpi_wait_ne(struct mpi_softc *, bus_size_t, u_int32_t,
115 			    u_int32_t);
116 
117 int			mpi_init(struct mpi_softc *);
118 int			mpi_reset_soft(struct mpi_softc *);
119 int			mpi_reset_hard(struct mpi_softc *);
120 
121 int			mpi_handshake_send(struct mpi_softc *, void *, size_t);
122 int			mpi_handshake_recv_dword(struct mpi_softc *,
123 			    u_int32_t *);
124 int			mpi_handshake_recv(struct mpi_softc *, void *, size_t);
125 
126 void			mpi_empty_done(struct mpi_ccb *);
127 
128 int			mpi_iocinit(struct mpi_softc *);
129 int			mpi_iocfacts(struct mpi_softc *);
130 int			mpi_portfacts(struct mpi_softc *);
131 int			mpi_portenable(struct mpi_softc *);
132 void			mpi_get_raid(struct mpi_softc *);
133 int			mpi_fwupload(struct mpi_softc *);
134 
135 int			mpi_eventnotify(struct mpi_softc *);
136 void			mpi_eventnotify_done(struct mpi_ccb *);
137 void			mpi_eventack(struct mpi_softc *,
138 			    struct mpi_msg_event_reply *);
139 void			mpi_eventack_done(struct mpi_ccb *);
140 void			mpi_evt_sas(void *, void *);
141 
142 int			mpi_req_cfg_header(struct mpi_softc *, u_int8_t,
143 			    u_int8_t, u_int32_t, int, void *);
144 int			mpi_req_cfg_page(struct mpi_softc *, u_int32_t, int,
145 			    void *, int, void *, size_t);
146 
147 #if NBIO > 0
148 int		mpi_bio_get_pg0_raid(struct mpi_softc *, int);
149 int		mpi_ioctl(struct device *, u_long, caddr_t);
150 int		mpi_ioctl_inq(struct mpi_softc *, struct bioc_inq *);
151 int		mpi_ioctl_vol(struct mpi_softc *, struct bioc_vol *);
152 int		mpi_ioctl_disk(struct mpi_softc *, struct bioc_disk *);
153 int		mpi_ioctl_setstate(struct mpi_softc *, struct bioc_setstate *);
154 #ifndef SMALL_KERNEL
155 int		mpi_create_sensors(struct mpi_softc *);
156 void		mpi_refresh_sensors(void *);
157 #endif /* SMALL_KERNEL */
158 #endif /* NBIO > 0 */
159 
160 #define DEVNAME(s)		((s)->sc_dev.dv_xname)
161 
162 #define	dwordsof(s)		(sizeof(s) / sizeof(u_int32_t))
163 
164 #define mpi_read_db(s)		mpi_read((s), MPI_DOORBELL)
165 #define mpi_write_db(s, v)	mpi_write((s), MPI_DOORBELL, (v))
166 #define mpi_read_intr(s)	mpi_read((s), MPI_INTR_STATUS)
167 #define mpi_write_intr(s, v)	mpi_write((s), MPI_INTR_STATUS, (v))
168 #define mpi_pop_reply(s)	mpi_read((s), MPI_REPLY_QUEUE)
169 #define mpi_push_reply(s, v)	mpi_write((s), MPI_REPLY_QUEUE, (v))
170 
171 #define mpi_wait_db_int(s)	mpi_wait_ne((s), MPI_INTR_STATUS, \
172 				    MPI_INTR_STATUS_DOORBELL, 0)
173 #define mpi_wait_db_ack(s)	mpi_wait_eq((s), MPI_INTR_STATUS, \
174 				    MPI_INTR_STATUS_IOCDOORBELL, 0)
175 
176 #define mpi_cfg_header(_s, _t, _n, _a, _h) \
177 	mpi_req_cfg_header((_s), (_t), (_n), (_a), 0, (_h))
178 #define mpi_ecfg_header(_s, _t, _n, _a, _h) \
179 	mpi_req_cfg_header((_s), (_t), (_n), (_a), 1, (_h))
180 
181 #define mpi_cfg_page(_s, _a, _h, _r, _p, _l) \
182 	mpi_req_cfg_page((_s), (_a), 0, (_h), (_r), (_p), (_l))
183 #define mpi_ecfg_page(_s, _a, _h, _r, _p, _l) \
184 	mpi_req_cfg_page((_s), (_a), 1, (_h), (_r), (_p), (_l))
185 
186 int
187 mpi_attach(struct mpi_softc *sc)
188 {
189 	struct scsibus_attach_args	saa;
190 	struct mpi_ccb			*ccb;
191 
192 	printf("\n");
193 
194 	/* disable interrupts */
195 	mpi_write(sc, MPI_INTR_MASK,
196 	    MPI_INTR_MASK_REPLY | MPI_INTR_MASK_DOORBELL);
197 
198 	if (mpi_init(sc) != 0) {
199 		printf("%s: unable to initialise\n", DEVNAME(sc));
200 		return (1);
201 	}
202 
203 	if (mpi_iocfacts(sc) != 0) {
204 		printf("%s: unable to get iocfacts\n", DEVNAME(sc));
205 		return (1);
206 	}
207 
208 	if (mpi_alloc_ccbs(sc) != 0) {
209 		/* error already printed */
210 		return (1);
211 	}
212 
213 	if (mpi_alloc_replies(sc) != 0) {
214 		printf("%s: unable to allocate reply space\n", DEVNAME(sc));
215 		goto free_ccbs;
216 	}
217 
218 	if (mpi_iocinit(sc) != 0) {
219 		printf("%s: unable to send iocinit\n", DEVNAME(sc));
220 		goto free_ccbs;
221 	}
222 
223 	/* spin until we're operational */
224 	if (mpi_wait_eq(sc, MPI_DOORBELL, MPI_DOORBELL_STATE,
225 	    MPI_DOORBELL_STATE_OPER) != 0) {
226 		printf("%s: state: 0x%08x\n", DEVNAME(sc),
227 		    mpi_read_db(sc) & MPI_DOORBELL_STATE);
228 		printf("%s: operational state timeout\n", DEVNAME(sc));
229 		goto free_ccbs;
230 	}
231 
232 	mpi_push_replies(sc);
233 
234 	if (mpi_portfacts(sc) != 0) {
235 		printf("%s: unable to get portfacts\n", DEVNAME(sc));
236 		goto free_replies;
237 	}
238 
239 #ifdef notyet
240 	if (mpi_eventnotify(sc) != 0) {
241 		printf("%s: unable to get portfacts\n", DEVNAME(sc));
242 		goto free_replies;
243 	}
244 #endif
245 
246 	if (mpi_portenable(sc) != 0) {
247 		printf("%s: unable to enable port\n", DEVNAME(sc));
248 		goto free_replies;
249 	}
250 
251 	if (mpi_fwupload(sc) != 0) {
252 		printf("%s: unable to upload firmware\n", DEVNAME(sc));
253 		goto free_replies;
254 	}
255 
256 	if (sc->sc_porttype == MPI_PORTFACTS_PORTTYPE_SCSI) {
257 		if (mpi_cfg_spi_port(sc) != 0)
258 			goto free_replies;
259 		mpi_squash_ppr(sc);
260 	}
261 
262 	rw_init(&sc->sc_lock, "mpi_lock");
263 
264 	/* we should be good to go now, attach scsibus */
265 	sc->sc_link.device = &mpi_dev;
266 	sc->sc_link.adapter = &mpi_switch;
267 	sc->sc_link.adapter_softc = sc;
268 	sc->sc_link.adapter_target = sc->sc_target;
269 	sc->sc_link.adapter_buswidth = sc->sc_buswidth;
270 	sc->sc_link.openings = sc->sc_maxcmds / sc->sc_buswidth;
271 
272 	bzero(&saa, sizeof(saa));
273 	saa.saa_sc_link = &sc->sc_link;
274 
275 	/* config_found() returns the scsibus attached to us */
276 	sc->sc_scsibus = (struct scsibus_softc *) config_found(&sc->sc_dev,
277 	    &saa, scsiprint);
278 
279 	/* get raid pages */
280 	mpi_get_raid(sc);
281 
282 	/* do domain validation */
283 	if (sc->sc_porttype == MPI_PORTFACTS_PORTTYPE_SCSI)
284 		mpi_run_ppr(sc);
285 
286 	/* enable interrupts */
287 	mpi_write(sc, MPI_INTR_MASK, MPI_INTR_MASK_DOORBELL);
288 
289 #if NBIO > 0
290 	if (sc->sc_flags & MPI_F_RAID) {
291 		if (bio_register(&sc->sc_dev, mpi_ioctl) != 0)
292 			panic("%s: controller registration failed",
293 			    DEVNAME(sc));
294 		else {
295 			if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_IOC,
296 			    2, 0, &sc->sc_cfg_hdr) != 0) {
297 				printf("%s: can't get IOC page 2 hdr, bio "
298 				    "disabled\n", DEVNAME(sc));
299 				goto done;
300 			}
301 			sc->sc_vol_page = malloc(sc->sc_cfg_hdr.page_length * 4,
302 			    M_TEMP, M_WAITOK | M_CANFAIL);
303 			if (sc->sc_vol_page == NULL) {
304 				printf("%s: can't get memory for IOC page 2, "
305 				    "bio disabled\n", DEVNAME(sc));
306 				goto done;
307 			}
308 			sc->sc_vol_list = (struct mpi_cfg_raid_vol *)
309 			    (sc->sc_vol_page + 1);
310 
311 			sc->sc_ioctl = mpi_ioctl;
312 		}
313 	}
314 #ifndef SMALL_KERNEL
315 	mpi_create_sensors(sc);
316 #endif /* SMALL_KERNEL */
317 done:
318 #endif /* NBIO > 0 */
319 
320 	return (0);
321 
322 free_replies:
323 	bus_dmamap_sync(sc->sc_dmat, MPI_DMA_MAP(sc->sc_replies),
324 	    0, PAGE_SIZE, BUS_DMASYNC_POSTREAD);
325 	mpi_dmamem_free(sc, sc->sc_replies);
326 free_ccbs:
327 	while ((ccb = mpi_get_ccb(sc)) != NULL)
328 		bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
329 	mpi_dmamem_free(sc, sc->sc_requests);
330 	free(sc->sc_ccbs, M_DEVBUF);
331 
332 	return(1);
333 }
334 
335 int
336 mpi_cfg_spi_port(struct mpi_softc *sc)
337 {
338 	struct mpi_cfg_hdr		hdr;
339 	struct mpi_cfg_spi_port_pg1	port;
340 
341 	if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_SCSI_SPI_PORT, 1, 0x0,
342 	    &hdr) != 0)
343 		return (1);
344 
345 	if (mpi_cfg_page(sc, 0x0, &hdr, 1, &port, sizeof(port)) != 0)
346 		return (1);
347 
348 	DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_spi_port_pg1\n", DEVNAME(sc));
349 	DNPRINTF(MPI_D_MISC, "%s:  port_scsi_id: %d port_resp_ids 0x%04x\n",
350 	    DEVNAME(sc), port.port_scsi_id, letoh16(port.port_resp_ids));
351 	DNPRINTF(MPI_D_MISC, "%s:  on_bus_timer_value: 0x%08x\n", DEVNAME(sc),
352 	    letoh32(port.port_scsi_id));
353 	DNPRINTF(MPI_D_MISC, "%s:  target_config: 0x%02x id_config: 0x%04x\n",
354 	    DEVNAME(sc), port.target_config, letoh16(port.id_config));
355 
356 	if (port.port_scsi_id == sc->sc_target &&
357 	    port.port_resp_ids == htole16(1 << sc->sc_target) &&
358 	    port.on_bus_timer_value != htole32(0x0))
359 		return (0);
360 
361 	DNPRINTF(MPI_D_MISC, "%s: setting port scsi id to %d\n", DEVNAME(sc),
362 	    sc->sc_target);
363 	port.port_scsi_id = sc->sc_target;
364 	port.port_resp_ids = htole16(1 << sc->sc_target);
365 	port.on_bus_timer_value = htole32(0x07000000); /* XXX magic */
366 
367 	if (mpi_cfg_page(sc, 0x0, &hdr, 0, &port, sizeof(port)) != 0) {
368 		printf("%s: unable to configure port scsi id\n", DEVNAME(sc));
369 		return (1);
370 	}
371 
372 	return (0);
373 }
374 
375 void
376 mpi_squash_ppr(struct mpi_softc *sc)
377 {
378 	struct mpi_cfg_hdr		hdr;
379 	struct mpi_cfg_spi_dev_pg1	page;
380 	int				i;
381 
382 	DNPRINTF(MPI_D_PPR, "%s: mpi_squash_ppr\n", DEVNAME(sc));
383 
384 	for (i = 0; i < sc->sc_buswidth; i++) {
385 		if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_SCSI_SPI_DEV,
386 		    1, i, &hdr) != 0)
387 			return;
388 
389 		if (mpi_cfg_page(sc, i, &hdr, 1, &page, sizeof(page)) != 0)
390 			return;
391 
392 		DNPRINTF(MPI_D_PPR, "%s:  target: %d req_params1: 0x%02x "
393 		    "req_offset: 0x%02x req_period: 0x%02x "
394 		    "req_params2: 0x%02x conf: 0x%08x\n", DEVNAME(sc), i,
395 		    page.req_params1, page.req_offset, page.req_period,
396 		    page.req_params2, letoh32(page.configuration));
397 
398 		page.req_params1 = 0x0;
399 		page.req_offset = 0x0;
400 		page.req_period = 0x0;
401 		page.req_params2 = 0x0;
402 		page.configuration = htole32(0x0);
403 
404 		if (mpi_cfg_page(sc, i, &hdr, 0, &page, sizeof(page)) != 0)
405 			return;
406 	}
407 }
408 
409 void
410 mpi_run_ppr(struct mpi_softc *sc)
411 {
412 	struct mpi_cfg_hdr		hdr;
413 	struct mpi_cfg_spi_port_pg0	port_pg;
414 	struct mpi_cfg_ioc_pg3		*physdisk_pg;
415 	struct mpi_cfg_raid_physdisk	*physdisk_list, *physdisk;
416 	size_t				pagelen;
417 	struct scsi_link		*link;
418 	int				i, tries;
419 
420 	if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_SCSI_SPI_PORT, 0, 0x0,
421 	    &hdr) != 0) {
422 		DNPRINTF(MPI_D_PPR, "%s: mpi_run_ppr unable to fetch header\n",
423 		    DEVNAME(sc));
424 		return;
425 	}
426 
427 	if (mpi_cfg_page(sc, 0x0, &hdr, 1, &port_pg, sizeof(port_pg)) != 0) {
428 		DNPRINTF(MPI_D_PPR, "%s: mpi_run_ppr unable to fetch page\n",
429 		    DEVNAME(sc));
430 		return;
431 	}
432 
433 	for (i = 0; i < sc->sc_buswidth; i++) {
434 		link = sc->sc_scsibus->sc_link[i][0];
435 		if (link == NULL)
436 			continue;
437 
438 		/* do not ppr volumes */
439 		if (link->flags & SDEV_VIRTUAL)
440 			continue;
441 
442 		tries = 0;
443 		while (mpi_ppr(sc, link, NULL, port_pg.min_period,
444 		    port_pg.max_offset, tries) == EAGAIN)
445 			tries++;
446 	}
447 
448 	if ((sc->sc_flags & MPI_F_RAID) == 0)
449 		return;
450 
451 	if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_IOC, 3, 0x0,
452 	    &hdr) != 0) {
453 		DNPRINTF(MPI_D_RAID|MPI_D_PPR, "%s: mpi_run_ppr unable to "
454 		    "fetch ioc pg 3 header\n", DEVNAME(sc));
455 		return;
456 	}
457 
458 	pagelen = hdr.page_length * 4; /* dwords to bytes */
459 	physdisk_pg = malloc(pagelen, M_TEMP, M_WAITOK|M_CANFAIL);
460 	if (physdisk_pg == NULL) {
461 		DNPRINTF(MPI_D_RAID|MPI_D_PPR, "%s: mpi_run_ppr unable to "
462 		    "allocate ioc pg 3\n", DEVNAME(sc));
463 		return;
464 	}
465 	physdisk_list = (struct mpi_cfg_raid_physdisk *)(physdisk_pg + 1);
466 
467 	if (mpi_cfg_page(sc, 0, &hdr, 1, physdisk_pg, pagelen) != 0) {
468 		DNPRINTF(MPI_D_PPR|MPI_D_PPR, "%s: mpi_run_ppr unable to "
469 		    "fetch ioc page 3\n", DEVNAME(sc));
470 		goto out;
471 	}
472 
473 	DNPRINTF(MPI_D_PPR|MPI_D_PPR, "%s:  no_phys_disks: %d\n", DEVNAME(sc),
474 	    physdisk_pg->no_phys_disks);
475 
476 	for (i = 0; i < physdisk_pg->no_phys_disks; i++) {
477 		physdisk = &physdisk_list[i];
478 
479 		DNPRINTF(MPI_D_PPR|MPI_D_PPR, "%s:  id: %d bus: %d ioc: %d "
480 		    "num: %d\n", DEVNAME(sc), physdisk->phys_disk_id,
481 		    physdisk->phys_disk_bus, physdisk->phys_disk_ioc,
482 		    physdisk->phys_disk_num);
483 
484 		if (physdisk->phys_disk_ioc != sc->sc_ioc_number)
485 			continue;
486 
487 		tries = 0;
488 		while (mpi_ppr(sc, NULL, physdisk, port_pg.min_period,
489 		    port_pg.max_offset, tries) == EAGAIN)
490 			tries++;
491 	}
492 
493 out:
494 	free(physdisk_pg, M_TEMP);
495 }
496 
497 int
498 mpi_ppr(struct mpi_softc *sc, struct scsi_link *link,
499     struct mpi_cfg_raid_physdisk *physdisk, int period, int offset, int try)
500 {
501 	struct mpi_cfg_hdr		hdr0, hdr1;
502 	struct mpi_cfg_spi_dev_pg0	pg0;
503 	struct mpi_cfg_spi_dev_pg1	pg1;
504 	u_int32_t			address;
505 	int				id;
506 	int				raid = 0;
507 
508 	DNPRINTF(MPI_D_PPR, "%s: mpi_ppr period: %d offset: %d try: %d "
509 	    "link quirks: 0x%x\n", DEVNAME(sc), period, offset, try,
510 	    link->quirks);
511 
512 	if (try >= 3)
513 		return (EIO);
514 
515 	if (physdisk == NULL) {
516 		if ((link->inqdata.device & SID_TYPE) == T_PROCESSOR)
517 			return (EIO);
518 
519 		address = link->target;
520 		id = link->target;
521 	} else {
522 		raid = 1;
523 		address = (physdisk->phys_disk_bus << 8) |
524 		    (physdisk->phys_disk_id);
525 		id = physdisk->phys_disk_num;
526 	}
527 
528 	if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_SCSI_SPI_DEV, 0,
529 	    address, &hdr0) != 0) {
530 		DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to fetch header 0\n",
531 		    DEVNAME(sc));
532 		return (EIO);
533 	}
534 
535 	if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_SCSI_SPI_DEV, 1,
536 	    address, &hdr1) != 0) {
537 		DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to fetch header 1\n",
538 		    DEVNAME(sc));
539 		return (EIO);
540 	}
541 
542 #ifdef MPI_DEBUG
543 	if (mpi_cfg_page(sc, address, &hdr0, 1, &pg0, sizeof(pg0)) != 0) {
544 		DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to fetch page 0\n",
545 		    DEVNAME(sc));
546 		return (EIO);
547 	}
548 
549 	DNPRINTF(MPI_D_PPR, "%s: mpi_ppr dev pg 0 neg_params1: 0x%02x "
550 	    "neg_offset: %d neg_period: 0x%02x neg_params2: 0x%02x "
551 	    "info: 0x%08x\n", DEVNAME(sc), pg0.neg_params1, pg0.neg_offset,
552 	    pg0.neg_period, pg0.neg_params2, letoh32(pg0.information));
553 #endif
554 
555 	if (mpi_cfg_page(sc, address, &hdr1, 1, &pg1, sizeof(pg1)) != 0) {
556 		DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to fetch page 1\n",
557 		    DEVNAME(sc));
558 		return (EIO);
559 	}
560 
561 	DNPRINTF(MPI_D_PPR, "%s: mpi_ppr dev pg 1 req_params1: 0x%02x "
562 	    "req_offset: 0x%02x req_period: 0x%02x req_params2: 0x%02x "
563 	    "conf: 0x%08x\n", DEVNAME(sc), pg1.req_params1, pg1.req_offset,
564 	    pg1.req_period, pg1.req_params2, letoh32(pg1.configuration));
565 
566 	pg1.req_params1 = 0;
567 	pg1.req_offset = offset;
568 	pg1.req_period = period;
569 	pg1.req_params2 &= ~MPI_CFG_SPI_DEV_1_REQPARAMS_WIDTH;
570 
571 	if (raid || !(link->quirks & SDEV_NOSYNC)) {
572 		pg1.req_params2 |= MPI_CFG_SPI_DEV_1_REQPARAMS_WIDTH_WIDE;
573 
574 		switch (try) {
575 		case 0: /* U320 */
576 			break;
577 		case 1: /* U160 */
578 			pg1.req_period = 0x09;
579 			break;
580 		case 2: /* U80 */
581 			pg1.req_period = 0x0a;
582 			break;
583 		}
584 
585 		if (pg1.req_period < 0x09) {
586 			/* Ultra320: enable QAS & PACKETIZED */
587 			pg1.req_params1 |= MPI_CFG_SPI_DEV_1_REQPARAMS_QAS |
588 			    MPI_CFG_SPI_DEV_1_REQPARAMS_PACKETIZED;
589 		}
590 		if (pg1.req_period < 0xa) {
591 			/* >= Ultra160: enable dual xfers */
592 			pg1.req_params1 |=
593 			    MPI_CFG_SPI_DEV_1_REQPARAMS_DUALXFERS;
594 		}
595 	}
596 
597 	DNPRINTF(MPI_D_PPR, "%s: mpi_ppr dev pg 1 req_params1: 0x%02x "
598 	    "req_offset: 0x%02x req_period: 0x%02x req_params2: 0x%02x "
599 	    "conf: 0x%08x\n", DEVNAME(sc), pg1.req_params1, pg1.req_offset,
600 	    pg1.req_period, pg1.req_params2, letoh32(pg1.configuration));
601 
602 	if (mpi_cfg_page(sc, address, &hdr1, 0, &pg1, sizeof(pg1)) != 0) {
603 		DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to write page 1\n",
604 		    DEVNAME(sc));
605 		return (EIO);
606 	}
607 
608 	if (mpi_cfg_page(sc, address, &hdr1, 1, &pg1, sizeof(pg1)) != 0) {
609 		DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to read page 1\n",
610 		    DEVNAME(sc));
611 		return (EIO);
612 	}
613 
614 	DNPRINTF(MPI_D_PPR, "%s: mpi_ppr dev pg 1 req_params1: 0x%02x "
615 	    "req_offset: 0x%02x req_period: 0x%02x req_params2: 0x%02x "
616 	    "conf: 0x%08x\n", DEVNAME(sc), pg1.req_params1, pg1.req_offset,
617 	    pg1.req_period, pg1.req_params2, letoh32(pg1.configuration));
618 
619 	if (mpi_inq(sc, id, raid) != 0) {
620 		DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to do inquiry against "
621 		    "target %d\n", DEVNAME(sc), link->target);
622 		return (EIO);
623 	}
624 
625 	if (mpi_cfg_page(sc, address, &hdr0, 1, &pg0, sizeof(pg0)) != 0) {
626 		DNPRINTF(MPI_D_PPR, "%s: mpi_ppr unable to read page 0 after "
627 		    "inquiry\n", DEVNAME(sc));
628 		return (EIO);
629 	}
630 
631 	DNPRINTF(MPI_D_PPR, "%s: mpi_ppr dev pg 0 neg_params1: 0x%02x "
632 	    "neg_offset: %d neg_period: 0x%02x neg_params2: 0x%02x "
633 	    "info: 0x%08x\n", DEVNAME(sc), pg0.neg_params1, pg0.neg_offset,
634 	    pg0.neg_period, pg0.neg_params2, letoh32(pg0.information));
635 
636 	if (!(letoh32(pg0.information) & 0x07) && (try == 0)) {
637 		DNPRINTF(MPI_D_PPR, "%s: mpi_ppr U320 ppr rejected\n",
638 		    DEVNAME(sc));
639 		return (EAGAIN);
640 	}
641 
642 	if ((((letoh32(pg0.information) >> 8) & 0xff) > 0x09) && (try == 1)) {
643 		DNPRINTF(MPI_D_PPR, "%s: mpi_ppr U160 ppr rejected\n",
644 		    DEVNAME(sc));
645 		return (EAGAIN);
646 	}
647 
648 	if (letoh32(pg0.information) & 0x0e) {
649 		DNPRINTF(MPI_D_PPR, "%s: mpi_ppr ppr rejected: %0x\n",
650 		    DEVNAME(sc), letoh32(pg0.information));
651 		return (EAGAIN);
652 	}
653 
654 	switch(pg0.neg_period) {
655 	case 0x08:
656 		period = 160;
657 		break;
658 	case 0x09:
659 		period = 80;
660 		break;
661 	case 0x0a:
662 		period = 40;
663 		break;
664 	case 0x0b:
665 		period = 20;
666 		break;
667 	case 0x0c:
668 		period = 10;
669 		break;
670 	default:
671 		period = 0;
672 		break;
673 	}
674 
675 	printf("%s: %s %d %s at %dMHz width %dbit offset %d "
676 	    "QAS %d DT %d IU %d\n", DEVNAME(sc), raid ? "phys disk" : "target",
677 	    id, period ? "Sync" : "Async", period,
678 	    (pg0.neg_params2 & MPI_CFG_SPI_DEV_0_NEGPARAMS_WIDTH_WIDE) ? 16 : 8,
679 	    pg0.neg_offset,
680 	    (pg0.neg_params1 & MPI_CFG_SPI_DEV_0_NEGPARAMS_QAS) ? 1 : 0,
681 	    (pg0.neg_params1 & MPI_CFG_SPI_DEV_0_NEGPARAMS_DUALXFERS) ? 1 : 0,
682 	    (pg0.neg_params1 & MPI_CFG_SPI_DEV_0_NEGPARAMS_PACKETIZED) ? 1 : 0);
683 
684 	return (0);
685 }
686 
687 int
688 mpi_inq(struct mpi_softc *sc, u_int16_t target, int physdisk)
689 {
690 	struct mpi_ccb			*ccb;
691 	struct scsi_inquiry		inq;
692 	struct {
693 		struct mpi_msg_scsi_io		io;
694 		struct mpi_sge			sge;
695 		struct scsi_inquiry_data	inqbuf;
696 		struct scsi_sense_data		sense;
697 	} __packed			*bundle;
698 	struct mpi_msg_scsi_io		*io;
699 	struct mpi_sge			*sge;
700 	u_int64_t			addr;
701 
702 	DNPRINTF(MPI_D_PPR, "%s: mpi_inq\n", DEVNAME(sc));
703 
704 	bzero(&inq, sizeof(inq));
705 	inq.opcode = INQUIRY;
706 	_lto2b(sizeof(struct scsi_inquiry_data), inq.length);
707 
708 	ccb = mpi_get_ccb(sc);
709 	if (ccb == NULL)
710 		return (1);
711 
712 	ccb->ccb_done = mpi_empty_done;
713 
714 	bundle = ccb->ccb_cmd;
715 	io = &bundle->io;
716 	sge = &bundle->sge;
717 
718 	io->function = physdisk ? MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH :
719 	    MPI_FUNCTION_SCSI_IO_REQUEST;
720 	/*
721 	 * bus is always 0
722 	 * io->bus = htole16(sc->sc_bus);
723 	 */
724 	io->target_id = target;
725 
726 	io->cdb_length = sizeof(inq);
727 	io->sense_buf_len = sizeof(struct scsi_sense_data);
728 	io->msg_flags = MPI_SCSIIO_SENSE_BUF_ADDR_WIDTH_64;
729 
730 	io->msg_context = htole32(ccb->ccb_id);
731 
732 	/*
733 	 * always lun 0
734 	 * io->lun[0] = htobe16(link->lun);
735 	 */
736 
737 	io->direction = MPI_SCSIIO_DIR_READ;
738 	io->tagging = MPI_SCSIIO_ATTR_NO_DISCONNECT;
739 
740 	bcopy(&inq, io->cdb, sizeof(inq));
741 
742 	io->data_length = htole32(sizeof(struct scsi_inquiry_data));
743 
744 	io->sense_buf_low_addr = htole32(ccb->ccb_cmd_dva +
745 	    ((u_int8_t *)&bundle->sense - (u_int8_t *)bundle));
746 
747 	sge->sg_hdr = htole32(MPI_SGE_FL_TYPE_SIMPLE | MPI_SGE_FL_SIZE_64 |
748 	    MPI_SGE_FL_LAST | MPI_SGE_FL_EOB | MPI_SGE_FL_EOL |
749 	    (u_int32_t)sizeof(inq));
750 
751 	addr = ccb->ccb_cmd_dva +
752 	    ((u_int8_t *)&bundle->inqbuf - (u_int8_t *)bundle);
753 	sge->sg_hi_addr = htole32((u_int32_t)(addr >> 32));
754 	sge->sg_lo_addr = htole32((u_int32_t)addr);
755 
756 	if (mpi_poll(sc, ccb, 5000) != 0)
757 		return (1);
758 
759 	if (ccb->ccb_rcb != NULL)
760 		mpi_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
761 
762 	mpi_put_ccb(sc, ccb);
763 
764 	return (0);
765 }
766 
767 void
768 mpi_detach(struct mpi_softc *sc)
769 {
770 
771 }
772 
773 int
774 mpi_intr(void *arg)
775 {
776 	struct mpi_softc		*sc = arg;
777 	u_int32_t			reg;
778 	int				rv = 0;
779 
780 	while ((reg = mpi_pop_reply(sc)) != 0xffffffff) {
781 		mpi_reply(sc, reg);
782 		rv = 1;
783 	}
784 
785 	return (rv);
786 }
787 
788 int
789 mpi_reply(struct mpi_softc *sc, u_int32_t reg)
790 {
791 	struct mpi_ccb			*ccb;
792 	struct mpi_rcb			*rcb = NULL;
793 	struct mpi_msg_reply		*reply = NULL;
794 	u_int32_t			reply_dva;
795 	int				id;
796 	int				i;
797 
798 	DNPRINTF(MPI_D_INTR, "%s: mpi_reply reg: 0x%08x\n", DEVNAME(sc), reg);
799 
800 	if (reg & MPI_REPLY_QUEUE_ADDRESS) {
801 		bus_dmamap_sync(sc->sc_dmat,
802 		    MPI_DMA_MAP(sc->sc_replies), 0, PAGE_SIZE,
803 		    BUS_DMASYNC_POSTREAD);
804 
805 		reply_dva = (reg & MPI_REPLY_QUEUE_ADDRESS_MASK) << 1;
806 
807 		i = (reply_dva - (u_int32_t)MPI_DMA_DVA(sc->sc_replies)) /
808 		    MPI_REPLY_SIZE;
809 		rcb = &sc->sc_rcbs[i];
810 		reply = rcb->rcb_reply;
811 
812 		id = letoh32(reply->msg_context);
813 
814 		bus_dmamap_sync(sc->sc_dmat,
815 		    MPI_DMA_MAP(sc->sc_replies), 0, PAGE_SIZE,
816 		    BUS_DMASYNC_PREREAD);
817 	} else {
818 		switch (reg & MPI_REPLY_QUEUE_TYPE_MASK) {
819 		case MPI_REPLY_QUEUE_TYPE_INIT:
820 			id = reg & MPI_REPLY_QUEUE_CONTEXT;
821 			break;
822 
823 		default:
824 			panic("%s: unsupported context reply\n",
825 			    DEVNAME(sc));
826 		}
827 	}
828 
829 	DNPRINTF(MPI_D_INTR, "%s: mpi_reply id: %d reply: %p\n",
830 	    DEVNAME(sc), id, reply);
831 
832 	ccb = &sc->sc_ccbs[id];
833 
834 	bus_dmamap_sync(sc->sc_dmat, MPI_DMA_MAP(sc->sc_requests),
835 	    ccb->ccb_offset, MPI_REQUEST_SIZE,
836 	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
837 	ccb->ccb_state = MPI_CCB_READY;
838 	ccb->ccb_rcb = rcb;
839 
840 	ccb->ccb_done(ccb);
841 
842 	return (id);
843 }
844 
845 struct mpi_dmamem *
846 mpi_dmamem_alloc(struct mpi_softc *sc, size_t size)
847 {
848 	struct mpi_dmamem		*mdm;
849 	int				nsegs;
850 
851 	mdm = malloc(sizeof(struct mpi_dmamem), M_DEVBUF, M_NOWAIT | M_ZERO);
852 	if (mdm == NULL)
853 		return (NULL);
854 
855 	mdm->mdm_size = size;
856 
857 	if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
858 	    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &mdm->mdm_map) != 0)
859 		goto mdmfree;
860 
861 	if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &mdm->mdm_seg,
862 	    1, &nsegs, BUS_DMA_NOWAIT) != 0)
863 		goto destroy;
864 
865 	if (bus_dmamem_map(sc->sc_dmat, &mdm->mdm_seg, nsegs, size,
866 	    &mdm->mdm_kva, BUS_DMA_NOWAIT) != 0)
867 		goto free;
868 
869 	if (bus_dmamap_load(sc->sc_dmat, mdm->mdm_map, mdm->mdm_kva, size,
870 	    NULL, BUS_DMA_NOWAIT) != 0)
871 		goto unmap;
872 
873 	bzero(mdm->mdm_kva, size);
874 
875 	DNPRINTF(MPI_D_MEM, "%s: mpi_dmamem_alloc size: %d mdm: %#x "
876 	    "map: %#x nsegs: %d segs: %#x kva: %x\n",
877 	    DEVNAME(sc), size, mdm->mdm_map, nsegs, mdm->mdm_seg, mdm->mdm_kva);
878 
879 	return (mdm);
880 
881 unmap:
882 	bus_dmamem_unmap(sc->sc_dmat, mdm->mdm_kva, size);
883 free:
884 	bus_dmamem_free(sc->sc_dmat, &mdm->mdm_seg, 1);
885 destroy:
886 	bus_dmamap_destroy(sc->sc_dmat, mdm->mdm_map);
887 mdmfree:
888 	free(mdm, M_DEVBUF);
889 
890 	return (NULL);
891 }
892 
893 void
894 mpi_dmamem_free(struct mpi_softc *sc, struct mpi_dmamem *mdm)
895 {
896 	DNPRINTF(MPI_D_MEM, "%s: mpi_dmamem_free %#x\n", DEVNAME(sc), mdm);
897 
898 	bus_dmamap_unload(sc->sc_dmat, mdm->mdm_map);
899 	bus_dmamem_unmap(sc->sc_dmat, mdm->mdm_kva, mdm->mdm_size);
900 	bus_dmamem_free(sc->sc_dmat, &mdm->mdm_seg, 1);
901 	bus_dmamap_destroy(sc->sc_dmat, mdm->mdm_map);
902 	free(mdm, M_DEVBUF);
903 }
904 
905 int
906 mpi_alloc_ccbs(struct mpi_softc *sc)
907 {
908 	struct mpi_ccb			*ccb;
909 	u_int8_t			*cmd;
910 	int				i;
911 
912 	TAILQ_INIT(&sc->sc_ccb_free);
913 
914 	sc->sc_ccbs = malloc(sizeof(struct mpi_ccb) * sc->sc_maxcmds,
915 	    M_DEVBUF, M_WAITOK | M_CANFAIL | M_ZERO);
916 	if (sc->sc_ccbs == NULL) {
917 		printf("%s: unable to allocate ccbs\n", DEVNAME(sc));
918 		return (1);
919 	}
920 
921 	sc->sc_requests = mpi_dmamem_alloc(sc,
922 	    MPI_REQUEST_SIZE * sc->sc_maxcmds);
923 	if (sc->sc_requests == NULL) {
924 		printf("%s: unable to allocate ccb dmamem\n", DEVNAME(sc));
925 		goto free_ccbs;
926 	}
927 	cmd = MPI_DMA_KVA(sc->sc_requests);
928 	bzero(cmd, MPI_REQUEST_SIZE * sc->sc_maxcmds);
929 
930 	for (i = 0; i < sc->sc_maxcmds; i++) {
931 		ccb = &sc->sc_ccbs[i];
932 
933 		if (bus_dmamap_create(sc->sc_dmat, MAXPHYS,
934 		    sc->sc_max_sgl_len, MAXPHYS, 0,
935 		    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
936 		    &ccb->ccb_dmamap) != 0) {
937 			printf("%s: unable to create dma map\n", DEVNAME(sc));
938 			goto free_maps;
939 		}
940 
941 		ccb->ccb_sc = sc;
942 		ccb->ccb_id = i;
943 		ccb->ccb_offset = MPI_REQUEST_SIZE * i;
944 
945 		ccb->ccb_cmd = &cmd[ccb->ccb_offset];
946 		ccb->ccb_cmd_dva = (u_int32_t)MPI_DMA_DVA(sc->sc_requests) +
947 		    ccb->ccb_offset;
948 
949 		DNPRINTF(MPI_D_CCB, "%s: mpi_alloc_ccbs(%d) ccb: %#x map: %#x "
950 		    "sc: %#x id: %#x offs: %#x cmd: %#x dva: %#x\n",
951 		    DEVNAME(sc), i, ccb, ccb->ccb_dmamap, ccb->ccb_sc,
952 		    ccb->ccb_id, ccb->ccb_offset, ccb->ccb_cmd,
953 		    ccb->ccb_cmd_dva);
954 
955 		mpi_put_ccb(sc, ccb);
956 	}
957 
958 	return (0);
959 
960 free_maps:
961 	while ((ccb = mpi_get_ccb(sc)) != NULL)
962 		bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
963 
964 	mpi_dmamem_free(sc, sc->sc_requests);
965 free_ccbs:
966 	free(sc->sc_ccbs, M_DEVBUF);
967 
968 	return (1);
969 }
970 
971 struct mpi_ccb *
972 mpi_get_ccb(struct mpi_softc *sc)
973 {
974 	struct mpi_ccb			*ccb;
975 
976 	ccb = TAILQ_FIRST(&sc->sc_ccb_free);
977 	if (ccb == NULL) {
978 		DNPRINTF(MPI_D_CCB, "%s: mpi_get_ccb == NULL\n", DEVNAME(sc));
979 		return (NULL);
980 	}
981 
982 	TAILQ_REMOVE(&sc->sc_ccb_free, ccb, ccb_link);
983 
984 	ccb->ccb_state = MPI_CCB_READY;
985 
986 	DNPRINTF(MPI_D_CCB, "%s: mpi_get_ccb %#x\n", DEVNAME(sc), ccb);
987 
988 	return (ccb);
989 }
990 
991 void
992 mpi_put_ccb(struct mpi_softc *sc, struct mpi_ccb *ccb)
993 {
994 	DNPRINTF(MPI_D_CCB, "%s: mpi_put_ccb %#x\n", DEVNAME(sc), ccb);
995 
996 	ccb->ccb_state = MPI_CCB_FREE;
997 	ccb->ccb_xs = NULL;
998 	ccb->ccb_done = NULL;
999 	bzero(ccb->ccb_cmd, MPI_REQUEST_SIZE);
1000 	TAILQ_INSERT_TAIL(&sc->sc_ccb_free, ccb, ccb_link);
1001 }
1002 
1003 int
1004 mpi_alloc_replies(struct mpi_softc *sc)
1005 {
1006 	DNPRINTF(MPI_D_MISC, "%s: mpi_alloc_replies\n", DEVNAME(sc));
1007 
1008 	sc->sc_rcbs = malloc(MPI_REPLY_COUNT * sizeof(struct mpi_rcb),
1009 	    M_DEVBUF, M_WAITOK|M_CANFAIL);
1010 	if (sc->sc_rcbs == NULL)
1011 		return (1);
1012 
1013 	sc->sc_replies = mpi_dmamem_alloc(sc, PAGE_SIZE);
1014 	if (sc->sc_replies == NULL) {
1015 		free(sc->sc_rcbs, M_DEVBUF);
1016 		return (1);
1017 	}
1018 
1019 	return (0);
1020 }
1021 
1022 void
1023 mpi_push_replies(struct mpi_softc *sc)
1024 {
1025 	struct mpi_rcb			*rcb;
1026 	char				*kva = MPI_DMA_KVA(sc->sc_replies);
1027 	int				i;
1028 
1029 	bus_dmamap_sync(sc->sc_dmat, MPI_DMA_MAP(sc->sc_replies),
1030 	    0, PAGE_SIZE, BUS_DMASYNC_PREREAD);
1031 
1032 	for (i = 0; i < MPI_REPLY_COUNT; i++) {
1033 		rcb = &sc->sc_rcbs[i];
1034 
1035 		rcb->rcb_reply = kva + MPI_REPLY_SIZE * i;
1036 		rcb->rcb_reply_dva = (u_int32_t)MPI_DMA_DVA(sc->sc_replies) +
1037 		    MPI_REPLY_SIZE * i;
1038 		mpi_push_reply(sc, rcb->rcb_reply_dva);
1039 	}
1040 }
1041 
1042 void
1043 mpi_start(struct mpi_softc *sc, struct mpi_ccb *ccb)
1044 {
1045 	DNPRINTF(MPI_D_RW, "%s: mpi_start %#x\n", DEVNAME(sc),
1046 	    ccb->ccb_cmd_dva);
1047 
1048 	bus_dmamap_sync(sc->sc_dmat, MPI_DMA_MAP(sc->sc_requests),
1049 	    ccb->ccb_offset, MPI_REQUEST_SIZE,
1050 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1051 
1052 	ccb->ccb_state = MPI_CCB_QUEUED;
1053 	mpi_write(sc, MPI_REQ_QUEUE, ccb->ccb_cmd_dva);
1054 }
1055 
1056 int
1057 mpi_complete(struct mpi_softc *sc, struct mpi_ccb *ccb, int timeout)
1058 {
1059 	u_int32_t			reg;
1060 	int				id = -1;
1061 
1062 	DNPRINTF(MPI_D_INTR, "%s: mpi_complete timeout %d\n", DEVNAME(sc),
1063 	    timeout);
1064 
1065 	do {
1066 		reg = mpi_pop_reply(sc);
1067 		if (reg == 0xffffffff) {
1068 			if (timeout-- == 0)
1069 				return (1);
1070 
1071 			delay(1000);
1072 			continue;
1073 		}
1074 
1075 		id = mpi_reply(sc, reg);
1076 
1077 	} while (ccb->ccb_id != id);
1078 
1079 	return (0);
1080 }
1081 
1082 int
1083 mpi_poll(struct mpi_softc *sc, struct mpi_ccb *ccb, int timeout)
1084 {
1085 	int				error;
1086 	int				s;
1087 
1088 	DNPRINTF(MPI_D_CMD, "%s: mpi_poll\n", DEVNAME(sc));
1089 
1090 	s = splbio();
1091 	mpi_start(sc, ccb);
1092 	error = mpi_complete(sc, ccb, timeout);
1093 	splx(s);
1094 
1095 	return (error);
1096 }
1097 
1098 int
1099 mpi_scsi_cmd(struct scsi_xfer *xs)
1100 {
1101 	struct scsi_link		*link = xs->sc_link;
1102 	struct mpi_softc		*sc = link->adapter_softc;
1103 	struct mpi_ccb			*ccb;
1104 	struct mpi_ccb_bundle		*mcb;
1105 	struct mpi_msg_scsi_io		*io;
1106 	int				s;
1107 
1108 	DNPRINTF(MPI_D_CMD, "%s: mpi_scsi_cmd\n", DEVNAME(sc));
1109 
1110 	if (xs->cmdlen > MPI_CDB_LEN) {
1111 		DNPRINTF(MPI_D_CMD, "%s: CBD too big %d\n",
1112 		    DEVNAME(sc), xs->cmdlen);
1113 		bzero(&xs->sense, sizeof(xs->sense));
1114 		xs->sense.error_code = SSD_ERRCODE_VALID | 0x70;
1115 		xs->sense.flags = SKEY_ILLEGAL_REQUEST;
1116 		xs->sense.add_sense_code = 0x20;
1117 		xs->error = XS_SENSE;
1118 		s = splbio();
1119 		scsi_done(xs);
1120 		splx(s);
1121 		return (COMPLETE);
1122 	}
1123 
1124 	s = splbio();
1125 	ccb = mpi_get_ccb(sc);
1126 	splx(s);
1127 	if (ccb == NULL)
1128 		return (NO_CCB);
1129 
1130 	DNPRINTF(MPI_D_CMD, "%s: ccb_id: %d xs->flags: 0x%x\n",
1131 	    DEVNAME(sc), ccb->ccb_id, xs->flags);
1132 
1133 	ccb->ccb_xs = xs;
1134 	ccb->ccb_done = mpi_scsi_cmd_done;
1135 
1136 	mcb = ccb->ccb_cmd;
1137 	io = &mcb->mcb_io;
1138 
1139 	io->function = MPI_FUNCTION_SCSI_IO_REQUEST;
1140 	/*
1141 	 * bus is always 0
1142 	 * io->bus = htole16(sc->sc_bus);
1143 	 */
1144 	io->target_id = link->target;
1145 
1146 	io->cdb_length = xs->cmdlen;
1147 	io->sense_buf_len = sizeof(xs->sense);
1148 	io->msg_flags = MPI_SCSIIO_SENSE_BUF_ADDR_WIDTH_64;
1149 
1150 	io->msg_context = htole32(ccb->ccb_id);
1151 
1152 	io->lun[0] = htobe16(link->lun);
1153 
1154 	switch (xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) {
1155 	case SCSI_DATA_IN:
1156 		io->direction = MPI_SCSIIO_DIR_READ;
1157 		break;
1158 	case SCSI_DATA_OUT:
1159 		io->direction = MPI_SCSIIO_DIR_WRITE;
1160 		break;
1161 	default:
1162 		io->direction = MPI_SCSIIO_DIR_NONE;
1163 		break;
1164 	}
1165 
1166 	if (sc->sc_porttype != MPI_PORTFACTS_PORTTYPE_SCSI &&
1167 	    (link->quirks & SDEV_NOTAGS))
1168 		io->tagging = MPI_SCSIIO_ATTR_UNTAGGED;
1169 	else
1170 		io->tagging = MPI_SCSIIO_ATTR_SIMPLE_Q;
1171 
1172 	bcopy(xs->cmd, io->cdb, xs->cmdlen);
1173 
1174 	io->data_length = htole32(xs->datalen);
1175 
1176 	io->sense_buf_low_addr = htole32(ccb->ccb_cmd_dva +
1177 	    ((u_int8_t *)&mcb->mcb_sense - (u_int8_t *)mcb));
1178 
1179 	if (mpi_load_xs(ccb) != 0) {
1180 		xs->error = XS_DRIVER_STUFFUP;
1181 		s = splbio();
1182 		mpi_put_ccb(sc, ccb);
1183 		scsi_done(xs);
1184 		splx(s);
1185 		return (COMPLETE);
1186 	}
1187 
1188 	timeout_set(&xs->stimeout, mpi_timeout_xs, ccb);
1189 
1190 	if (xs->flags & SCSI_POLL) {
1191 		if (mpi_poll(sc, ccb, xs->timeout) != 0)
1192 			xs->error = XS_DRIVER_STUFFUP;
1193 		return (COMPLETE);
1194 	}
1195 
1196 	s = splbio();
1197 	mpi_start(sc, ccb);
1198 	splx(s);
1199 	return (SUCCESSFULLY_QUEUED);
1200 }
1201 
1202 void
1203 mpi_scsi_cmd_done(struct mpi_ccb *ccb)
1204 {
1205 	struct mpi_softc		*sc = ccb->ccb_sc;
1206 	struct scsi_xfer		*xs = ccb->ccb_xs;
1207 	struct mpi_ccb_bundle		*mcb = ccb->ccb_cmd;
1208 	bus_dmamap_t			dmap = ccb->ccb_dmamap;
1209 	struct mpi_msg_scsi_io_error	*sie;
1210 
1211 	if (xs->datalen != 0) {
1212 		bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
1213 		    (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
1214 		    BUS_DMASYNC_POSTWRITE);
1215 
1216 		bus_dmamap_unload(sc->sc_dmat, dmap);
1217 	}
1218 
1219 	/* timeout_del */
1220 	xs->error = XS_NOERROR;
1221 	xs->resid = 0;
1222 	xs->flags |= ITSDONE;
1223 
1224 	if (ccb->ccb_rcb == NULL) {
1225 		/* no scsi error, we're ok so drop out early */
1226 		xs->status = SCSI_OK;
1227 		mpi_put_ccb(sc, ccb);
1228 		scsi_done(xs);
1229 		return;
1230 	}
1231 
1232 	sie = ccb->ccb_rcb->rcb_reply;
1233 
1234 	DNPRINTF(MPI_D_CMD, "%s: mpi_scsi_cmd_done xs cmd: 0x%02x len: %d "
1235 	    "flags 0x%x\n", DEVNAME(sc), xs->cmd->opcode, xs->datalen,
1236 	    xs->flags);
1237 	DNPRINTF(MPI_D_CMD, "%s:  target_id: %d bus: %d msg_length: %d "
1238 	    "function: 0x%02x\n", DEVNAME(sc), sie->target_id, sie->bus,
1239 	    sie->msg_length, sie->function);
1240 	DNPRINTF(MPI_D_CMD, "%s:  cdb_length: %d sense_buf_length: %d "
1241 	    "msg_flags: 0x%02x\n", DEVNAME(sc), sie->cdb_length,
1242 	    sie->sense_buf_len, sie->msg_flags);
1243 	DNPRINTF(MPI_D_CMD, "%s:  msg_context: 0x%08x\n", DEVNAME(sc),
1244 	    letoh32(sie->msg_context));
1245 	DNPRINTF(MPI_D_CMD, "%s:  scsi_status: 0x%02x scsi_state: 0x%02x "
1246 	    "ioc_status: 0x%04x\n", DEVNAME(sc), sie->scsi_status,
1247 	    sie->scsi_state, letoh16(sie->ioc_status));
1248 	DNPRINTF(MPI_D_CMD, "%s:  ioc_loginfo: 0x%08x\n", DEVNAME(sc),
1249 	    letoh32(sie->ioc_loginfo));
1250 	DNPRINTF(MPI_D_CMD, "%s:  transfer_count: %d\n", DEVNAME(sc),
1251 	    letoh32(sie->transfer_count));
1252 	DNPRINTF(MPI_D_CMD, "%s:  sense_count: %d\n", DEVNAME(sc),
1253 	    letoh32(sie->sense_count));
1254 	DNPRINTF(MPI_D_CMD, "%s:  response_info: 0x%08x\n", DEVNAME(sc),
1255 	    letoh32(sie->response_info));
1256 	DNPRINTF(MPI_D_CMD, "%s:  tag: 0x%04x\n", DEVNAME(sc),
1257 	    letoh16(sie->tag));
1258 
1259 	xs->status = sie->scsi_status;
1260 	switch (letoh16(sie->ioc_status)) {
1261 	case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:
1262 		xs->resid = xs->datalen - letoh32(sie->transfer_count);
1263 		if (sie->scsi_state & MPI_SCSIIO_ERR_STATE_NO_SCSI_STATUS) {
1264 			xs->error = XS_DRIVER_STUFFUP;
1265 			break;
1266 		}
1267 		/* FALLTHROUGH */
1268 	case MPI_IOCSTATUS_SUCCESS:
1269 	case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:
1270 		switch (xs->status) {
1271 		case SCSI_OK:
1272 			xs->resid = 0;
1273 			break;
1274 
1275 		case SCSI_CHECK:
1276 			xs->error = XS_SENSE;
1277 			break;
1278 
1279 		case SCSI_BUSY:
1280 		case SCSI_QUEUE_FULL:
1281 			xs->error = XS_BUSY;
1282 			break;
1283 
1284 		default:
1285 			xs->error = XS_DRIVER_STUFFUP;
1286 			break;
1287 		}
1288 		break;
1289 
1290 	case MPI_IOCSTATUS_BUSY:
1291 	case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:
1292 		xs->error = XS_BUSY;
1293 		break;
1294 
1295 	case MPI_IOCSTATUS_SCSI_INVALID_BUS:
1296 	case MPI_IOCSTATUS_SCSI_INVALID_TARGETID:
1297 	case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
1298 		xs->error = XS_SELTIMEOUT;
1299 		break;
1300 
1301 	default:
1302 		xs->error = XS_DRIVER_STUFFUP;
1303 		break;
1304 	}
1305 
1306 	if (sie->scsi_state & MPI_SCSIIO_ERR_STATE_AUTOSENSE_VALID)
1307 		bcopy(&mcb->mcb_sense, &xs->sense, sizeof(xs->sense));
1308 
1309 	DNPRINTF(MPI_D_CMD, "%s:  xs err: 0x%02x status: %d\n", DEVNAME(sc),
1310 	    xs->error, xs->status);
1311 
1312 	mpi_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
1313 	mpi_put_ccb(sc, ccb);
1314 	scsi_done(xs);
1315 }
1316 
1317 void
1318 mpi_timeout_xs(void *arg)
1319 {
1320 	/* XXX */
1321 }
1322 
1323 int
1324 mpi_load_xs(struct mpi_ccb *ccb)
1325 {
1326 	struct mpi_softc		*sc = ccb->ccb_sc;
1327 	struct scsi_xfer		*xs = ccb->ccb_xs;
1328 	struct mpi_ccb_bundle		*mcb = ccb->ccb_cmd;
1329 	struct mpi_msg_scsi_io		*io = &mcb->mcb_io;
1330 	struct mpi_sge			*sge, *nsge = &mcb->mcb_sgl[0];
1331 	struct mpi_sge			*ce = NULL, *nce;
1332 	u_int64_t			ce_dva;
1333 	bus_dmamap_t			dmap = ccb->ccb_dmamap;
1334 	u_int32_t			addr, flags;
1335 	int				i, error;
1336 
1337 	if (xs->datalen == 0) {
1338 		nsge->sg_hdr = htole32(MPI_SGE_FL_TYPE_SIMPLE |
1339 		    MPI_SGE_FL_LAST | MPI_SGE_FL_EOB | MPI_SGE_FL_EOL);
1340 		return (0);
1341 	}
1342 
1343 	error = bus_dmamap_load(sc->sc_dmat, dmap,
1344 	    xs->data, xs->datalen, NULL,
1345 	    (xs->flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
1346 	if (error) {
1347 		printf("%s: error %d loading dmamap\n", DEVNAME(sc), error);
1348 		return (1);
1349 	}
1350 
1351 	flags = MPI_SGE_FL_TYPE_SIMPLE | MPI_SGE_FL_SIZE_64;
1352 	if (xs->flags & SCSI_DATA_OUT)
1353 		flags |= MPI_SGE_FL_DIR_OUT;
1354 
1355 	if (dmap->dm_nsegs > sc->sc_first_sgl_len) {
1356 		ce = &mcb->mcb_sgl[sc->sc_first_sgl_len - 1];
1357 		io->chain_offset = ((u_int8_t *)ce - (u_int8_t *)io) / 4;
1358 	}
1359 
1360 	for (i = 0; i < dmap->dm_nsegs; i++) {
1361 
1362 		if (nsge == ce) {
1363 			nsge++;
1364 			sge->sg_hdr |= htole32(MPI_SGE_FL_LAST);
1365 
1366 			DNPRINTF(MPI_D_DMA, "%s:   - 0x%08x 0x%08x 0x%08x\n",
1367 			    DEVNAME(sc), sge->sg_hdr,
1368 			    sge->sg_hi_addr, sge->sg_lo_addr);
1369 
1370 			if ((dmap->dm_nsegs - i) > sc->sc_chain_len) {
1371 				nce = &nsge[sc->sc_chain_len - 1];
1372 				addr = ((u_int8_t *)nce - (u_int8_t *)nsge) / 4;
1373 				addr = addr << 16 |
1374 				    sizeof(struct mpi_sge) * sc->sc_chain_len;
1375 			} else {
1376 				nce = NULL;
1377 				addr = sizeof(struct mpi_sge) *
1378 				    (dmap->dm_nsegs - i);
1379 			}
1380 
1381 			ce->sg_hdr = htole32(MPI_SGE_FL_TYPE_CHAIN |
1382 			    MPI_SGE_FL_SIZE_64 | addr);
1383 
1384 			ce_dva = ccb->ccb_cmd_dva +
1385 			    ((u_int8_t *)nsge - (u_int8_t *)mcb);
1386 
1387 			addr = (u_int32_t)(ce_dva >> 32);
1388 			ce->sg_hi_addr = htole32(addr);
1389 			addr = (u_int32_t)ce_dva;
1390 			ce->sg_lo_addr = htole32(addr);
1391 
1392 			DNPRINTF(MPI_D_DMA, "%s:  ce: 0x%08x 0x%08x 0x%08x\n",
1393 			    DEVNAME(sc), ce->sg_hdr, ce->sg_hi_addr,
1394 			    ce->sg_lo_addr);
1395 
1396 			ce = nce;
1397 		}
1398 
1399 		DNPRINTF(MPI_D_DMA, "%s:  %d: %d 0x%016llx\n", DEVNAME(sc),
1400 		    i, dmap->dm_segs[i].ds_len,
1401 		    (u_int64_t)dmap->dm_segs[i].ds_addr);
1402 
1403 		sge = nsge;
1404 
1405 		sge->sg_hdr = htole32(flags | dmap->dm_segs[i].ds_len);
1406 		addr = (u_int32_t)((u_int64_t)dmap->dm_segs[i].ds_addr >> 32);
1407 		sge->sg_hi_addr = htole32(addr);
1408 		addr = (u_int32_t)dmap->dm_segs[i].ds_addr;
1409 		sge->sg_lo_addr = htole32(addr);
1410 
1411 		DNPRINTF(MPI_D_DMA, "%s:  %d: 0x%08x 0x%08x 0x%08x\n",
1412 		    DEVNAME(sc), i, sge->sg_hdr, sge->sg_hi_addr,
1413 		    sge->sg_lo_addr);
1414 
1415 		nsge = sge + 1;
1416 	}
1417 
1418 	/* terminate list */
1419 	sge->sg_hdr |= htole32(MPI_SGE_FL_LAST | MPI_SGE_FL_EOB |
1420 	    MPI_SGE_FL_EOL);
1421 
1422 	bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
1423 	    (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
1424 	    BUS_DMASYNC_PREWRITE);
1425 
1426 	return (0);
1427 }
1428 
1429 void
1430 mpi_minphys(struct buf *bp, struct scsi_link *sl)
1431 {
1432 	/* XXX */
1433 	if (bp->b_bcount > MAXPHYS)
1434 		bp->b_bcount = MAXPHYS;
1435 	minphys(bp);
1436 }
1437 
1438 int
1439 mpi_scsi_probe(struct scsi_link *link)
1440 {
1441 	struct mpi_softc		*sc = link->adapter_softc;
1442 	struct mpi_ecfg_hdr		ehdr;
1443 	struct mpi_cfg_sas_dev_pg0	pg0;
1444 	u_int32_t			address;
1445 
1446 	if (sc->sc_porttype != MPI_PORTFACTS_PORTTYPE_SAS)
1447 		return (0);
1448 
1449 	address = MPI_CFG_SAS_DEV_ADDR_BUS | link->target;
1450 
1451 	if (mpi_ecfg_header(sc, MPI_CONFIG_REQ_EXTPAGE_TYPE_SAS_DEVICE, 0,
1452 	    address, &ehdr) != 0)
1453 		return (EIO);
1454 
1455 	if (mpi_ecfg_page(sc, address, &ehdr, 1, &pg0, sizeof(pg0)) != 0)
1456 		return (0);
1457 
1458 	DNPRINTF(MPI_D_MISC, "%s: mpi_scsi_probe sas dev pg 0 for target %d:\n",
1459 	    DEVNAME(sc), link->target);
1460 	DNPRINTF(MPI_D_MISC, "%s:  slot: 0x%04x enc_handle: 0x%04x\n",
1461 	    DEVNAME(sc), letoh16(pg0.slot), letoh16(pg0.enc_handle));
1462 	DNPRINTF(MPI_D_MISC, "%s:  sas_addr: 0x%016llx\n", DEVNAME(sc),
1463 	    letoh64(pg0.sas_addr));
1464 	DNPRINTF(MPI_D_MISC, "%s:  parent_dev_handle: 0x%04x phy_num: 0x%02x "
1465 	    "access_status: 0x%02x\n", DEVNAME(sc),
1466 	    letoh16(pg0.parent_dev_handle), pg0.phy_num, pg0.access_status);
1467 	DNPRINTF(MPI_D_MISC, "%s:  dev_handle: 0x%04x "
1468 	    "bus: 0x%02x target: 0x%02x\n", DEVNAME(sc),
1469 	    letoh16(pg0.dev_handle), pg0.bus, pg0.target);
1470 	DNPRINTF(MPI_D_MISC, "%s:  device_info: 0x%08x\n", DEVNAME(sc),
1471 	    letoh32(pg0.device_info));
1472 	DNPRINTF(MPI_D_MISC, "%s:  flags: 0x%04x physical_port: 0x%02x\n",
1473 	    DEVNAME(sc), letoh16(pg0.flags), pg0.physical_port);
1474 
1475 	if (ISSET(letoh32(pg0.device_info),
1476 	    MPI_CFG_SAS_DEV_0_DEVINFO_ATAPI_DEVICE)) {
1477 		DNPRINTF(MPI_D_MISC, "%s: target %d is an ATAPI device\n",
1478 		    DEVNAME(sc), link->target);
1479 		link->flags |= SDEV_ATAPI;
1480 		link->quirks |= SDEV_ONLYBIG;
1481 	}
1482 
1483 	return (0);
1484 }
1485 
1486 u_int32_t
1487 mpi_read(struct mpi_softc *sc, bus_size_t r)
1488 {
1489 	u_int32_t			rv;
1490 
1491 	bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4,
1492 	    BUS_SPACE_BARRIER_READ);
1493 	rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, r);
1494 
1495 	DNPRINTF(MPI_D_RW, "%s: mpi_read %#x %#x\n", DEVNAME(sc), r, rv);
1496 
1497 	return (rv);
1498 }
1499 
1500 void
1501 mpi_write(struct mpi_softc *sc, bus_size_t r, u_int32_t v)
1502 {
1503 	DNPRINTF(MPI_D_RW, "%s: mpi_write %#x %#x\n", DEVNAME(sc), r, v);
1504 
1505 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, r, v);
1506 	bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4,
1507 	    BUS_SPACE_BARRIER_WRITE);
1508 }
1509 
1510 int
1511 mpi_wait_eq(struct mpi_softc *sc, bus_size_t r, u_int32_t mask,
1512     u_int32_t target)
1513 {
1514 	int				i;
1515 
1516 	DNPRINTF(MPI_D_RW, "%s: mpi_wait_eq %#x %#x %#x\n", DEVNAME(sc), r,
1517 	    mask, target);
1518 
1519 	for (i = 0; i < 10000; i++) {
1520 		if ((mpi_read(sc, r) & mask) == target)
1521 			return (0);
1522 		delay(1000);
1523 	}
1524 
1525 	return (1);
1526 }
1527 
1528 int
1529 mpi_wait_ne(struct mpi_softc *sc, bus_size_t r, u_int32_t mask,
1530     u_int32_t target)
1531 {
1532 	int				i;
1533 
1534 	DNPRINTF(MPI_D_RW, "%s: mpi_wait_ne %#x %#x %#x\n", DEVNAME(sc), r,
1535 	    mask, target);
1536 
1537 	for (i = 0; i < 10000; i++) {
1538 		if ((mpi_read(sc, r) & mask) != target)
1539 			return (0);
1540 		delay(1000);
1541 	}
1542 
1543 	return (1);
1544 }
1545 
1546 int
1547 mpi_init(struct mpi_softc *sc)
1548 {
1549 	u_int32_t			db;
1550 	int				i;
1551 
1552 	/* spin until the IOC leaves the RESET state */
1553 	if (mpi_wait_ne(sc, MPI_DOORBELL, MPI_DOORBELL_STATE,
1554 	    MPI_DOORBELL_STATE_RESET) != 0) {
1555 		DNPRINTF(MPI_D_MISC, "%s: mpi_init timeout waiting to leave "
1556 		    "reset state\n", DEVNAME(sc));
1557 		return (1);
1558 	}
1559 
1560 	/* check current ownership */
1561 	db = mpi_read_db(sc);
1562 	if ((db & MPI_DOORBELL_WHOINIT) == MPI_DOORBELL_WHOINIT_PCIPEER) {
1563 		DNPRINTF(MPI_D_MISC, "%s: mpi_init initialised by pci peer\n",
1564 		    DEVNAME(sc));
1565 		return (0);
1566 	}
1567 
1568 	for (i = 0; i < 5; i++) {
1569 		switch (db & MPI_DOORBELL_STATE) {
1570 		case MPI_DOORBELL_STATE_READY:
1571 			DNPRINTF(MPI_D_MISC, "%s: mpi_init ioc is ready\n",
1572 			    DEVNAME(sc));
1573 			return (0);
1574 
1575 		case MPI_DOORBELL_STATE_OPER:
1576 		case MPI_DOORBELL_STATE_FAULT:
1577 			DNPRINTF(MPI_D_MISC, "%s: mpi_init ioc is being "
1578 			    "reset\n" , DEVNAME(sc));
1579 			if (mpi_reset_soft(sc) != 0)
1580 				mpi_reset_hard(sc);
1581 			break;
1582 
1583 		case MPI_DOORBELL_STATE_RESET:
1584 			DNPRINTF(MPI_D_MISC, "%s: mpi_init waiting to come "
1585 			    "out of reset\n", DEVNAME(sc));
1586 			if (mpi_wait_ne(sc, MPI_DOORBELL, MPI_DOORBELL_STATE,
1587 			    MPI_DOORBELL_STATE_RESET) != 0)
1588 				return (1);
1589 			break;
1590 		}
1591 		db = mpi_read_db(sc);
1592 	}
1593 
1594 	return (1);
1595 }
1596 
1597 int
1598 mpi_reset_soft(struct mpi_softc *sc)
1599 {
1600 	DNPRINTF(MPI_D_MISC, "%s: mpi_reset_soft\n", DEVNAME(sc));
1601 
1602 	if (mpi_read_db(sc) & MPI_DOORBELL_INUSE)
1603 		return (1);
1604 
1605 	mpi_write_db(sc,
1606 	    MPI_DOORBELL_FUNCTION(MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET));
1607 	if (mpi_wait_eq(sc, MPI_INTR_STATUS,
1608 	    MPI_INTR_STATUS_IOCDOORBELL, 0) != 0)
1609 		return (1);
1610 
1611 	if (mpi_wait_eq(sc, MPI_DOORBELL, MPI_DOORBELL_STATE,
1612 	    MPI_DOORBELL_STATE_READY) != 0)
1613 		return (1);
1614 
1615 	return (0);
1616 }
1617 
1618 int
1619 mpi_reset_hard(struct mpi_softc *sc)
1620 {
1621 	DNPRINTF(MPI_D_MISC, "%s: mpi_reset_hard\n", DEVNAME(sc));
1622 
1623 	/* enable diagnostic register */
1624 	mpi_write(sc, MPI_WRITESEQ, 0xff);
1625 	mpi_write(sc, MPI_WRITESEQ, MPI_WRITESEQ_1);
1626 	mpi_write(sc, MPI_WRITESEQ, MPI_WRITESEQ_2);
1627 	mpi_write(sc, MPI_WRITESEQ, MPI_WRITESEQ_3);
1628 	mpi_write(sc, MPI_WRITESEQ, MPI_WRITESEQ_4);
1629 	mpi_write(sc, MPI_WRITESEQ, MPI_WRITESEQ_5);
1630 
1631 	/* reset ioc */
1632 	mpi_write(sc, MPI_HOSTDIAG, MPI_HOSTDIAG_RESET_ADAPTER);
1633 
1634 	delay(10000);
1635 
1636 	/* disable diagnostic register */
1637 	mpi_write(sc, MPI_WRITESEQ, 0xff);
1638 
1639 	/* restore pci bits? */
1640 
1641 	/* firmware bits? */
1642 	return (0);
1643 }
1644 
1645 int
1646 mpi_handshake_send(struct mpi_softc *sc, void *buf, size_t dwords)
1647 {
1648 	u_int32_t				*query = buf;
1649 	int					i;
1650 
1651 	/* make sure the doorbell is not in use. */
1652 	if (mpi_read_db(sc) & MPI_DOORBELL_INUSE)
1653 		return (1);
1654 
1655 	/* clear pending doorbell interrupts */
1656 	if (mpi_read_intr(sc) & MPI_INTR_STATUS_DOORBELL)
1657 		mpi_write_intr(sc, 0);
1658 
1659 	/*
1660 	 * first write the doorbell with the handshake function and the
1661 	 * dword count.
1662 	 */
1663 	mpi_write_db(sc, MPI_DOORBELL_FUNCTION(MPI_FUNCTION_HANDSHAKE) |
1664 	    MPI_DOORBELL_DWORDS(dwords));
1665 
1666 	/*
1667 	 * the doorbell used bit will be set because a doorbell function has
1668 	 * started. Wait for the interrupt and then ack it.
1669 	 */
1670 	if (mpi_wait_db_int(sc) != 0)
1671 		return (1);
1672 	mpi_write_intr(sc, 0);
1673 
1674 	/* poll for the acknowledgement. */
1675 	if (mpi_wait_db_ack(sc) != 0)
1676 		return (1);
1677 
1678 	/* write the query through the doorbell. */
1679 	for (i = 0; i < dwords; i++) {
1680 		mpi_write_db(sc, htole32(query[i]));
1681 		if (mpi_wait_db_ack(sc) != 0)
1682 			return (1);
1683 	}
1684 
1685 	return (0);
1686 }
1687 
1688 int
1689 mpi_handshake_recv_dword(struct mpi_softc *sc, u_int32_t *dword)
1690 {
1691 	u_int16_t				*words = (u_int16_t *)dword;
1692 	int					i;
1693 
1694 	for (i = 0; i < 2; i++) {
1695 		if (mpi_wait_db_int(sc) != 0)
1696 			return (1);
1697 		words[i] = letoh16(mpi_read_db(sc) & MPI_DOORBELL_DATA_MASK);
1698 		mpi_write_intr(sc, 0);
1699 	}
1700 
1701 	return (0);
1702 }
1703 
1704 int
1705 mpi_handshake_recv(struct mpi_softc *sc, void *buf, size_t dwords)
1706 {
1707 	struct mpi_msg_reply			*reply = buf;
1708 	u_int32_t				*dbuf = buf, dummy;
1709 	int					i;
1710 
1711 	/* get the first dword so we can read the length out of the header. */
1712 	if (mpi_handshake_recv_dword(sc, &dbuf[0]) != 0)
1713 		return (1);
1714 
1715 	DNPRINTF(MPI_D_CMD, "%s: mpi_handshake_recv dwords: %d reply: %d\n",
1716 	    DEVNAME(sc), dwords, reply->msg_length);
1717 
1718 	/*
1719 	 * the total length, in dwords, is in the message length field of the
1720 	 * reply header.
1721 	 */
1722 	for (i = 1; i < MIN(dwords, reply->msg_length); i++) {
1723 		if (mpi_handshake_recv_dword(sc, &dbuf[i]) != 0)
1724 			return (1);
1725 	}
1726 
1727 	/* if there's extra stuff to come off the ioc, discard it */
1728 	while (i++ < reply->msg_length) {
1729 		if (mpi_handshake_recv_dword(sc, &dummy) != 0)
1730 			return (1);
1731 		DNPRINTF(MPI_D_CMD, "%s: mpi_handshake_recv dummy read: "
1732 		    "0x%08x\n", DEVNAME(sc), dummy);
1733 	}
1734 
1735 	/* wait for the doorbell used bit to be reset and clear the intr */
1736 	if (mpi_wait_db_int(sc) != 0)
1737 		return (1);
1738 	mpi_write_intr(sc, 0);
1739 
1740 	return (0);
1741 }
1742 
1743 void
1744 mpi_empty_done(struct mpi_ccb *ccb)
1745 {
1746 	/* nothing to do */
1747 }
1748 
1749 int
1750 mpi_iocfacts(struct mpi_softc *sc)
1751 {
1752 	struct mpi_msg_iocfacts_request		ifq;
1753 	struct mpi_msg_iocfacts_reply		ifp;
1754 
1755 	DNPRINTF(MPI_D_MISC, "%s: mpi_iocfacts\n", DEVNAME(sc));
1756 
1757 	bzero(&ifq, sizeof(ifq));
1758 	bzero(&ifp, sizeof(ifp));
1759 
1760 	ifq.function = MPI_FUNCTION_IOC_FACTS;
1761 	ifq.chain_offset = 0;
1762 	ifq.msg_flags = 0;
1763 	ifq.msg_context = htole32(0xdeadbeef);
1764 
1765 	if (mpi_handshake_send(sc, &ifq, dwordsof(ifq)) != 0) {
1766 		DNPRINTF(MPI_D_MISC, "%s: mpi_iocfacts send failed\n",
1767 		    DEVNAME(sc));
1768 		return (1);
1769 	}
1770 
1771 	if (mpi_handshake_recv(sc, &ifp, dwordsof(ifp)) != 0) {
1772 		DNPRINTF(MPI_D_MISC, "%s: mpi_iocfacts recv failed\n",
1773 		    DEVNAME(sc));
1774 		return (1);
1775 	}
1776 
1777 	DNPRINTF(MPI_D_MISC, "%s:  func: 0x%02x len: %d msgver: %d.%d\n",
1778 	    DEVNAME(sc), ifp.function, ifp.msg_length,
1779 	    ifp.msg_version_maj, ifp.msg_version_min);
1780 	DNPRINTF(MPI_D_MISC, "%s:  msgflags: 0x%02x iocnumber: 0x%02x "
1781 	    "hdrver: %d.%d\n", DEVNAME(sc), ifp.msg_flags,
1782 	    ifp.ioc_number, ifp.header_version_maj,
1783 	    ifp.header_version_min);
1784 	DNPRINTF(MPI_D_MISC, "%s:  message context: 0x%08x\n", DEVNAME(sc),
1785 	    letoh32(ifp.msg_context));
1786 	DNPRINTF(MPI_D_MISC, "%s:  iocstatus: 0x%04x ioexcept: 0x%04x\n",
1787 	    DEVNAME(sc), letoh16(ifp.ioc_status),
1788 	    letoh16(ifp.ioc_exceptions));
1789 	DNPRINTF(MPI_D_MISC, "%s:  iocloginfo: 0x%08x\n", DEVNAME(sc),
1790 	    letoh32(ifp.ioc_loginfo));
1791 	DNPRINTF(MPI_D_MISC, "%s:  flags: 0x%02x blocksize: %d whoinit: 0x%02x "
1792 	    "maxchdepth: %d\n", DEVNAME(sc), ifp.flags,
1793 	    ifp.block_size, ifp.whoinit, ifp.max_chain_depth);
1794 	DNPRINTF(MPI_D_MISC, "%s:  reqfrsize: %d replyqdepth: %d\n",
1795 	    DEVNAME(sc), letoh16(ifp.request_frame_size),
1796 	    letoh16(ifp.reply_queue_depth));
1797 	DNPRINTF(MPI_D_MISC, "%s:  productid: 0x%04x\n", DEVNAME(sc),
1798 	    letoh16(ifp.product_id));
1799 	DNPRINTF(MPI_D_MISC, "%s:  hostmfahiaddr: 0x%08x\n", DEVNAME(sc),
1800 	    letoh32(ifp.current_host_mfa_hi_addr));
1801 	DNPRINTF(MPI_D_MISC, "%s:  event_state: 0x%02x number_of_ports: %d "
1802 	    "global_credits: %d\n",
1803 	    DEVNAME(sc), ifp.event_state, ifp.number_of_ports,
1804 	    letoh16(ifp.global_credits));
1805 	DNPRINTF(MPI_D_MISC, "%s:  sensebufhiaddr: 0x%08x\n", DEVNAME(sc),
1806 	    letoh32(ifp.current_sense_buffer_hi_addr));
1807 	DNPRINTF(MPI_D_MISC, "%s:  maxbus: %d maxdev: %d replyfrsize: %d\n",
1808 	    DEVNAME(sc), ifp.max_buses, ifp.max_devices,
1809 	    letoh16(ifp.current_reply_frame_size));
1810 	DNPRINTF(MPI_D_MISC, "%s:  fw_image_size: %d\n", DEVNAME(sc),
1811 	    letoh32(ifp.fw_image_size));
1812 	DNPRINTF(MPI_D_MISC, "%s:  ioc_capabilities: 0x%08x\n", DEVNAME(sc),
1813 	    letoh32(ifp.ioc_capabilities));
1814 	DNPRINTF(MPI_D_MISC, "%s:  fw_version: %d.%d fw_version_unit: 0x%02x "
1815 	    "fw_version_dev: 0x%02x\n", DEVNAME(sc),
1816 	    ifp.fw_version_maj, ifp.fw_version_min,
1817 	    ifp.fw_version_unit, ifp.fw_version_dev);
1818 	DNPRINTF(MPI_D_MISC, "%s:  hi_priority_queue_depth: 0x%04x\n",
1819 	    DEVNAME(sc), letoh16(ifp.hi_priority_queue_depth));
1820 	DNPRINTF(MPI_D_MISC, "%s:  host_page_buffer_sge: hdr: 0x%08x "
1821 	    "addr 0x%08x %08x\n", DEVNAME(sc),
1822 	    letoh32(ifp.host_page_buffer_sge.sg_hdr),
1823 	    letoh32(ifp.host_page_buffer_sge.sg_hi_addr),
1824 	    letoh32(ifp.host_page_buffer_sge.sg_lo_addr));
1825 
1826 	sc->sc_maxcmds = letoh16(ifp.global_credits);
1827 	sc->sc_maxchdepth = ifp.max_chain_depth;
1828 	sc->sc_ioc_number = ifp.ioc_number;
1829 	if (sc->sc_flags & MPI_F_SPI)
1830 		sc->sc_buswidth = 16;
1831 	else
1832 		sc->sc_buswidth =
1833 		    (ifp.max_devices == 0) ? 256 : ifp.max_devices;
1834 	if (ifp.flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
1835 		sc->sc_fw_len = letoh32(ifp.fw_image_size);
1836 
1837 	/*
1838 	 * you can fit sg elements on the end of the io cmd if they fit in the
1839 	 * request frame size.
1840 	 */
1841 	sc->sc_first_sgl_len = ((letoh16(ifp.request_frame_size) * 4) -
1842 	    sizeof(struct mpi_msg_scsi_io)) / sizeof(struct mpi_sge);
1843 	DNPRINTF(MPI_D_MISC, "%s:   first sgl len: %d\n", DEVNAME(sc),
1844 	    sc->sc_first_sgl_len);
1845 
1846 	sc->sc_chain_len = (letoh16(ifp.request_frame_size) * 4) /
1847 	    sizeof(struct mpi_sge);
1848 	DNPRINTF(MPI_D_MISC, "%s:   chain len: %d\n", DEVNAME(sc),
1849 	    sc->sc_chain_len);
1850 
1851 	/* the sgl tailing the io cmd loses an entry to the chain element. */
1852 	sc->sc_max_sgl_len = MPI_MAX_SGL - 1;
1853 	/* the sgl chains lose an entry for each chain element */
1854 	sc->sc_max_sgl_len -= (MPI_MAX_SGL - sc->sc_first_sgl_len) /
1855 	    sc->sc_chain_len;
1856 	DNPRINTF(MPI_D_MISC, "%s:   max sgl len: %d\n", DEVNAME(sc),
1857 	    sc->sc_max_sgl_len);
1858 
1859 	/* XXX we're ignoring the max chain depth */
1860 
1861 	return (0);
1862 }
1863 
1864 int
1865 mpi_iocinit(struct mpi_softc *sc)
1866 {
1867 	struct mpi_msg_iocinit_request		iiq;
1868 	struct mpi_msg_iocinit_reply		iip;
1869 	u_int32_t				hi_addr;
1870 
1871 	DNPRINTF(MPI_D_MISC, "%s: mpi_iocinit\n", DEVNAME(sc));
1872 
1873 	bzero(&iiq, sizeof(iiq));
1874 	bzero(&iip, sizeof(iip));
1875 
1876 	iiq.function = MPI_FUNCTION_IOC_INIT;
1877 	iiq.whoinit = MPI_WHOINIT_HOST_DRIVER;
1878 
1879 	iiq.max_devices = (sc->sc_buswidth == 256) ? 0 : sc->sc_buswidth;
1880 	iiq.max_buses = 1;
1881 
1882 	iiq.msg_context = htole32(0xd00fd00f);
1883 
1884 	iiq.reply_frame_size = htole16(MPI_REPLY_SIZE);
1885 
1886 	hi_addr = (u_int32_t)((u_int64_t)MPI_DMA_DVA(sc->sc_requests) >> 32);
1887 	iiq.host_mfa_hi_addr = htole32(hi_addr);
1888 	iiq.sense_buffer_hi_addr = htole32(hi_addr);
1889 
1890 	hi_addr = (u_int32_t)((u_int64_t)MPI_DMA_DVA(sc->sc_replies) >> 32);
1891 	iiq.reply_fifo_host_signalling_addr = htole32(hi_addr);
1892 
1893 	iiq.msg_version_maj = 0x01;
1894 	iiq.msg_version_min = 0x02;
1895 
1896 	iiq.hdr_version_unit = 0x0d;
1897 	iiq.hdr_version_dev = 0x00;
1898 
1899 	if (mpi_handshake_send(sc, &iiq, dwordsof(iiq)) != 0) {
1900 		DNPRINTF(MPI_D_MISC, "%s: mpi_iocinit send failed\n",
1901 		    DEVNAME(sc));
1902 		return (1);
1903 	}
1904 
1905 	if (mpi_handshake_recv(sc, &iip, dwordsof(iip)) != 0) {
1906 		DNPRINTF(MPI_D_MISC, "%s: mpi_iocinit recv failed\n",
1907 		    DEVNAME(sc));
1908 		return (1);
1909 	}
1910 
1911 	DNPRINTF(MPI_D_MISC, "%s:  function: 0x%02x msg_length: %d "
1912 	    "whoinit: 0x%02x\n", DEVNAME(sc), iip.function,
1913 	    iip.msg_length, iip.whoinit);
1914 	DNPRINTF(MPI_D_MISC, "%s:  msg_flags: 0x%02x max_buses: %d "
1915 	    "max_devices: %d flags: 0x%02x\n", DEVNAME(sc), iip.msg_flags,
1916 	    iip.max_buses, iip.max_devices, iip.flags);
1917 	DNPRINTF(MPI_D_MISC, "%s:  msg_context: 0x%08x\n", DEVNAME(sc),
1918 	    letoh32(iip.msg_context));
1919 	DNPRINTF(MPI_D_MISC, "%s:  ioc_status: 0x%04x\n", DEVNAME(sc),
1920 	    letoh16(iip.ioc_status));
1921 	DNPRINTF(MPI_D_MISC, "%s:  ioc_loginfo: 0x%08x\n", DEVNAME(sc),
1922 	    letoh32(iip.ioc_loginfo));
1923 
1924 	return (0);
1925 }
1926 
1927 int
1928 mpi_portfacts(struct mpi_softc *sc)
1929 {
1930 	struct mpi_ccb				*ccb;
1931 	struct mpi_msg_portfacts_request	*pfq;
1932 	volatile struct mpi_msg_portfacts_reply	*pfp;
1933 	int					s, rv = 1;
1934 
1935 	DNPRINTF(MPI_D_MISC, "%s: mpi_portfacts\n", DEVNAME(sc));
1936 
1937 	s = splbio();
1938 	ccb = mpi_get_ccb(sc);
1939 	splx(s);
1940 	if (ccb == NULL) {
1941 		DNPRINTF(MPI_D_MISC, "%s: mpi_portfacts ccb_get\n",
1942 		    DEVNAME(sc));
1943 		return (rv);
1944 	}
1945 
1946 	ccb->ccb_done = mpi_empty_done;
1947 	pfq = ccb->ccb_cmd;
1948 
1949 	pfq->function = MPI_FUNCTION_PORT_FACTS;
1950 	pfq->chain_offset = 0;
1951 	pfq->msg_flags = 0;
1952 	pfq->port_number = 0;
1953 	pfq->msg_context = htole32(ccb->ccb_id);
1954 
1955 	if (mpi_poll(sc, ccb, 50000) != 0) {
1956 		DNPRINTF(MPI_D_MISC, "%s: mpi_portfacts poll\n", DEVNAME(sc));
1957 		goto err;
1958 	}
1959 
1960 	if (ccb->ccb_rcb == NULL) {
1961 		DNPRINTF(MPI_D_MISC, "%s: empty portfacts reply\n",
1962 		    DEVNAME(sc));
1963 		goto err;
1964 	}
1965 	pfp = ccb->ccb_rcb->rcb_reply;
1966 
1967 	DNPRINTF(MPI_D_MISC, "%s:  function: 0x%02x msg_length: %d\n",
1968 	    DEVNAME(sc), pfp->function, pfp->msg_length);
1969 	DNPRINTF(MPI_D_MISC, "%s:  msg_flags: 0x%02x port_number: %d\n",
1970 	    DEVNAME(sc), pfp->msg_flags, pfp->port_number);
1971 	DNPRINTF(MPI_D_MISC, "%s:  msg_context: 0x%08x\n", DEVNAME(sc),
1972 	    letoh32(pfp->msg_context));
1973 	DNPRINTF(MPI_D_MISC, "%s:  ioc_status: 0x%04x\n", DEVNAME(sc),
1974 	    letoh16(pfp->ioc_status));
1975 	DNPRINTF(MPI_D_MISC, "%s:  ioc_loginfo: 0x%08x\n", DEVNAME(sc),
1976 	    letoh32(pfp->ioc_loginfo));
1977 	DNPRINTF(MPI_D_MISC, "%s:  max_devices: %d port_type: 0x%02x\n",
1978 	    DEVNAME(sc), letoh16(pfp->max_devices), pfp->port_type);
1979 	DNPRINTF(MPI_D_MISC, "%s:  protocol_flags: 0x%04x port_scsi_id: %d\n",
1980 	    DEVNAME(sc), letoh16(pfp->protocol_flags),
1981 	    letoh16(pfp->port_scsi_id));
1982 	DNPRINTF(MPI_D_MISC, "%s:  max_persistent_ids: %d "
1983 	    "max_posted_cmd_buffers: %d\n", DEVNAME(sc),
1984 	    letoh16(pfp->max_persistent_ids),
1985 	    letoh16(pfp->max_posted_cmd_buffers));
1986 	DNPRINTF(MPI_D_MISC, "%s:  max_lan_buckets: %d\n", DEVNAME(sc),
1987 	    letoh16(pfp->max_lan_buckets));
1988 
1989 	sc->sc_porttype = pfp->port_type;
1990 	if (sc->sc_target == -1)
1991 		sc->sc_target = letoh16(pfp->port_scsi_id);
1992 
1993 	mpi_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
1994 	rv = 0;
1995 err:
1996 	mpi_put_ccb(sc, ccb);
1997 
1998 	return (rv);
1999 }
2000 
2001 int
2002 mpi_eventnotify(struct mpi_softc *sc)
2003 {
2004 	struct mpi_ccb				*ccb;
2005 	struct mpi_msg_event_request		*enq;
2006 	int					s;
2007 
2008 	s = splbio();
2009 	ccb = mpi_get_ccb(sc);
2010 	splx(s);
2011 	if (ccb == NULL) {
2012 		DNPRINTF(MPI_D_MISC, "%s: mpi_eventnotify ccb_get\n",
2013 		    DEVNAME(sc));
2014 		return (1);
2015 	}
2016 
2017 	ccb->ccb_done = mpi_eventnotify_done;
2018 	enq = ccb->ccb_cmd;
2019 
2020 	enq->function = MPI_FUNCTION_EVENT_NOTIFICATION;
2021 	enq->chain_offset = 0;
2022 	enq->event_switch = MPI_EVENT_SWITCH_ON;
2023 	enq->msg_context = htole32(ccb->ccb_id);
2024 
2025 	mpi_start(sc, ccb);
2026 	return (0);
2027 }
2028 
2029 void
2030 mpi_eventnotify_done(struct mpi_ccb *ccb)
2031 {
2032 	struct mpi_softc			*sc = ccb->ccb_sc;
2033 	struct mpi_msg_event_reply		*enp = ccb->ccb_rcb->rcb_reply;
2034 	int					deferred = 0;
2035 
2036 	DNPRINTF(MPI_D_EVT, "%s: mpi_eventnotify_done\n", DEVNAME(sc));
2037 
2038 	DNPRINTF(MPI_D_EVT, "%s:  function: 0x%02x msg_length: %d "
2039 	    "data_length: %d\n", DEVNAME(sc), enp->function, enp->msg_length,
2040 	    letoh16(enp->data_length));
2041 	DNPRINTF(MPI_D_EVT, "%s:  ack_required: %d msg_flags 0x%02x\n",
2042 	    DEVNAME(sc), enp->ack_required, enp->msg_flags);
2043 	DNPRINTF(MPI_D_EVT, "%s:  msg_context: 0x%08x\n", DEVNAME(sc),
2044 	    letoh32(enp->msg_context));
2045 	DNPRINTF(MPI_D_EVT, "%s:  ioc_status: 0x%04x\n", DEVNAME(sc),
2046 	    letoh16(enp->ioc_status));
2047 	DNPRINTF(MPI_D_EVT, "%s:  ioc_loginfo: 0x%08x\n", DEVNAME(sc),
2048 	    letoh32(enp->ioc_loginfo));
2049 	DNPRINTF(MPI_D_EVT, "%s:  event: 0x%08x\n", DEVNAME(sc),
2050 	    letoh32(enp->event));
2051 	DNPRINTF(MPI_D_EVT, "%s:  event_context: 0x%08x\n", DEVNAME(sc),
2052 	    letoh32(enp->event_context));
2053 
2054 	switch (letoh32(enp->event)) {
2055 	/* ignore these */
2056 	case MPI_EVENT_EVENT_CHANGE:
2057 	case MPI_EVENT_SAS_PHY_LINK_STATUS:
2058 		break;
2059 
2060 	case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
2061 		if (sc->sc_scsibus == NULL)
2062 			break;
2063 
2064 		if (scsi_task(mpi_evt_sas, sc, ccb->ccb_rcb, 0) != 0) {
2065 			printf("%s: unable to run SAS device status change\n",
2066 			    DEVNAME(sc));
2067 			break;
2068 		}
2069 		deferred = 1;
2070 		break;
2071 
2072 	default:
2073 		printf("%s: unhandled event 0x%02x\n", DEVNAME(sc),
2074 		    letoh32(enp->event));
2075 		break;
2076 	}
2077 
2078 	if (!deferred) {
2079 		if (enp->ack_required)
2080 			mpi_eventack(sc, enp);
2081 		mpi_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
2082 	}
2083 
2084 	if ((enp->msg_flags & MPI_EVENT_FLAGS_REPLY_KEPT) == 0) {
2085 		/* XXX this shouldnt happen till shutdown */
2086 		mpi_put_ccb(sc, ccb);
2087 	}
2088 }
2089 
2090 void
2091 mpi_evt_sas(void *xsc, void *arg)
2092 {
2093 	struct mpi_softc			*sc = xsc;
2094 	struct mpi_rcb				*rcb = arg;
2095 	struct mpi_msg_event_reply		*enp = rcb->rcb_reply;
2096 	struct mpi_evt_sas_change		*ch;
2097 	u_int8_t				*data;
2098 	int					s;
2099 
2100 	data = rcb->rcb_reply;
2101 	data += sizeof(struct mpi_msg_event_reply);
2102 	ch = (struct mpi_evt_sas_change *)data;
2103 
2104 	if (ch->bus != 0)
2105 		return;
2106 
2107 	switch (ch->reason) {
2108 	case MPI_EVT_SASCH_REASON_ADDED:
2109 	case MPI_EVT_SASCH_REASON_NO_PERSIST_ADDED:
2110 		scsi_probe_target(sc->sc_scsibus, ch->target);
2111 		break;
2112 
2113 	case MPI_EVT_SASCH_REASON_NOT_RESPONDING:
2114 		scsi_detach_target(sc->sc_scsibus, ch->target, DETACH_FORCE);
2115 		break;
2116 
2117 	case MPI_EVT_SASCH_REASON_SMART_DATA:
2118 	case MPI_EVT_SASCH_REASON_UNSUPPORTED:
2119 	case MPI_EVT_SASCH_REASON_INTERNAL_RESET:
2120 		break;
2121 	default:
2122 		printf("%s: unknown reason for SAS device status change: "
2123 		    "0x%02x\n", DEVNAME(sc), ch->reason);
2124 		break;
2125 	}
2126 
2127 	s = splbio();
2128 	mpi_push_reply(sc, rcb->rcb_reply_dva);
2129 	if (enp->ack_required)
2130 		mpi_eventack(sc, enp);
2131 	splx(s);
2132 }
2133 
2134 void
2135 mpi_eventack(struct mpi_softc *sc, struct mpi_msg_event_reply *enp)
2136 {
2137 	struct mpi_ccb				*ccb;
2138 	struct mpi_msg_eventack_request		*eaq;
2139 
2140 	ccb = mpi_get_ccb(sc);
2141 	if (ccb == NULL) {
2142 		DNPRINTF(MPI_D_EVT, "%s: mpi_eventack ccb_get\n", DEVNAME(sc));
2143 		return;
2144 	}
2145 
2146 	ccb->ccb_done = mpi_eventack_done;
2147 	eaq = ccb->ccb_cmd;
2148 
2149 	eaq->function = MPI_FUNCTION_EVENT_ACK;
2150 	eaq->msg_context = htole32(ccb->ccb_id);
2151 
2152 	eaq->event = enp->event;
2153 	eaq->event_context = enp->event_context;
2154 
2155 	mpi_start(sc, ccb);
2156 	return;
2157 }
2158 
2159 void
2160 mpi_eventack_done(struct mpi_ccb *ccb)
2161 {
2162 	struct mpi_softc			*sc = ccb->ccb_sc;
2163 
2164 	DNPRINTF(MPI_D_EVT, "%s: event ack done\n", DEVNAME(sc));
2165 
2166 	mpi_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
2167 	mpi_put_ccb(sc, ccb);
2168 }
2169 
2170 int
2171 mpi_portenable(struct mpi_softc *sc)
2172 {
2173 	struct mpi_ccb				*ccb;
2174 	struct mpi_msg_portenable_request	*peq;
2175 	struct mpi_msg_portenable_repy		*pep;
2176 	int					s;
2177 
2178 	DNPRINTF(MPI_D_MISC, "%s: mpi_portenable\n", DEVNAME(sc));
2179 
2180 	s = splbio();
2181 	ccb = mpi_get_ccb(sc);
2182 	splx(s);
2183 	if (ccb == NULL) {
2184 		DNPRINTF(MPI_D_MISC, "%s: mpi_portenable ccb_get\n",
2185 		    DEVNAME(sc));
2186 		return (1);
2187 	}
2188 
2189 	ccb->ccb_done = mpi_empty_done;
2190 	peq = ccb->ccb_cmd;
2191 
2192 	peq->function = MPI_FUNCTION_PORT_ENABLE;
2193 	peq->port_number = 0;
2194 	peq->msg_context = htole32(ccb->ccb_id);
2195 
2196 	if (mpi_poll(sc, ccb, 50000) != 0) {
2197 		DNPRINTF(MPI_D_MISC, "%s: mpi_portenable poll\n", DEVNAME(sc));
2198 		return (1);
2199 	}
2200 
2201 	if (ccb->ccb_rcb == NULL) {
2202 		DNPRINTF(MPI_D_MISC, "%s: empty portenable reply\n",
2203 		    DEVNAME(sc));
2204 		return (1);
2205 	}
2206 	pep = ccb->ccb_rcb->rcb_reply;
2207 
2208 	mpi_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
2209 	mpi_put_ccb(sc, ccb);
2210 
2211 	return (0);
2212 }
2213 
2214 int
2215 mpi_fwupload(struct mpi_softc *sc)
2216 {
2217 	struct mpi_ccb				*ccb;
2218 	struct {
2219 		struct mpi_msg_fwupload_request		req;
2220 		struct mpi_sge				sge;
2221 	} __packed				*bundle;
2222 	struct mpi_msg_fwupload_reply		*upp;
2223 	u_int64_t				addr;
2224 	int					s;
2225 	int					rv = 0;
2226 
2227 	if (sc->sc_fw_len == 0)
2228 		return (0);
2229 
2230 	DNPRINTF(MPI_D_MISC, "%s: mpi_fwupload\n", DEVNAME(sc));
2231 
2232 	sc->sc_fw = mpi_dmamem_alloc(sc, sc->sc_fw_len);
2233 	if (sc->sc_fw == NULL) {
2234 		DNPRINTF(MPI_D_MISC, "%s: mpi_fwupload unable to allocate %d\n",
2235 		    DEVNAME(sc), sc->sc_fw_len);
2236 		return (1);
2237 	}
2238 
2239 	s = splbio();
2240 	ccb = mpi_get_ccb(sc);
2241 	splx(s);
2242 	if (ccb == NULL) {
2243 		DNPRINTF(MPI_D_MISC, "%s: mpi_fwupload ccb_get\n",
2244 		    DEVNAME(sc));
2245 		goto err;
2246 	}
2247 
2248 	ccb->ccb_done = mpi_empty_done;
2249 	bundle = ccb->ccb_cmd;
2250 
2251 	bundle->req.function = MPI_FUNCTION_FW_UPLOAD;
2252 	bundle->req.msg_context = htole32(ccb->ccb_id);
2253 
2254 	bundle->req.image_type = MPI_FWUPLOAD_IMAGETYPE_IOC_FW;
2255 
2256 	bundle->req.tce.details_length = 12;
2257 	bundle->req.tce.image_size = htole32(sc->sc_fw_len);
2258 
2259 	bundle->sge.sg_hdr = htole32(MPI_SGE_FL_TYPE_SIMPLE |
2260 	    MPI_SGE_FL_SIZE_64 | MPI_SGE_FL_LAST | MPI_SGE_FL_EOB |
2261 	    MPI_SGE_FL_EOL | (u_int32_t)sc->sc_fw_len);
2262 	addr = MPI_DMA_DVA(sc->sc_fw);
2263 	bundle->sge.sg_hi_addr = htole32((u_int32_t)(addr >> 32));
2264 	bundle->sge.sg_lo_addr = htole32((u_int32_t)addr);
2265 
2266 	if (mpi_poll(sc, ccb, 50000) != 0) {
2267 		DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_header poll\n", DEVNAME(sc));
2268 		goto err;
2269 	}
2270 
2271 	if (ccb->ccb_rcb == NULL)
2272 		panic("%s: unable to do fw upload\n", DEVNAME(sc));
2273 	upp = ccb->ccb_rcb->rcb_reply;
2274 
2275 	if (letoh16(upp->ioc_status) != MPI_IOCSTATUS_SUCCESS)
2276 		rv = 1;
2277 
2278 	mpi_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
2279 	mpi_put_ccb(sc, ccb);
2280 
2281 	return (rv);
2282 
2283 err:
2284 	mpi_dmamem_free(sc, sc->sc_fw);
2285 	return (1);
2286 }
2287 
2288 void
2289 mpi_get_raid(struct mpi_softc *sc)
2290 {
2291 	struct mpi_cfg_hdr		hdr;
2292 	struct mpi_cfg_ioc_pg2		*vol_page;
2293 	struct mpi_cfg_raid_vol		*vol_list, *vol;
2294 	size_t				pagelen;
2295 	u_int32_t			capabilities;
2296 	struct scsi_link		*link;
2297 	int				i;
2298 
2299 	DNPRINTF(MPI_D_RAID, "%s: mpi_get_raid\n", DEVNAME(sc));
2300 
2301 	if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_IOC, 2, 0, &hdr) != 0) {
2302 		DNPRINTF(MPI_D_RAID, "%s: mpi_get_raid unable to fetch header"
2303 		    "for IOC page 2\n", DEVNAME(sc));
2304 		return;
2305 	}
2306 
2307 	pagelen = hdr.page_length * 4; /* dwords to bytes */
2308 	vol_page = malloc(pagelen, M_TEMP, M_WAITOK|M_CANFAIL);
2309 	if (vol_page == NULL) {
2310 		DNPRINTF(MPI_D_RAID, "%s: mpi_get_raid unable to allocate "
2311 		    "space for ioc config page 2\n", DEVNAME(sc));
2312 		return;
2313 	}
2314 	vol_list = (struct mpi_cfg_raid_vol *)(vol_page + 1);
2315 
2316 	if (mpi_cfg_page(sc, 0, &hdr, 1, vol_page, pagelen) != 0) {
2317 		DNPRINTF(MPI_D_RAID, "%s: mpi_get_raid unable to fetch IOC "
2318 		    "page 2\n", DEVNAME(sc));
2319 		goto out;
2320 	}
2321 
2322 	capabilities = letoh32(vol_page->capabilities);
2323 
2324 	DNPRINTF(MPI_D_RAID, "%s:  capabilities: 0x08%x\n", DEVNAME(sc),
2325 	    letoh32(vol_page->capabilities));
2326 	DNPRINTF(MPI_D_RAID, "%s:  active_vols: %d max_vols: %d "
2327 	    "active_physdisks: %d max_physdisks: %d\n", DEVNAME(sc),
2328 	    vol_page->active_vols, vol_page->max_vols,
2329 	    vol_page->active_physdisks, vol_page->max_physdisks);
2330 
2331 	/* don't walk list if there are no RAID capability */
2332 	if (capabilities == 0xdeadbeef) {
2333 		printf("%s: deadbeef in raid configuration\n", DEVNAME(sc));
2334 		goto out;
2335 	}
2336 
2337 	if ((capabilities & MPI_CFG_IOC_2_CAPABILITIES_RAID) == 0 ||
2338 	    (vol_page->active_vols == 0))
2339 		goto out;
2340 
2341 	sc->sc_flags |= MPI_F_RAID;
2342 
2343 	for (i = 0; i < vol_page->active_vols; i++) {
2344 		vol = &vol_list[i];
2345 
2346 		DNPRINTF(MPI_D_RAID, "%s:   id: %d bus: %d ioc: %d pg: %d\n",
2347 		    DEVNAME(sc), vol->vol_id, vol->vol_bus, vol->vol_ioc,
2348 		    vol->vol_page);
2349 		DNPRINTF(MPI_D_RAID, "%s:   type: 0x%02x flags: 0x%02x\n",
2350 		    DEVNAME(sc), vol->vol_type, vol->flags);
2351 
2352 		if (vol->vol_ioc != sc->sc_ioc_number || vol->vol_bus != 0)
2353 			continue;
2354 
2355 		link = sc->sc_scsibus->sc_link[vol->vol_id][0];
2356 		if (link == NULL)
2357 			continue;
2358 
2359 		link->flags |= SDEV_VIRTUAL;
2360 	}
2361 
2362 out:
2363 	free(vol_page, M_TEMP);
2364 }
2365 
2366 int
2367 mpi_req_cfg_header(struct mpi_softc *sc, u_int8_t type, u_int8_t number,
2368     u_int32_t address, int extended, void *p)
2369 {
2370 	struct mpi_ccb				*ccb;
2371 	struct mpi_msg_config_request		*cq;
2372 	struct mpi_msg_config_reply		*cp;
2373 	struct mpi_cfg_hdr			*hdr = p;
2374 	struct mpi_ecfg_hdr			*ehdr = p;
2375 	int					etype = 0;
2376 	int					rv = 0;
2377 	int					s;
2378 
2379 	DNPRINTF(MPI_D_MISC, "%s: mpi_req_cfg_header type: %#x number: %x "
2380 	    "address: 0x%08x extended: %d\n", DEVNAME(sc), type, number,
2381 	    address, extended);
2382 
2383 	s = splbio();
2384 	ccb = mpi_get_ccb(sc);
2385 	splx(s);
2386 	if (ccb == NULL) {
2387 		DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_header ccb_get\n",
2388 		    DEVNAME(sc));
2389 		return (1);
2390 	}
2391 
2392 	if (extended) {
2393 		etype = type;
2394 		type = MPI_CONFIG_REQ_PAGE_TYPE_EXTENDED;
2395 	}
2396 
2397 	ccb->ccb_done = mpi_empty_done;
2398 	cq = ccb->ccb_cmd;
2399 
2400 	cq->function = MPI_FUNCTION_CONFIG;
2401 	cq->msg_context = htole32(ccb->ccb_id);
2402 
2403 	cq->action = MPI_CONFIG_REQ_ACTION_PAGE_HEADER;
2404 
2405 	cq->config_header.page_number = number;
2406 	cq->config_header.page_type = type;
2407 	cq->ext_page_type = etype;
2408 	cq->page_address = htole32(address);
2409 	cq->page_buffer.sg_hdr = htole32(MPI_SGE_FL_TYPE_SIMPLE |
2410 	    MPI_SGE_FL_LAST | MPI_SGE_FL_EOB | MPI_SGE_FL_EOL);
2411 
2412 	if (mpi_poll(sc, ccb, 50000) != 0) {
2413 		DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_header poll\n", DEVNAME(sc));
2414 		return (1);
2415 	}
2416 
2417 	if (ccb->ccb_rcb == NULL)
2418 		panic("%s: unable to fetch config header\n", DEVNAME(sc));
2419 	cp = ccb->ccb_rcb->rcb_reply;
2420 
2421 	DNPRINTF(MPI_D_MISC, "%s:  action: 0x%02x msg_length: %d function: "
2422 	    "0x%02x\n", DEVNAME(sc), cp->action, cp->msg_length, cp->function);
2423 	DNPRINTF(MPI_D_MISC, "%s:  ext_page_length: %d ext_page_type: 0x%02x "
2424 	    "msg_flags: 0x%02x\n", DEVNAME(sc),
2425 	    letoh16(cp->ext_page_length), cp->ext_page_type,
2426 	    cp->msg_flags);
2427 	DNPRINTF(MPI_D_MISC, "%s:  msg_context: 0x%08x\n", DEVNAME(sc),
2428 	    letoh32(cp->msg_context));
2429 	DNPRINTF(MPI_D_MISC, "%s:  ioc_status: 0x%04x\n", DEVNAME(sc),
2430 	    letoh16(cp->ioc_status));
2431 	DNPRINTF(MPI_D_MISC, "%s:  ioc_loginfo: 0x%08x\n", DEVNAME(sc),
2432 	    letoh32(cp->ioc_loginfo));
2433 	DNPRINTF(MPI_D_MISC, "%s:  page_version: 0x%02x page_length: %d "
2434 	    "page_number: 0x%02x page_type: 0x%02x\n", DEVNAME(sc),
2435 	    cp->config_header.page_version,
2436 	    cp->config_header.page_length,
2437 	    cp->config_header.page_number,
2438 	    cp->config_header.page_type);
2439 
2440 	if (letoh16(cp->ioc_status) != MPI_IOCSTATUS_SUCCESS)
2441 		rv = 1;
2442 	else if (extended) {
2443 		bzero(ehdr, sizeof(*ehdr));
2444 		ehdr->page_version = cp->config_header.page_version;
2445 		ehdr->page_number = cp->config_header.page_number;
2446 		ehdr->page_type = cp->config_header.page_type;
2447 		ehdr->ext_page_length = cp->ext_page_length;
2448 		ehdr->ext_page_type = cp->ext_page_type;
2449 	} else
2450 		*hdr = cp->config_header;
2451 
2452 	mpi_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
2453 	mpi_put_ccb(sc, ccb);
2454 
2455 	return (rv);
2456 }
2457 
2458 int
2459 mpi_req_cfg_page(struct mpi_softc *sc, u_int32_t address, int extended,
2460     void *p, int read, void *page, size_t len)
2461 {
2462 	struct mpi_ccb				*ccb;
2463 	struct mpi_msg_config_request		*cq;
2464 	struct mpi_msg_config_reply		*cp;
2465 	struct mpi_cfg_hdr			*hdr = p;
2466 	struct mpi_ecfg_hdr			*ehdr = p;
2467 	u_int64_t				dva;
2468 	char					*kva;
2469 	int					page_length;
2470 	int					rv = 0;
2471 	int					s;
2472 
2473 	DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_page address: %d read: %d type: %x\n",
2474 	    DEVNAME(sc), address, read, hdr->page_type);
2475 
2476 	page_length = extended ?
2477 	    letoh16(ehdr->ext_page_length) : hdr->page_length;
2478 
2479 	if (len > MPI_REQUEST_SIZE - sizeof(struct mpi_msg_config_request) ||
2480 	    len < page_length * 4)
2481 		return (1);
2482 
2483 	s = splbio();
2484 	ccb = mpi_get_ccb(sc);
2485 	splx(s);
2486 	if (ccb == NULL) {
2487 		DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_page ccb_get\n", DEVNAME(sc));
2488 		return (1);
2489 	}
2490 
2491 	ccb->ccb_done = mpi_empty_done;
2492 	cq = ccb->ccb_cmd;
2493 
2494 	cq->function = MPI_FUNCTION_CONFIG;
2495 	cq->msg_context = htole32(ccb->ccb_id);
2496 
2497 	cq->action = (read ? MPI_CONFIG_REQ_ACTION_PAGE_READ_CURRENT :
2498 	    MPI_CONFIG_REQ_ACTION_PAGE_WRITE_CURRENT);
2499 
2500 	if (extended) {
2501 		cq->config_header.page_version = ehdr->page_version;
2502 		cq->config_header.page_number = ehdr->page_number;
2503 		cq->config_header.page_type = ehdr->page_type;
2504 		cq->ext_page_len = ehdr->ext_page_length;
2505 		cq->ext_page_type = ehdr->ext_page_type;
2506 	} else
2507 		cq->config_header = *hdr;
2508 	cq->config_header.page_type &= MPI_CONFIG_REQ_PAGE_TYPE_MASK;
2509 	cq->page_address = htole32(address);
2510 	cq->page_buffer.sg_hdr = htole32(MPI_SGE_FL_TYPE_SIMPLE |
2511 	    MPI_SGE_FL_LAST | MPI_SGE_FL_EOB | MPI_SGE_FL_EOL |
2512 	    (page_length * 4) |
2513 	    (read ? MPI_SGE_FL_DIR_IN : MPI_SGE_FL_DIR_OUT));
2514 
2515 	/* bounce the page via the request space to avoid more bus_dma games */
2516 	dva = ccb->ccb_cmd_dva + sizeof(struct mpi_msg_config_request);
2517 
2518 	cq->page_buffer.sg_hi_addr = htole32((u_int32_t)(dva >> 32));
2519 	cq->page_buffer.sg_lo_addr = htole32((u_int32_t)dva);
2520 
2521 	kva = ccb->ccb_cmd;
2522 	kva += sizeof(struct mpi_msg_config_request);
2523 	if (!read)
2524 		bcopy(page, kva, len);
2525 
2526 	if (mpi_poll(sc, ccb, 50000) != 0) {
2527 		DNPRINTF(MPI_D_MISC, "%s: mpi_cfg_page poll\n", DEVNAME(sc));
2528 		return (1);
2529 	}
2530 
2531 	if (ccb->ccb_rcb == NULL) {
2532 		mpi_put_ccb(sc, ccb);
2533 		return (1);
2534 	}
2535 	cp = ccb->ccb_rcb->rcb_reply;
2536 
2537 	DNPRINTF(MPI_D_MISC, "%s:  action: 0x%02x msg_length: %d function: "
2538 	    "0x%02x\n", DEVNAME(sc), cp->action, cp->msg_length, cp->function);
2539 	DNPRINTF(MPI_D_MISC, "%s:  ext_page_length: %d ext_page_type: 0x%02x "
2540 	    "msg_flags: 0x%02x\n", DEVNAME(sc),
2541 	    letoh16(cp->ext_page_length), cp->ext_page_type,
2542 	    cp->msg_flags);
2543 	DNPRINTF(MPI_D_MISC, "%s:  msg_context: 0x%08x\n", DEVNAME(sc),
2544 	    letoh32(cp->msg_context));
2545 	DNPRINTF(MPI_D_MISC, "%s:  ioc_status: 0x%04x\n", DEVNAME(sc),
2546 	    letoh16(cp->ioc_status));
2547 	DNPRINTF(MPI_D_MISC, "%s:  ioc_loginfo: 0x%08x\n", DEVNAME(sc),
2548 	    letoh32(cp->ioc_loginfo));
2549 	DNPRINTF(MPI_D_MISC, "%s:  page_version: 0x%02x page_length: %d "
2550 	    "page_number: 0x%02x page_type: 0x%02x\n", DEVNAME(sc),
2551 	    cp->config_header.page_version,
2552 	    cp->config_header.page_length,
2553 	    cp->config_header.page_number,
2554 	    cp->config_header.page_type);
2555 
2556 	if (letoh16(cp->ioc_status) != MPI_IOCSTATUS_SUCCESS)
2557 		rv = 1;
2558 	else if (read)
2559 		bcopy(kva, page, len);
2560 
2561 	mpi_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
2562 	mpi_put_ccb(sc, ccb);
2563 
2564 	return (rv);
2565 }
2566 
2567 int
2568 mpi_scsi_ioctl(struct scsi_link *link, u_long cmd, caddr_t addr, int flag,
2569     struct proc *p)
2570 {
2571 	struct mpi_softc	*sc = (struct mpi_softc *)link->adapter_softc;
2572 
2573 	DNPRINTF(MPI_D_IOCTL, "%s: mpi_scsi_ioctl\n", DEVNAME(sc));
2574 
2575 	if (sc->sc_ioctl)
2576 		return (sc->sc_ioctl(link->adapter_softc, cmd, addr));
2577 	else
2578 		return (ENOTTY);
2579 }
2580 
2581 #if NBIO > 0
2582 int
2583 mpi_bio_get_pg0_raid(struct mpi_softc *sc, int id)
2584 {
2585 	int			len, rv = EINVAL;
2586 	u_int32_t		address;
2587 	struct mpi_cfg_hdr	hdr;
2588 	struct mpi_cfg_raid_vol_pg0 *rpg0;
2589 
2590 	/* get IOC page 2 */
2591 	if (mpi_cfg_page(sc, 0, &sc->sc_cfg_hdr, 1, sc->sc_vol_page,
2592 	    sc->sc_cfg_hdr.page_length * 4) != 0) {
2593 		DNPRINTF(MPI_D_IOCTL, "%s: mpi_bio_get_pg0_raid unable to "
2594 		    "fetch IOC page 2\n", DEVNAME(sc));
2595 		goto done;
2596 	}
2597 
2598 	/* XXX return something else than EINVAL to indicate within hs range */
2599 	if (id > sc->sc_vol_page->active_vols) {
2600 		DNPRINTF(MPI_D_IOCTL, "%s: mpi_bio_get_pg0_raid invalid vol "
2601 		    "id: %d\n", DEVNAME(sc), id);
2602 		goto done;
2603 	}
2604 
2605 	/* replace current buffer with new one */
2606 	len = sizeof *rpg0 + sc->sc_vol_page->max_physdisks *
2607 	    sizeof(struct mpi_cfg_raid_vol_pg0_physdisk);
2608 	rpg0 = malloc(len, M_TEMP, M_WAITOK | M_CANFAIL);
2609 	if (rpg0 == NULL) {
2610 		printf("%s: can't get memory for RAID page 0, "
2611 		    "bio disabled\n", DEVNAME(sc));
2612 		goto done;
2613 	}
2614 	if (sc->sc_rpg0)
2615 		free(sc->sc_rpg0, M_DEVBUF);
2616 	sc->sc_rpg0 = rpg0;
2617 
2618 	/* get raid vol page 0 */
2619 	address = sc->sc_vol_list[id].vol_id |
2620 	    (sc->sc_vol_list[id].vol_bus << 8);
2621 	if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_RAID_VOL, 0,
2622 	    address, &hdr) != 0)
2623 		goto done;
2624 	if (mpi_cfg_page(sc, address, &hdr, 1, rpg0, len)) {
2625 		printf("%s: can't get RAID vol cfg page 0\n", DEVNAME(sc));
2626 		goto done;
2627 	}
2628 
2629 	rv = 0;
2630 done:
2631 	return (rv);
2632 }
2633 
2634 int
2635 mpi_ioctl(struct device *dev, u_long cmd, caddr_t addr)
2636 {
2637 	struct mpi_softc	*sc = (struct mpi_softc *)dev;
2638 	int error = 0;
2639 
2640 	DNPRINTF(MPI_D_IOCTL, "%s: mpi_ioctl ", DEVNAME(sc));
2641 
2642 	/* make sure we have bio enabled */
2643 	if (sc->sc_ioctl != mpi_ioctl)
2644 		return (EINVAL);
2645 
2646 	rw_enter_write(&sc->sc_lock);
2647 
2648 	switch (cmd) {
2649 	case BIOCINQ:
2650 		DNPRINTF(MPI_D_IOCTL, "inq\n");
2651 		error = mpi_ioctl_inq(sc, (struct bioc_inq *)addr);
2652 		break;
2653 
2654 	case BIOCVOL:
2655 		DNPRINTF(MPI_D_IOCTL, "vol\n");
2656 		error = mpi_ioctl_vol(sc, (struct bioc_vol *)addr);
2657 		break;
2658 
2659 	case BIOCDISK:
2660 		DNPRINTF(MPI_D_IOCTL, "disk\n");
2661 		error = mpi_ioctl_disk(sc, (struct bioc_disk *)addr);
2662 		break;
2663 
2664 	case BIOCALARM:
2665 		DNPRINTF(MPI_D_IOCTL, "alarm\n");
2666 		break;
2667 
2668 	case BIOCBLINK:
2669 		DNPRINTF(MPI_D_IOCTL, "blink\n");
2670 		break;
2671 
2672 	case BIOCSETSTATE:
2673 		DNPRINTF(MPI_D_IOCTL, "setstate\n");
2674 		error = mpi_ioctl_setstate(sc, (struct bioc_setstate *)addr);
2675 		break;
2676 
2677 	default:
2678 		DNPRINTF(MPI_D_IOCTL, " invalid ioctl\n");
2679 		error = EINVAL;
2680 	}
2681 
2682 	rw_exit_write(&sc->sc_lock);
2683 
2684 	return (error);
2685 }
2686 
2687 int
2688 mpi_ioctl_inq(struct mpi_softc *sc, struct bioc_inq *bi)
2689 {
2690 	if (!(sc->sc_flags & MPI_F_RAID)) {
2691 		bi->bi_novol = 0;
2692 		bi->bi_nodisk = 0;
2693 	}
2694 
2695 	if (mpi_cfg_page(sc, 0, &sc->sc_cfg_hdr, 1, sc->sc_vol_page,
2696 	    sc->sc_cfg_hdr.page_length * 4) != 0) {
2697 		DNPRINTF(MPI_D_IOCTL, "%s: mpi_get_raid unable to fetch IOC "
2698 		    "page 2\n", DEVNAME(sc));
2699 		return (EINVAL);
2700 	}
2701 
2702 	DNPRINTF(MPI_D_IOCTL, "%s:  active_vols: %d max_vols: %d "
2703 	    "active_physdisks: %d max_physdisks: %d\n", DEVNAME(sc),
2704 	    sc->sc_vol_page->active_vols, sc->sc_vol_page->max_vols,
2705 	    sc->sc_vol_page->active_physdisks, sc->sc_vol_page->max_physdisks);
2706 
2707 	bi->bi_novol = sc->sc_vol_page->active_vols;
2708 	bi->bi_nodisk = sc->sc_vol_page->active_physdisks;
2709 	strlcpy(bi->bi_dev, DEVNAME(sc), sizeof(bi->bi_dev));
2710 
2711 	return (0);
2712 }
2713 
2714 int
2715 mpi_ioctl_vol(struct mpi_softc *sc, struct bioc_vol *bv)
2716 {
2717 	int			i, vol, id, rv = EINVAL;
2718 	struct device		*dev;
2719 	struct scsi_link	*link;
2720 	struct mpi_cfg_raid_vol_pg0 *rpg0;
2721 
2722 	id = bv->bv_volid;
2723 	if (mpi_bio_get_pg0_raid(sc, id))
2724 		goto done;
2725 
2726 	if (id > sc->sc_vol_page->active_vols)
2727 		return (EINVAL); /* XXX deal with hot spares */
2728 
2729 	rpg0 = sc->sc_rpg0;
2730 	if (rpg0 == NULL)
2731 		goto done;
2732 
2733 	/* determine status */
2734 	switch (rpg0->volume_state) {
2735 	case MPI_CFG_RAID_VOL_0_STATE_OPTIMAL:
2736 		bv->bv_status = BIOC_SVONLINE;
2737 		break;
2738 	case MPI_CFG_RAID_VOL_0_STATE_DEGRADED:
2739 		bv->bv_status = BIOC_SVDEGRADED;
2740 		break;
2741 	case MPI_CFG_RAID_VOL_0_STATE_FAILED:
2742 	case MPI_CFG_RAID_VOL_0_STATE_MISSING:
2743 		bv->bv_status = BIOC_SVOFFLINE;
2744 		break;
2745 	default:
2746 		bv->bv_status = BIOC_SVINVALID;
2747 	}
2748 
2749 	/* override status if scrubbing or something */
2750 	if (rpg0->volume_status & MPI_CFG_RAID_VOL_0_STATUS_RESYNCING)
2751 		bv->bv_status = BIOC_SVREBUILD;
2752 
2753 	bv->bv_size = (u_quad_t)letoh32(rpg0->max_lba) * 512;
2754 
2755 	switch (sc->sc_vol_list[id].vol_type) {
2756 	case MPI_CFG_RAID_TYPE_RAID_IS:
2757 		bv->bv_level = 0;
2758 		break;
2759 	case MPI_CFG_RAID_TYPE_RAID_IME:
2760 	case MPI_CFG_RAID_TYPE_RAID_IM:
2761 		bv->bv_level = 1;
2762 		break;
2763 	case MPI_CFG_RAID_TYPE_RAID_5:
2764 		bv->bv_level = 5;
2765 		break;
2766 	case MPI_CFG_RAID_TYPE_RAID_6:
2767 		bv->bv_level = 6;
2768 		break;
2769 	case MPI_CFG_RAID_TYPE_RAID_10:
2770 		bv->bv_level = 10;
2771 		break;
2772 	case MPI_CFG_RAID_TYPE_RAID_50:
2773 		bv->bv_level = 50;
2774 		break;
2775 	default:
2776 		bv->bv_level = -1;
2777 	}
2778 
2779 	bv->bv_nodisk = rpg0->num_phys_disks;
2780 
2781 	for (i = 0, vol = -1; i < sc->sc_buswidth; i++) {
2782 		link = sc->sc_scsibus->sc_link[i][0];
2783 		if (link == NULL)
2784 			continue;
2785 
2786 		/* skip if not a virtual disk */
2787 		if (!(link->flags & SDEV_VIRTUAL))
2788 			continue;
2789 
2790 		vol++;
2791 		/* are we it? */
2792 		if (vol == bv->bv_volid) {
2793 			dev = link->device_softc;
2794 			memcpy(bv->bv_vendor, link->inqdata.vendor,
2795 			    sizeof bv->bv_vendor);
2796 			bv->bv_vendor[sizeof(bv->bv_vendor) - 1] = '\0';
2797 			strlcpy(bv->bv_dev, dev->dv_xname, sizeof bv->bv_dev);
2798 			break;
2799 		}
2800 	}
2801 	rv = 0;
2802 done:
2803 	return (rv);
2804 }
2805 
2806 int
2807 mpi_ioctl_disk(struct mpi_softc *sc, struct bioc_disk *bd)
2808 {
2809 	int			pdid, id, rv = EINVAL;
2810 	u_int32_t		address;
2811 	struct mpi_cfg_hdr	hdr;
2812 	struct mpi_cfg_raid_vol_pg0 *rpg0;
2813 	struct mpi_cfg_raid_vol_pg0_physdisk *physdisk;
2814 	struct mpi_cfg_raid_physdisk_pg0 pdpg0;
2815 
2816 	id = bd->bd_volid;
2817 	if (mpi_bio_get_pg0_raid(sc, id))
2818 		goto done;
2819 
2820 	if (id > sc->sc_vol_page->active_vols)
2821 		return (EINVAL); /* XXX deal with hot spares */
2822 
2823 	rpg0 = sc->sc_rpg0;
2824 	if (rpg0 == NULL)
2825 		goto done;
2826 
2827 	pdid = bd->bd_diskid;
2828 	if (pdid > rpg0->num_phys_disks)
2829 		goto done;
2830 	physdisk = (struct mpi_cfg_raid_vol_pg0_physdisk *)(rpg0 + 1);
2831 	physdisk += pdid;
2832 
2833 	/* get raid phys disk page 0 */
2834 	address = physdisk->phys_disk_num;
2835 	if (mpi_cfg_header(sc, MPI_CONFIG_REQ_PAGE_TYPE_RAID_PD, 0, address,
2836 	    &hdr) != 0)
2837 		goto done;
2838 	if (mpi_cfg_page(sc, address, &hdr, 1, &pdpg0, sizeof pdpg0)) {
2839 		bd->bd_status = BIOC_SDFAILED;
2840 		return (0);
2841 	}
2842 	bd->bd_channel = pdpg0.phys_disk_bus;
2843 	bd->bd_target = pdpg0.phys_disk_id;
2844 	bd->bd_lun = 0;
2845 	bd->bd_size = (u_quad_t)pdpg0.max_lba * 512;
2846 	strlcpy(bd->bd_vendor, pdpg0.vendor_id, sizeof(bd->bd_vendor));
2847 
2848 	switch (pdpg0.phys_disk_state) {
2849 	case MPI_CFG_RAID_PHYDISK_0_STATE_ONLINE:
2850 		bd->bd_status = BIOC_SDONLINE;
2851 		break;
2852 	case MPI_CFG_RAID_PHYDISK_0_STATE_MISSING:
2853 	case MPI_CFG_RAID_PHYDISK_0_STATE_FAILED:
2854 		bd->bd_status = BIOC_SDFAILED;
2855 		break;
2856 	case MPI_CFG_RAID_PHYDISK_0_STATE_HOSTFAIL:
2857 	case MPI_CFG_RAID_PHYDISK_0_STATE_OTHER:
2858 	case MPI_CFG_RAID_PHYDISK_0_STATE_OFFLINE:
2859 		bd->bd_status = BIOC_SDOFFLINE;
2860 		break;
2861 	case MPI_CFG_RAID_PHYDISK_0_STATE_INIT:
2862 		bd->bd_status = BIOC_SDSCRUB;
2863 		break;
2864 	case MPI_CFG_RAID_PHYDISK_0_STATE_INCOMPAT:
2865 	default:
2866 		bd->bd_status = BIOC_SDINVALID;
2867 		break;
2868 	}
2869 
2870 	/* XXX figure this out */
2871 	/* bd_serial[32]; */
2872 	/* bd_procdev[16]; */
2873 
2874 	rv = 0;
2875 done:
2876 	return (rv);
2877 }
2878 
2879 int
2880 mpi_ioctl_setstate(struct mpi_softc *sc, struct bioc_setstate *bs)
2881 {
2882 	return (ENOTTY);
2883 }
2884 
2885 #ifndef SMALL_KERNEL
2886 int
2887 mpi_create_sensors(struct mpi_softc *sc)
2888 {
2889 	struct device		*dev;
2890 	struct scsi_link	*link;
2891 	int			i, vol;
2892 
2893 	/* count volumes */
2894 	for (i = 0, vol = 0; i < sc->sc_buswidth; i++) {
2895 		link = sc->sc_scsibus->sc_link[i][0];
2896 		if (link == NULL)
2897 			continue;
2898 		/* skip if not a virtual disk */
2899 		if (!(link->flags & SDEV_VIRTUAL))
2900 			continue;
2901 
2902 		vol++;
2903 	}
2904 
2905 	sc->sc_sensors = malloc(sizeof(struct ksensor) * vol,
2906 	    M_DEVBUF, M_WAITOK|M_ZERO);
2907 	if (sc->sc_sensors == NULL)
2908 		return (1);
2909 
2910 	strlcpy(sc->sc_sensordev.xname, DEVNAME(sc),
2911 	    sizeof(sc->sc_sensordev.xname));
2912 
2913 	for (i = 0, vol= 0; i < sc->sc_buswidth; i++) {
2914 		link = sc->sc_scsibus->sc_link[i][0];
2915 		if (link == NULL)
2916 			continue;
2917 		/* skip if not a virtual disk */
2918 		if (!(link->flags & SDEV_VIRTUAL))
2919 			continue;
2920 
2921 		dev = link->device_softc;
2922 		strlcpy(sc->sc_sensors[vol].desc, dev->dv_xname,
2923 		    sizeof(sc->sc_sensors[vol].desc));
2924 		sc->sc_sensors[vol].type = SENSOR_DRIVE;
2925 		sc->sc_sensors[vol].status = SENSOR_S_UNKNOWN;
2926 		sensor_attach(&sc->sc_sensordev, &sc->sc_sensors[vol]);
2927 
2928 		vol++;
2929 	}
2930 
2931 	if (sensor_task_register(sc, mpi_refresh_sensors, 10) == NULL)
2932 		goto bad;
2933 
2934 	sensordev_install(&sc->sc_sensordev);
2935 
2936 	return (0);
2937 
2938 bad:
2939 	free(sc->sc_sensors, M_DEVBUF);
2940 	return (1);
2941 }
2942 
2943 void
2944 mpi_refresh_sensors(void *arg)
2945 {
2946 	int			i, vol;
2947 	struct scsi_link	*link;
2948 	struct mpi_softc	*sc = arg;
2949 	struct mpi_cfg_raid_vol_pg0 *rpg0;
2950 
2951 	rw_enter_write(&sc->sc_lock);
2952 
2953 	for (i = 0, vol = 0; i < sc->sc_buswidth; i++) {
2954 		link = sc->sc_scsibus->sc_link[i][0];
2955 		if (link == NULL)
2956 			continue;
2957 		/* skip if not a virtual disk */
2958 		if (!(link->flags & SDEV_VIRTUAL))
2959 			continue;
2960 
2961 		if (mpi_bio_get_pg0_raid(sc, vol))
2962 			continue;
2963 
2964 		rpg0 = sc->sc_rpg0;
2965 		if (rpg0 == NULL)
2966 			goto done;
2967 
2968 		/* determine status */
2969 		switch (rpg0->volume_state) {
2970 		case MPI_CFG_RAID_VOL_0_STATE_OPTIMAL:
2971 			sc->sc_sensors[vol].value = SENSOR_DRIVE_ONLINE;
2972 			sc->sc_sensors[vol].status = SENSOR_S_OK;
2973 			break;
2974 		case MPI_CFG_RAID_VOL_0_STATE_DEGRADED:
2975 			sc->sc_sensors[vol].value = SENSOR_DRIVE_PFAIL;
2976 			sc->sc_sensors[vol].status = SENSOR_S_WARN;
2977 			break;
2978 		case MPI_CFG_RAID_VOL_0_STATE_FAILED:
2979 		case MPI_CFG_RAID_VOL_0_STATE_MISSING:
2980 			sc->sc_sensors[vol].value = SENSOR_DRIVE_FAIL;
2981 			sc->sc_sensors[vol].status = SENSOR_S_CRIT;
2982 			break;
2983 		default:
2984 			sc->sc_sensors[vol].value = 0; /* unknown */
2985 			sc->sc_sensors[vol].status = SENSOR_S_UNKNOWN;
2986 		}
2987 
2988 		/* override status if scrubbing or something */
2989 		if (rpg0->volume_status & MPI_CFG_RAID_VOL_0_STATUS_RESYNCING) {
2990 			sc->sc_sensors[vol].value = SENSOR_DRIVE_REBUILD;
2991 			sc->sc_sensors[vol].status = SENSOR_S_WARN;
2992 		}
2993 
2994 		vol++;
2995 	}
2996 done:
2997 	rw_exit_write(&sc->sc_lock);
2998 }
2999 #endif /* SMALL_KERNEL */
3000 #endif /* NBIO > 0 */
3001