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