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