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