xref: /freebsd/sys/dev/mps/mps_sas.c (revision 66e576525d35c68fcb86f142ebaa5a448555c0c7)
1 /*-
2  * Copyright (c) 2009 Yahoo! Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29 
30 /* Communications core for LSI MPT2 */
31 
32 #include <sys/types.h>
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/kernel.h>
36 #include <sys/selinfo.h>
37 #include <sys/module.h>
38 #include <sys/bus.h>
39 #include <sys/conf.h>
40 #include <sys/bio.h>
41 #include <sys/malloc.h>
42 #include <sys/uio.h>
43 #include <sys/sysctl.h>
44 
45 #include <machine/bus.h>
46 #include <machine/resource.h>
47 #include <sys/rman.h>
48 
49 #include <cam/cam.h>
50 #include <cam/cam_ccb.h>
51 #include <cam/cam_debug.h>
52 #include <cam/cam_sim.h>
53 #include <cam/cam_xpt_sim.h>
54 #include <cam/cam_xpt_periph.h>
55 #include <cam/cam_periph.h>
56 #include <cam/scsi/scsi_all.h>
57 #include <cam/scsi/scsi_message.h>
58 
59 #include <dev/mps/mpi/mpi2_type.h>
60 #include <dev/mps/mpi/mpi2.h>
61 #include <dev/mps/mpi/mpi2_ioc.h>
62 #include <dev/mps/mpi/mpi2_sas.h>
63 #include <dev/mps/mpi/mpi2_cnfg.h>
64 #include <dev/mps/mpi/mpi2_init.h>
65 #include <dev/mps/mpsvar.h>
66 #include <dev/mps/mps_table.h>
67 
68 struct mpssas_target {
69 	uint16_t	handle;
70 	uint8_t		linkrate;
71 	uint64_t	devname;
72 	uint32_t	devinfo;
73 	uint16_t	encl_handle;
74 	uint16_t	encl_slot;
75 	int		flags;
76 #define MPSSAS_TARGET_INABORT	(1 << 0)
77 #define MPSSAS_TARGET_INRESET	(1 << 1)
78 #define MPSSAS_TARGET_INCHIPRESET (1 << 2)
79 #define MPSSAS_TARGET_INRECOVERY 0x7
80 	uint16_t	tid;
81 };
82 
83 struct mpssas_softc {
84 	struct mps_softc	*sc;
85 	u_int			flags;
86 #define MPSSAS_IN_DISCOVERY	(1 << 0)
87 #define MPSSAS_IN_STARTUP	(1 << 1)
88 #define MPSSAS_DISCOVERY_TIMEOUT_PENDING	(1 << 2)
89 #define MPSSAS_QUEUE_FROZEN	(1 << 3)
90 	struct mpssas_target	*targets;
91 	struct cam_devq		*devq;
92 	struct cam_sim		*sim;
93 	struct cam_path		*path;
94 	struct intr_config_hook	sas_ich;
95 	struct callout		discovery_callout;
96 	u_int			discovery_timeouts;
97 	struct mps_event_handle	*mpssas_eh;
98 };
99 
100 struct mpssas_devprobe {
101 	struct mps_config_params	params;
102 	u_int			state;
103 #define MPSSAS_PROBE_DEV1	0x01
104 #define MPSSAS_PROBE_DEV2	0x02
105 #define MPSSAS_PROBE_PHY	0x03
106 #define MPSSAS_PROBE_EXP	0x04
107 #define MPSSAS_PROBE_PHY2	0x05
108 #define MPSSAS_PROBE_EXP2	0x06
109 	struct mpssas_target	target;
110 };
111 
112 #define MPSSAS_DISCOVERY_TIMEOUT	20
113 #define MPSSAS_MAX_DISCOVERY_TIMEOUTS	10 /* 200 seconds */
114 
115 MALLOC_DEFINE(M_MPSSAS, "MPSSAS", "MPS SAS memory");
116 
117 static struct mpssas_target * mpssas_alloc_target(struct mpssas_softc *,
118     struct mpssas_target *);
119 static struct mpssas_target * mpssas_find_target(struct mpssas_softc *, int,
120      uint16_t);
121 static void mpssas_announce_device(struct mpssas_softc *,
122      struct mpssas_target *);
123 static void mpssas_startup(void *data);
124 static void mpssas_discovery_end(struct mpssas_softc *sassc);
125 static void mpssas_discovery_timeout(void *data);
126 static void mpssas_prepare_remove(struct mpssas_softc *,
127     MPI2_EVENT_SAS_TOPO_PHY_ENTRY *);
128 static void mpssas_remove_device(struct mps_softc *, struct mps_command *);
129 static void mpssas_remove_complete(struct mps_softc *, struct mps_command *);
130 static void mpssas_action(struct cam_sim *sim, union ccb *ccb);
131 static void mpssas_poll(struct cam_sim *sim);
132 static void mpssas_probe_device(struct mps_softc *sc, uint16_t handle);
133 static void mpssas_probe_device_complete(struct mps_softc *sc,
134      struct mps_config_params *params);
135 static void mpssas_scsiio_timeout(void *data);
136 static void mpssas_abort_complete(struct mps_softc *sc, struct mps_command *cm);
137 static void mpssas_recovery(struct mps_softc *, struct mps_command *);
138 static void mpssas_action_scsiio(struct mpssas_softc *, union ccb *);
139 static void mpssas_scsiio_complete(struct mps_softc *, struct mps_command *);
140 static int mpssas_resetdev(struct mpssas_softc *, struct mps_command *);
141 static void mpssas_action_resetdev(struct mpssas_softc *, union ccb *);
142 static void mpssas_resetdev_complete(struct mps_softc *, struct mps_command *);
143 static void mpssas_freeze_device(struct mpssas_softc *, struct mpssas_target *);
144 static void mpssas_unfreeze_device(struct mpssas_softc *, struct mpssas_target *) __unused;
145 
146 static struct mpssas_target *
147 mpssas_alloc_target(struct mpssas_softc *sassc, struct mpssas_target *probe)
148 {
149 	struct mpssas_target *target;
150 	int start;
151 
152 	mps_dprint(sassc->sc, MPS_TRACE, "%s\n", __func__);
153 
154 	/*
155 	 * If it's not a sata or sas target, CAM won't be able to see it.  Put
156 	 * it into a high-numbered slot so that it's accessible but not
157 	 * interrupting the target numbering sequence of real drives.
158 	 */
159 	if ((probe->devinfo & (MPI2_SAS_DEVICE_INFO_SSP_TARGET |
160 	    MPI2_SAS_DEVICE_INFO_STP_TARGET | MPI2_SAS_DEVICE_INFO_SATA_DEVICE))
161 	    == 0) {
162 		start = 200;
163 	} else {
164 		/*
165 		 * Use the enclosure number and slot number as a hint for target
166 		 * numbering.  If that doesn't produce a sane result, search the
167 		 * entire space.
168 		 */
169 #if 0
170 		start = probe->encl_handle * 16 + probe->encl_slot;
171 #else
172 		start = probe->encl_slot;
173 #endif
174 		if (start >= sassc->sc->facts->MaxTargets)
175 			start = 0;
176 	}
177 
178 	target = mpssas_find_target(sassc, start, 0);
179 
180 	/*
181 	 * Nothing found on the first pass, try a second pass that searches the
182 	 * entire space.
183 	 */
184 	if (target == NULL)
185 		target = mpssas_find_target(sassc, 0, 0);
186 
187 	return (target);
188 }
189 
190 static struct mpssas_target *
191 mpssas_find_target(struct mpssas_softc *sassc, int start, uint16_t handle)
192 {
193 	struct mpssas_target *target;
194 	int i;
195 
196 	for (i = start; i < sassc->sc->facts->MaxTargets; i++) {
197 		target = &sassc->targets[i];
198 		if (target->handle == handle)
199 			return (target);
200 	}
201 
202 	return (NULL);
203 }
204 
205 /*
206  * Start the probe sequence for a given device handle.  This will not
207  * block.
208  */
209 static void
210 mpssas_probe_device(struct mps_softc *sc, uint16_t handle)
211 {
212 	struct mpssas_devprobe *probe;
213 	struct mps_config_params *params;
214 	MPI2_CONFIG_EXTENDED_PAGE_HEADER *hdr;
215 	int error;
216 
217 	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
218 
219 	probe = malloc(sizeof(*probe), M_MPSSAS, M_NOWAIT | M_ZERO);
220 	if (probe == NULL) {
221 		mps_dprint(sc, MPS_FAULT, "Out of memory starting probe\n");
222 		return;
223 	}
224 	params = &probe->params;
225 	hdr = &params->hdr.Ext;
226 
227 	params->action = MPI2_CONFIG_ACTION_PAGE_HEADER;
228 	params->page_address = MPI2_SAS_DEVICE_PGAD_FORM_HANDLE | handle;
229 	hdr->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
230 	hdr->ExtPageLength = 0;
231 	hdr->PageNumber = 0;
232 	hdr->PageVersion = 0;
233 	params->buffer = NULL;
234 	params->length = 0;
235 	params->callback = mpssas_probe_device_complete;
236 	params->cbdata = probe;
237 	probe->target.handle = handle;
238 	probe->state = MPSSAS_PROBE_DEV1;
239 
240 	if ((error = mps_read_config_page(sc, params)) != 0) {
241 		free(probe, M_MPSSAS);
242 		mps_dprint(sc, MPS_FAULT, "Failure starting device probe\n");
243 		return;
244 	}
245 }
246 
247 static void
248 mpssas_probe_device_complete(struct mps_softc *sc,
249     struct mps_config_params *params)
250 {
251 	MPI2_CONFIG_EXTENDED_PAGE_HEADER *hdr;
252 	struct mpssas_devprobe *probe;
253 	int error;
254 
255 	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
256 
257 	hdr = &params->hdr.Ext;
258 	probe = params->cbdata;
259 
260 	switch (probe->state) {
261 	case MPSSAS_PROBE_DEV1:
262 	case MPSSAS_PROBE_PHY:
263 	case MPSSAS_PROBE_EXP:
264 		if (params->status != MPI2_IOCSTATUS_SUCCESS) {
265 			mps_dprint(sc, MPS_FAULT,
266 			    "Probe Failure 0x%x state %d\n", params->status,
267 			    probe->state);
268 			free(probe, M_MPSSAS);
269 			return;
270 		}
271 		params->action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
272 		params->length = hdr->ExtPageLength * 4;
273 		params->buffer = malloc(params->length, M_MPSSAS,
274 		    M_ZERO|M_NOWAIT);
275 		if (params->buffer == NULL) {
276 			mps_dprint(sc, MPS_FAULT, "Out of memory at state "
277 			   "0x%x, size 0x%x\n", probe->state, params->length);
278 			free(probe, M_MPSSAS);
279 			return;
280 		}
281 		if (probe->state == MPSSAS_PROBE_DEV1)
282 			probe->state = MPSSAS_PROBE_DEV2;
283 		else if (probe->state == MPSSAS_PROBE_PHY)
284 			probe->state = MPSSAS_PROBE_PHY2;
285 		else if (probe->state == MPSSAS_PROBE_EXP)
286 			probe->state = MPSSAS_PROBE_EXP2;
287 		error = mps_read_config_page(sc, params);
288 		break;
289 	case MPSSAS_PROBE_DEV2:
290 	{
291 		MPI2_CONFIG_PAGE_SAS_DEV_0 *buf;
292 
293 		if (params->status != MPI2_IOCSTATUS_SUCCESS) {
294 			mps_dprint(sc, MPS_FAULT,
295 			    "Probe Failure 0x%x state %d\n", params->status,
296 			    probe->state);
297 			free(params->buffer, M_MPSSAS);
298 			free(probe, M_MPSSAS);
299 			return;
300 		}
301 		buf = params->buffer;
302 		mps_print_sasdev0(sc, buf);
303 
304 		probe->target.devname = mps_to_u64(&buf->DeviceName);
305 		probe->target.devinfo = buf->DeviceInfo;
306 		probe->target.encl_handle = buf->EnclosureHandle;
307 		probe->target.encl_slot = buf->Slot;
308 
309 		if (buf->DeviceInfo & MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH) {
310 			params->page_address =
311 			    MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | buf->PhyNum;
312 			hdr->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
313 			hdr->PageNumber = 0;
314 			probe->state = MPSSAS_PROBE_PHY;
315 		} else {
316 			params->page_address =
317 			    MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |
318 			    buf->ParentDevHandle | (buf->PhyNum << 16);
319 			hdr->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
320 			hdr->PageNumber = 1;
321 			probe->state = MPSSAS_PROBE_EXP;
322 		}
323 		params->action = MPI2_CONFIG_ACTION_PAGE_HEADER;
324 		hdr->ExtPageLength = 0;
325 		hdr->PageVersion = 0;
326 		params->buffer = NULL;
327 		params->length = 0;
328 		free(buf, M_MPSSAS);
329 		error = mps_read_config_page(sc, params);
330 		break;
331 	}
332 	case MPSSAS_PROBE_PHY2:
333 	case MPSSAS_PROBE_EXP2:
334 	{
335 		MPI2_CONFIG_PAGE_SAS_PHY_0 *phy;
336 		MPI2_CONFIG_PAGE_EXPANDER_1 *exp;
337 		struct mpssas_softc *sassc;
338 		struct mpssas_target *targ;
339 		char devstring[80];
340 		uint16_t handle;
341 
342 		if (params->status != MPI2_IOCSTATUS_SUCCESS) {
343 			mps_dprint(sc, MPS_FAULT,
344 			    "Probe Failure 0x%x state %d\n", params->status,
345 			    probe->state);
346 			free(params->buffer, M_MPSSAS);
347 			free(probe, M_MPSSAS);
348 			return;
349 		}
350 
351 		if (probe->state == MPSSAS_PROBE_PHY2) {
352 			phy = params->buffer;
353 			mps_print_sasphy0(sc, phy);
354 			probe->target.linkrate = phy->NegotiatedLinkRate & 0xf;
355 		} else {
356 			exp = params->buffer;
357 			mps_print_expander1(sc, exp);
358 			probe->target.linkrate = exp->NegotiatedLinkRate & 0xf;
359 		}
360 		free(params->buffer, M_MPSSAS);
361 
362 		sassc = sc->sassc;
363 		handle = probe->target.handle;
364 		if ((targ = mpssas_find_target(sassc, 0, handle)) != NULL) {
365 			mps_printf(sc, "Ignoring dup device handle 0x%04x\n",
366 			    handle);
367 			free(probe, M_MPSSAS);
368 			return;
369 		}
370 		if ((targ = mpssas_alloc_target(sassc, &probe->target)) == NULL) {
371 			mps_printf(sc, "Target table overflow, handle 0x%04x\n",
372 			    handle);
373 			free(probe, M_MPSSAS);
374 			return;
375 		}
376 
377 		*targ = probe->target;	/* Copy the attributes */
378 		targ->tid = targ - sassc->targets;
379 		mps_describe_devinfo(targ->devinfo, devstring, 80);
380 		if (bootverbose)
381 			mps_printf(sc, "Found device <%s> <%s> <0x%04x> "
382 			    "<%d/%d>\n", devstring,
383 			    mps_describe_table(mps_linkrate_names,
384 			    targ->linkrate), targ->handle, targ->encl_handle,
385 			    targ->encl_slot);
386 
387 		free(probe, M_MPSSAS);
388 		mpssas_announce_device(sassc, targ);
389 		break;
390 	}
391 	default:
392 		printf("what?\n");
393 	}
394 }
395 
396 /*
397  * The MPT2 firmware performs debounce on the link to avoid transient link errors
398  * and false removals.  When it does decide that link has been lost and a device
399  * need to go away, it expects that the host will perform a target reset and then
400  * an op remove.  The reset has the side-effect of aborting any outstanding
401  * requests for the device, which is required for the op-remove to succeed.  It's
402  * not clear if the host should check for the device coming back alive after the
403  * reset.
404  */
405 static void
406 mpssas_prepare_remove(struct mpssas_softc *sassc, MPI2_EVENT_SAS_TOPO_PHY_ENTRY *phy)
407 {
408 	MPI2_SCSI_TASK_MANAGE_REQUEST *req;
409 	struct mps_softc *sc;
410 	struct mps_command *cm;
411 	struct mpssas_target *targ = NULL;
412 	uint16_t handle;
413 
414 	mps_dprint(sassc->sc, MPS_TRACE, "%s\n", __func__);
415 
416 	handle = phy->AttachedDevHandle;
417 	targ = mpssas_find_target(sassc, 0, handle);
418 	if (targ == NULL)
419 		/* We don't know about this device? */
420 		return;
421 
422 	sc = sassc->sc;
423 	cm = mps_alloc_command(sc);
424 	if (cm == NULL) {
425 		mps_printf(sc, "comand alloc failure in mpssas_prepare_remove\n");
426 		return;
427 	}
428 
429 	req = (MPI2_SCSI_TASK_MANAGE_REQUEST *)cm->cm_req;
430 	req->DevHandle = targ->handle;
431 	req->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
432 	req->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
433 
434 	/* SAS Hard Link Reset / SATA Link Reset */
435 	req->MsgFlags = MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET;
436 
437 	cm->cm_data = NULL;
438 	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
439 	cm->cm_complete = mpssas_remove_device;
440 	cm->cm_targ = targ;
441 	xpt_freeze_simq(sc->sassc->sim, 1);
442 	mps_map_command(sc, cm);
443 }
444 
445 static void
446 mpssas_remove_device(struct mps_softc *sc, struct mps_command *cm)
447 {
448 	MPI2_SCSI_TASK_MANAGE_REPLY *reply;
449 	MPI2_SAS_IOUNIT_CONTROL_REQUEST *req;
450 	struct mpssas_target *targ;
451 	uint16_t handle;
452 
453 	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
454 
455 	reply = (MPI2_SCSI_TASK_MANAGE_REPLY *)cm->cm_reply;
456 	handle = cm->cm_targ->handle;
457 	xpt_release_simq(sc->sassc->sim, 1);
458 	if (reply->IOCStatus != MPI2_IOCSTATUS_SUCCESS) {
459 		mps_printf(sc, "Failure 0x%x reseting device 0x%04x\n",
460 		   reply->IOCStatus, handle);
461 		mps_free_command(sc, cm);
462 		return;
463 	}
464 
465 	mps_printf(sc, "Reset aborted %d commands\n", reply->TerminationCount);
466 	mps_free_reply(sc, cm->cm_reply_data);
467 
468 	/* Reuse the existing command */
469 	req = (MPI2_SAS_IOUNIT_CONTROL_REQUEST *)cm->cm_req;
470 	req->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
471 	req->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
472 	req->DevHandle = handle;
473 	cm->cm_data = NULL;
474 	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
475 	cm->cm_flags &= ~MPS_CM_FLAGS_COMPLETE;
476 	cm->cm_complete = mpssas_remove_complete;
477 
478 	mps_map_command(sc, cm);
479 
480 	mps_dprint(sc, MPS_INFO, "clearing target handle 0x%04x\n", handle);
481 	targ = mpssas_find_target(sc->sassc, 0, handle);
482 	if (targ != NULL) {
483 		targ->handle = 0x0;
484 		mpssas_announce_device(sc->sassc, targ);
485 	}
486 }
487 
488 static void
489 mpssas_remove_complete(struct mps_softc *sc, struct mps_command *cm)
490 {
491 	MPI2_SAS_IOUNIT_CONTROL_REPLY *reply;
492 
493 	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
494 
495 	reply = (MPI2_SAS_IOUNIT_CONTROL_REPLY *)cm->cm_reply;
496 
497 	mps_printf(sc, "mpssas_remove_complete on target 0x%04x,"
498 	   " IOCStatus= 0x%x\n", cm->cm_targ->tid, reply->IOCStatus);
499 
500 	mps_free_command(sc, cm);
501 }
502 
503 static void
504 mpssas_evt_handler(struct mps_softc *sc, uintptr_t data,
505     MPI2_EVENT_NOTIFICATION_REPLY *event)
506 {
507 	struct mpssas_softc *sassc;
508 
509 	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
510 
511 	sassc = sc->sassc;
512 	mps_print_evt_sas(sc, event);
513 
514 	switch (event->Event) {
515 	case MPI2_EVENT_SAS_DISCOVERY:
516 	{
517 		MPI2_EVENT_DATA_SAS_DISCOVERY *data;
518 
519 		data = (MPI2_EVENT_DATA_SAS_DISCOVERY *)&event->EventData;
520 
521 		if (data->ReasonCode & MPI2_EVENT_SAS_DISC_RC_STARTED)
522 			mps_dprint(sc, MPS_TRACE,"SAS discovery start event\n");
523 		if (data->ReasonCode & MPI2_EVENT_SAS_DISC_RC_COMPLETED) {
524 			mps_dprint(sc, MPS_TRACE, "SAS discovery end event\n");
525 			sassc->flags &= ~MPSSAS_IN_DISCOVERY;
526 			mpssas_discovery_end(sassc);
527 		}
528 		break;
529 	}
530 	case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
531 	{
532 		MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *data;
533 		MPI2_EVENT_SAS_TOPO_PHY_ENTRY *phy;
534 		int i;
535 
536 		data = (MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *)
537 		    &event->EventData;
538 
539 		if (data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_ADDED) {
540 			if (bootverbose)
541 				printf("Expander found at enclosure %d\n",
542 				    data->EnclosureHandle);
543 			mpssas_probe_device(sc, data->ExpanderDevHandle);
544 		}
545 
546 		for (i = 0; i < data->NumEntries; i++) {
547 			phy = &data->PHY[i];
548 			switch (phy->PhyStatus & MPI2_EVENT_SAS_TOPO_RC_MASK) {
549 			case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
550 				mpssas_probe_device(sc, phy->AttachedDevHandle);
551 				break;
552 			case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
553 				mpssas_prepare_remove(sassc, phy);
554 				break;
555 			case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
556 			case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE:
557 			case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING:
558 			default:
559 				break;
560 			}
561 		}
562 
563 		break;
564 	}
565 	case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
566 		break;
567 	default:
568 		break;
569 	}
570 
571 	mps_free_reply(sc, data);
572 }
573 
574 static int
575 mpssas_register_events(struct mps_softc *sc)
576 {
577 	uint8_t events[16];
578 
579 	bzero(events, 16);
580 	setbit(events, MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE);
581 	setbit(events, MPI2_EVENT_SAS_DISCOVERY);
582 	setbit(events, MPI2_EVENT_SAS_BROADCAST_PRIMITIVE);
583 	setbit(events, MPI2_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE);
584 	setbit(events, MPI2_EVENT_SAS_INIT_TABLE_OVERFLOW);
585 	setbit(events, MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST);
586 	setbit(events, MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE);
587 
588 	mps_register_events(sc, events, mpssas_evt_handler, NULL,
589 	    &sc->sassc->mpssas_eh);
590 
591 	return (0);
592 }
593 
594 int
595 mps_attach_sas(struct mps_softc *sc)
596 {
597 	struct mpssas_softc *sassc;
598 	int error = 0;
599 	int num_sim_reqs;
600 
601 	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
602 
603 	sassc = malloc(sizeof(struct mpssas_softc), M_MPT2, M_WAITOK|M_ZERO);
604 	sassc->targets = malloc(sizeof(struct mpssas_target) *
605 	    sc->facts->MaxTargets, M_MPT2, M_WAITOK|M_ZERO);
606 	sc->sassc = sassc;
607 	sassc->sc = sc;
608 
609 	/*
610 	 * Tell CAM that we can handle 5 fewer requests than we have
611 	 * allocated.  If we allow the full number of requests, all I/O
612 	 * will halt when we run out of resources.  Things work fine with
613 	 * just 1 less request slot given to CAM than we have allocated.
614 	 * We also need a couple of extra commands so that we can send down
615 	 * abort, reset, etc. requests when commands time out.  Otherwise
616 	 * we could wind up in a situation with sc->num_reqs requests down
617 	 * on the card and no way to send an abort.
618 	 *
619 	 * XXX KDM need to figure out why I/O locks up if all commands are
620 	 * used.
621 	 */
622 	num_sim_reqs = sc->num_reqs - 5;
623 
624 	if ((sassc->devq = cam_simq_alloc(num_sim_reqs)) == NULL) {
625 		mps_dprint(sc, MPS_FAULT, "Cannot allocate SIMQ\n");
626 		error = ENOMEM;
627 		goto out;
628 	}
629 
630 	sassc->sim = cam_sim_alloc(mpssas_action, mpssas_poll, "mps", sassc,
631 	    device_get_unit(sc->mps_dev), &sc->mps_mtx, num_sim_reqs,
632 	    num_sim_reqs, sassc->devq);
633 	if (sassc->sim == NULL) {
634 		mps_dprint(sc, MPS_FAULT, "Cannot allocate SIM\n");
635 		error = EINVAL;
636 		goto out;
637 	}
638 
639 	/*
640 	 * XXX There should be a bus for every port on the adapter, but since
641 	 * we're just going to fake the topology for now, we'll pretend that
642 	 * everything is just a target on a single bus.
643 	 */
644 	mps_lock(sc);
645 	if ((error = xpt_bus_register(sassc->sim, sc->mps_dev, 0)) != 0) {
646 		mps_dprint(sc, MPS_FAULT, "Error %d registering SCSI bus\n",
647 		    error);
648 		mps_unlock(sc);
649 		goto out;
650 	}
651 
652 	/*
653 	 * Assume that discovery events will start right away.  Freezing
654 	 * the simq will prevent the CAM boottime scanner from running
655 	 * before discovery is complete.
656 	 */
657 	sassc->flags = MPSSAS_IN_STARTUP | MPSSAS_IN_DISCOVERY;
658 	xpt_freeze_simq(sassc->sim, 1);
659 
660 	mps_unlock(sc);
661 
662 	callout_init(&sassc->discovery_callout, 1 /*mpsafe*/);
663 	sassc->discovery_timeouts = 0;
664 
665 	mpssas_register_events(sc);
666 out:
667 	if (error)
668 		mps_detach_sas(sc);
669 	return (error);
670 }
671 
672 int
673 mps_detach_sas(struct mps_softc *sc)
674 {
675 	struct mpssas_softc *sassc;
676 
677 	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
678 
679 	if (sc->sassc == NULL)
680 		return (0);
681 
682 	sassc = sc->sassc;
683 
684 	/* Make sure CAM doesn't wedge if we had to bail out early. */
685 	mps_lock(sc);
686 	if (sassc->flags & MPSSAS_IN_STARTUP)
687 		xpt_release_simq(sassc->sim, 1);
688 	mps_unlock(sc);
689 
690 	if (sassc->mpssas_eh != NULL)
691 		mps_deregister_events(sc, sassc->mpssas_eh);
692 
693 	mps_lock(sc);
694 
695 	if (sassc->sim != NULL) {
696 		xpt_bus_deregister(cam_sim_path(sassc->sim));
697 		cam_sim_free(sassc->sim, FALSE);
698 	}
699 	mps_unlock(sc);
700 
701 	if (sassc->devq != NULL)
702 		cam_simq_free(sassc->devq);
703 
704 	free(sassc->targets, M_MPT2);
705 	free(sassc, M_MPT2);
706 	sc->sassc = NULL;
707 
708 	return (0);
709 }
710 
711 static void
712 mpssas_discovery_end(struct mpssas_softc *sassc)
713 {
714 	struct mps_softc *sc = sassc->sc;
715 
716 	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
717 
718 	if (sassc->flags & MPSSAS_DISCOVERY_TIMEOUT_PENDING)
719 		callout_stop(&sassc->discovery_callout);
720 
721 	if ((sassc->flags & MPSSAS_IN_STARTUP) != 0) {
722 		mps_dprint(sc, MPS_INFO,
723 		    "mpssas_discovery_end: removing confighook\n");
724 		sassc->flags &= ~MPSSAS_IN_STARTUP;
725 		xpt_release_simq(sassc->sim, 1);
726 	}
727 #if 0
728 	mpssas_announce_device(sassc, NULL);
729 #endif
730 
731 }
732 
733 static void
734 mpssas_announce_device(struct mpssas_softc *sassc, struct mpssas_target *targ)
735 {
736 	union ccb *ccb;
737 	int bus, tid, lun;
738 
739 	/*
740 	 * Force a rescan, a hackish way to announce devices.
741 	 * XXX Doing a scan on an individual device is hackish in that it
742 	 *     won't scan the LUNs.
743 	 * XXX Does it matter if any of this fails?
744 	 */
745 	bus = cam_sim_path(sassc->sim);
746 	if (targ != NULL) {
747 		tid = targ->tid;
748 		lun = 0;
749 	} else {
750 		tid = CAM_TARGET_WILDCARD;
751 		lun = CAM_LUN_WILDCARD;
752 	}
753 	ccb = xpt_alloc_ccb_nowait();
754 	if (ccb == NULL)
755 		return;
756 	if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, bus, tid,
757 	    CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
758 		xpt_free_ccb(ccb);
759 		return;
760 	}
761 	mps_dprint(sassc->sc, MPS_INFO, "Triggering rescan of %d:%d:-1\n",
762 	    bus, tid);
763 	xpt_rescan(ccb);
764 }
765 
766 static void
767 mpssas_startup(void *data)
768 {
769 	struct mpssas_softc *sassc = data;
770 
771 	mps_dprint(sassc->sc, MPS_TRACE, "%s\n", __func__);
772 
773 	mps_lock(sassc->sc);
774 	if ((sassc->flags & MPSSAS_IN_DISCOVERY) == 0) {
775 		mpssas_discovery_end(sassc);
776 	} else {
777 		if (sassc->discovery_timeouts < MPSSAS_MAX_DISCOVERY_TIMEOUTS) {
778 			sassc->flags |= MPSSAS_DISCOVERY_TIMEOUT_PENDING;
779 			callout_reset(&sassc->discovery_callout,
780 			    MPSSAS_DISCOVERY_TIMEOUT * hz,
781 			    mpssas_discovery_timeout, sassc);
782 			sassc->discovery_timeouts++;
783 		} else {
784 			mps_dprint(sassc->sc, MPS_FAULT,
785 			    "Discovery timed out, continuing.\n");
786 			sassc->flags &= ~MPSSAS_IN_DISCOVERY;
787 			mpssas_discovery_end(sassc);
788 		}
789 	}
790 	mps_unlock(sassc->sc);
791 
792 	return;
793 }
794 
795 static void
796 mpssas_discovery_timeout(void *data)
797 {
798 	struct mpssas_softc *sassc = data;
799 	struct mps_softc *sc;
800 
801 	sc = sassc->sc;
802 	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
803 
804 	mps_lock(sc);
805 	mps_printf(sc,
806 	    "Timeout waiting for discovery, interrupts may not be working!\n");
807 	sassc->flags &= ~MPSSAS_DISCOVERY_TIMEOUT_PENDING;
808 
809 	/* Poll the hardware for events in case interrupts aren't working */
810 	mps_intr_locked(sc);
811 	mps_unlock(sc);
812 
813 	/* Check the status of discovery and re-arm the timeout if needed */
814 	mpssas_startup(sassc);
815 }
816 
817 static void
818 mpssas_action(struct cam_sim *sim, union ccb *ccb)
819 {
820 	struct mpssas_softc *sassc;
821 
822 	sassc = cam_sim_softc(sim);
823 
824 	mps_dprint(sassc->sc, MPS_TRACE, "%s func 0x%x\n", __func__,
825 	    ccb->ccb_h.func_code);
826 
827 	switch (ccb->ccb_h.func_code) {
828 	case XPT_PATH_INQ:
829 	{
830 		struct ccb_pathinq *cpi = &ccb->cpi;
831 
832 		cpi->version_num = 1;
833 		cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
834 		cpi->target_sprt = 0;
835 		cpi->hba_misc = PIM_NOBUSRESET;
836 		cpi->hba_eng_cnt = 0;
837 		cpi->max_target = sassc->sc->facts->MaxTargets - 1;
838 		cpi->max_lun = 0;
839 		cpi->initiator_id = 255;
840 		strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
841 		strncpy(cpi->hba_vid, "LSILogic", HBA_IDLEN);
842 		strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
843 		cpi->unit_number = cam_sim_unit(sim);
844 		cpi->bus_id = cam_sim_bus(sim);
845 		cpi->base_transfer_speed = 150000;
846 		cpi->transport = XPORT_SAS;
847 		cpi->transport_version = 0;
848 		cpi->protocol = PROTO_SCSI;
849 		cpi->protocol_version = SCSI_REV_SPC;
850 		cpi->ccb_h.status = CAM_REQ_CMP;
851 		break;
852 	}
853 	case XPT_GET_TRAN_SETTINGS:
854 	{
855 		struct ccb_trans_settings	*cts;
856 		struct ccb_trans_settings_sas	*sas;
857 		struct ccb_trans_settings_scsi	*scsi;
858 		struct mpssas_target *targ;
859 
860 		cts = &ccb->cts;
861 		sas = &cts->xport_specific.sas;
862 		scsi = &cts->proto_specific.scsi;
863 
864 		targ = &sassc->targets[cts->ccb_h.target_id];
865 		if (targ->handle == 0x0) {
866 			cts->ccb_h.status = CAM_TID_INVALID;
867 			break;
868 		}
869 
870 		cts->protocol_version = SCSI_REV_SPC2;
871 		cts->transport = XPORT_SAS;
872 		cts->transport_version = 0;
873 
874 		sas->valid = CTS_SAS_VALID_SPEED;
875 		switch (targ->linkrate) {
876 		case 0x08:
877 			sas->bitrate = 150000;
878 			break;
879 		case 0x09:
880 			sas->bitrate = 300000;
881 			break;
882 		case 0x0a:
883 			sas->bitrate = 600000;
884 			break;
885 		default:
886 			sas->valid = 0;
887 		}
888 
889 		cts->protocol = PROTO_SCSI;
890 		scsi->valid = CTS_SCSI_VALID_TQ;
891 		scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
892 
893 		cts->ccb_h.status = CAM_REQ_CMP;
894 		break;
895 	}
896 	case XPT_CALC_GEOMETRY:
897 		cam_calc_geometry(&ccb->ccg, /*extended*/1);
898 		ccb->ccb_h.status = CAM_REQ_CMP;
899 		break;
900 	case XPT_RESET_DEV:
901 		mpssas_action_resetdev(sassc, ccb);
902 		return;
903 	case XPT_RESET_BUS:
904 	case XPT_ABORT:
905 	case XPT_TERM_IO:
906 		ccb->ccb_h.status = CAM_REQ_CMP;
907 		break;
908 	case XPT_SCSI_IO:
909 		mpssas_action_scsiio(sassc, ccb);
910 		return;
911 	default:
912 		ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
913 		break;
914 	}
915 	xpt_done(ccb);
916 
917 }
918 
919 #if 0
920 static void
921 mpssas_resettimeout_complete(struct mps_softc *sc, struct mps_command *cm)
922 {
923 	MPI2_SCSI_TASK_MANAGE_REPLY *resp;
924 	uint16_t code;
925 
926 	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
927 
928 	resp = (MPI2_SCSI_TASK_MANAGE_REPLY *)cm->cm_reply;
929 	code = resp->ResponseCode;
930 
931 	mps_free_command(sc, cm);
932 	mpssas_unfreeze_device(sassc, targ);
933 
934 	if (code != MPI2_SCSITASKMGMT_RSP_TM_COMPLETE) {
935 		mps_reset_controller(sc);
936 	}
937 
938 	return;
939 }
940 #endif
941 
942 static void
943 mpssas_scsiio_timeout(void *data)
944 {
945 	union ccb *ccb;
946 	struct mps_softc *sc;
947 	struct mps_command *cm;
948 	struct mpssas_target *targ;
949 #if 0
950 	char cdb_str[(SCSI_MAX_CDBLEN * 3) + 1];
951 #endif
952 
953 	cm = (struct mps_command *)data;
954 	sc = cm->cm_sc;
955 
956 	/*
957 	 * Run the interrupt handler to make sure it's not pending.  This
958 	 * isn't perfect because the command could have already completed
959 	 * and been re-used, though this is unlikely.
960 	 */
961 	mps_lock(sc);
962 	mps_intr_locked(sc);
963 	if (cm->cm_state == MPS_CM_STATE_FREE) {
964 		mps_unlock(sc);
965 		return;
966 	}
967 
968 	ccb = cm->cm_complete_data;
969 	targ = cm->cm_targ;
970 	if (targ == 0x00)
971 		/* Driver bug */
972 		targ = &sc->sassc->targets[ccb->ccb_h.target_id];
973 
974 	xpt_print(ccb->ccb_h.path, "SCSI command timeout on device handle "
975 		  "0x%04x SMID %d\n", targ->handle, cm->cm_desc.Default.SMID);
976 	/*
977 	 * XXX KDM this is useful for debugging purposes, but the existing
978 	 * scsi_op_desc() implementation can't handle a NULL value for
979 	 * inq_data.  So this will remain commented out until I bring in
980 	 * those changes as well.
981 	 */
982 #if 0
983 	xpt_print(ccb->ccb_h.path, "Timed out command: %s. CDB %s\n",
984 		  scsi_op_desc((ccb->ccb_h.flags & CAM_CDB_POINTER) ?
985 		  		ccb->csio.cdb_io.cdb_ptr[0] :
986 				ccb->csio.cdb_io.cdb_bytes[0], NULL),
987 		  scsi_cdb_string((ccb->ccb_h.flags & CAM_CDB_POINTER) ?
988 				   ccb->csio.cdb_io.cdb_ptr :
989 				   ccb->csio.cdb_io.cdb_bytes, cdb_str,
990 		  		   sizeof(cdb_str)));
991 #endif
992 
993 	/* Inform CAM about the timeout and that recovery is starting. */
994 #if 0
995 	if ((targ->flags & MPSSAS_TARGET_INRECOVERY) == 0) {
996 		mpssas_freeze_device(sc->sassc, targ);
997 		ccb->ccb_h.status = CAM_CMD_TIMEOUT;
998 		xpt_done(ccb);
999 	}
1000 #endif
1001 	mpssas_freeze_device(sc->sassc, targ);
1002 	ccb->ccb_h.status = CAM_CMD_TIMEOUT;
1003 
1004 	/*
1005 	 * recycle the command into recovery so that there's no risk of
1006 	 * command allocation failure.
1007 	 */
1008 	cm->cm_state = MPS_CM_STATE_TIMEDOUT;
1009 	mpssas_recovery(sc, cm);
1010 	mps_unlock(sc);
1011 }
1012 
1013 static void
1014 mpssas_abort_complete(struct mps_softc *sc, struct mps_command *cm)
1015 {
1016 	MPI2_SCSI_TASK_MANAGE_REQUEST *req;
1017 
1018 	req = (MPI2_SCSI_TASK_MANAGE_REQUEST *)cm->cm_req;
1019 
1020 	mps_printf(sc, "%s: abort request on handle %#04x SMID %d "
1021 		   "complete\n", __func__, req->DevHandle, req->TaskMID);
1022 
1023 	/*
1024 	 * Release the SIM queue, we froze it when we sent the abort.
1025 	 */
1026 	xpt_release_simq(sc->sassc->sim, 1);
1027 
1028 	mps_free_command(sc, cm);
1029 }
1030 
1031 static void
1032 mpssas_recovery(struct mps_softc *sc, struct mps_command *abort_cm)
1033 {
1034 	struct mps_command *cm;
1035 	MPI2_SCSI_TASK_MANAGE_REQUEST *req, *orig_req;
1036 	int error;
1037 
1038 	cm = mps_alloc_command(sc);
1039 	if (cm == NULL) {
1040 		mps_printf(sc, "%s: command allocation failure\n", __func__);
1041 		return;
1042 	}
1043 
1044 	cm->cm_targ = abort_cm->cm_targ;
1045 	cm->cm_complete = mpssas_abort_complete;
1046 
1047 	req = (MPI2_SCSI_TASK_MANAGE_REQUEST *)cm->cm_req;
1048 	orig_req = (MPI2_SCSI_TASK_MANAGE_REQUEST *)abort_cm->cm_req;
1049 	req->DevHandle = abort_cm->cm_targ->handle;
1050 	req->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
1051 	req->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK;
1052 	memcpy(req->LUN, orig_req->LUN, sizeof(req->LUN));
1053 	req->TaskMID = abort_cm->cm_desc.Default.SMID;
1054 
1055 	cm->cm_data = NULL;
1056 	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1057 
1058 	/*
1059 	 * Freeze the SIM queue while we issue the abort.  According to the
1060 	 * Fusion-MPT 2.0 spec, task management requests are serialized,
1061 	 * and so the host should not send any I/O requests while task
1062 	 * management requests are pending.
1063 	 */
1064 	xpt_freeze_simq(sc->sassc->sim, 1);
1065 
1066 	error = mps_map_command(sc, cm);
1067 
1068 	if (error != 0) {
1069 		mps_printf(sc, "%s: error mapping abort request!\n", __func__);
1070 		xpt_release_simq(sc->sassc->sim, 1);
1071 	}
1072 #if 0
1073 	error = mpssas_reset(sc, targ, &resetcm);
1074 	if ((error != 0) && (error != EBUSY)) {
1075 		mps_printf(sc, "Error resetting device!\n");
1076 		mps_unlock(sc);
1077 		return;
1078 	}
1079 
1080 	targ->flags |= MPSSAS_TARGET_INRESET;
1081 
1082 	cm->cm_complete = mpssas_resettimeout_complete;
1083 	cm->cm_complete_data = cm;
1084 	mps_map_command(sassc->sc, cm);
1085 #endif
1086 }
1087 
1088 static void
1089 mpssas_action_scsiio(struct mpssas_softc *sassc, union ccb *ccb)
1090 {
1091 	MPI2_SCSI_IO_REQUEST *req;
1092 	struct ccb_scsiio *csio;
1093 	struct mps_softc *sc;
1094 	struct mpssas_target *targ;
1095 	struct mps_command *cm;
1096 
1097 	mps_dprint(sassc->sc, MPS_TRACE, "%s\n", __func__);
1098 
1099 	sc = sassc->sc;
1100 
1101 	csio = &ccb->csio;
1102 	targ = &sassc->targets[csio->ccb_h.target_id];
1103 	if (targ->handle == 0x0) {
1104 		csio->ccb_h.status = CAM_SEL_TIMEOUT;
1105 		xpt_done(ccb);
1106 		return;
1107 	}
1108 
1109 	cm = mps_alloc_command(sc);
1110 	if (cm == NULL) {
1111 		if ((sassc->flags & MPSSAS_QUEUE_FROZEN) == 0) {
1112 			xpt_freeze_simq(sassc->sim, 1);
1113 			sassc->flags |= MPSSAS_QUEUE_FROZEN;
1114 		}
1115 		ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1116 		ccb->ccb_h.status |= CAM_REQUEUE_REQ;
1117 		xpt_done(ccb);
1118 		return;
1119 	}
1120 
1121 	req = (MPI2_SCSI_IO_REQUEST *)cm->cm_req;
1122 	req->DevHandle = targ->handle;
1123 	req->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
1124 	req->MsgFlags = 0;
1125 	req->SenseBufferLowAddress = cm->cm_sense_busaddr;
1126 	req->SenseBufferLength = MPS_SENSE_LEN;
1127 	req->SGLFlags = 0;
1128 	req->ChainOffset = 0;
1129 	req->SGLOffset0 = 24;	/* 32bit word offset to the SGL */
1130 	req->SGLOffset1= 0;
1131 	req->SGLOffset2= 0;
1132 	req->SGLOffset3= 0;
1133 	req->SkipCount = 0;
1134 	req->DataLength = csio->dxfer_len;
1135 	req->BidirectionalDataLength = 0;
1136 	req->IoFlags = csio->cdb_len;
1137 	req->EEDPFlags = 0;
1138 
1139 	/* Note: BiDirectional transfers are not supported */
1140 	switch (csio->ccb_h.flags & CAM_DIR_MASK) {
1141 	case CAM_DIR_IN:
1142 		req->Control = MPI2_SCSIIO_CONTROL_READ;
1143 		cm->cm_flags |= MPS_CM_FLAGS_DATAIN;
1144 		break;
1145 	case CAM_DIR_OUT:
1146 		req->Control = MPI2_SCSIIO_CONTROL_WRITE;
1147 		cm->cm_flags |= MPS_CM_FLAGS_DATAOUT;
1148 		break;
1149 	case CAM_DIR_NONE:
1150 	default:
1151 		req->Control = MPI2_SCSIIO_CONTROL_NODATATRANSFER;
1152 		break;
1153 	}
1154 
1155 	/*
1156 	 * It looks like the hardware doesn't require an explicit tag
1157 	 * number for each transaction.  SAM Task Management not supported
1158 	 * at the moment.
1159 	 */
1160 	switch (csio->tag_action) {
1161 	case MSG_HEAD_OF_Q_TAG:
1162 		req->Control |= MPI2_SCSIIO_CONTROL_HEADOFQ;
1163 		break;
1164 	case MSG_ORDERED_Q_TAG:
1165 		req->Control |= MPI2_SCSIIO_CONTROL_ORDEREDQ;
1166 		break;
1167 	case MSG_ACA_TASK:
1168 		req->Control |= MPI2_SCSIIO_CONTROL_ACAQ;
1169 		break;
1170 	case CAM_TAG_ACTION_NONE:
1171 	case MSG_SIMPLE_Q_TAG:
1172 	default:
1173 		req->Control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
1174 		break;
1175 	}
1176 
1177 	/* XXX Need to handle multi-level LUNs */
1178 	if (csio->ccb_h.target_lun > 255) {
1179 		mps_free_command(sc, cm);
1180 		ccb->ccb_h.status = CAM_LUN_INVALID;
1181 		xpt_done(ccb);
1182 		return;
1183 	}
1184 	req->LUN[1] = csio->ccb_h.target_lun;
1185 
1186 	if (csio->ccb_h.flags & CAM_CDB_POINTER)
1187 		bcopy(csio->cdb_io.cdb_ptr, &req->CDB.CDB32[0], csio->cdb_len);
1188 	else
1189 		bcopy(csio->cdb_io.cdb_bytes, &req->CDB.CDB32[0],csio->cdb_len);
1190 	req->IoFlags = csio->cdb_len;
1191 
1192 	cm->cm_data = csio->data_ptr;
1193 	cm->cm_length = csio->dxfer_len;
1194 	cm->cm_sge = &req->SGL;
1195 	cm->cm_sglsize = (32 - 24) * 4;
1196 	cm->cm_desc.SCSIIO.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
1197 	cm->cm_desc.SCSIIO.DevHandle = targ->handle;
1198 	cm->cm_complete = mpssas_scsiio_complete;
1199 	cm->cm_complete_data = ccb;
1200 	cm->cm_targ = targ;
1201 
1202 	callout_reset(&cm->cm_callout, (ccb->ccb_h.timeout * hz) / 1000,
1203 	   mpssas_scsiio_timeout, cm);
1204 
1205 	mps_map_command(sc, cm);
1206 	return;
1207 }
1208 
1209 static void
1210 mpssas_scsiio_complete(struct mps_softc *sc, struct mps_command *cm)
1211 {
1212 	MPI2_SCSI_IO_REPLY *rep;
1213 	union ccb *ccb;
1214 	struct mpssas_softc *sassc;
1215 	u_int sense_len;
1216 	int dir = 0;
1217 
1218 	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
1219 
1220 	callout_stop(&cm->cm_callout);
1221 
1222 	sassc = sc->sassc;
1223 	ccb = cm->cm_complete_data;
1224 	rep = (MPI2_SCSI_IO_REPLY *)cm->cm_reply;
1225 
1226 	if (cm->cm_data != NULL) {
1227 		if (cm->cm_flags & MPS_CM_FLAGS_DATAIN)
1228 			dir = BUS_DMASYNC_POSTREAD;
1229 		else if (cm->cm_flags & MPS_CM_FLAGS_DATAOUT)
1230 			dir = BUS_DMASYNC_POSTWRITE;;
1231 		bus_dmamap_sync(sc->buffer_dmat, cm->cm_dmamap, dir);
1232 		bus_dmamap_unload(sc->buffer_dmat, cm->cm_dmamap);
1233 	}
1234 
1235 	if (sassc->flags & MPSSAS_QUEUE_FROZEN) {
1236 		ccb->ccb_h.flags |= CAM_RELEASE_SIMQ;
1237 		sassc->flags &= ~MPSSAS_QUEUE_FROZEN;
1238 	}
1239 
1240 	/* Take the fast path to completion */
1241 	if (cm->cm_reply == NULL) {
1242 		ccb->ccb_h.status = CAM_REQ_CMP;
1243 		ccb->csio.scsi_status = SCSI_STATUS_OK;
1244 		mps_free_command(sc, cm);
1245 		xpt_done(ccb);
1246 		return;
1247 	}
1248 
1249 	mps_dprint(sc, MPS_INFO, "(%d:%d:%d) IOCStatus= 0x%x, "
1250 	    "ScsiStatus= 0x%x, SCSIState= 0x%x TransferCount= 0x%x\n",
1251 	    xpt_path_path_id(ccb->ccb_h.path),
1252 	    xpt_path_target_id(ccb->ccb_h.path),
1253 	    xpt_path_lun_id(ccb->ccb_h.path), rep->IOCStatus,
1254 	    rep->SCSIStatus, rep->SCSIState, rep->TransferCount);
1255 
1256 	switch (rep->IOCStatus & MPI2_IOCSTATUS_MASK) {
1257 	case MPI2_IOCSTATUS_BUSY:
1258 	case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
1259 		/*
1260 		 * The controller is overloaded, try waiting a bit for it
1261 		 * to free up.
1262 		 */
1263 		ccb->ccb_h.status = CAM_BUSY;
1264 		break;
1265 	case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN:
1266 		ccb->csio.resid = cm->cm_length - rep->TransferCount;
1267 		/* FALLTHROUGH */
1268 	case MPI2_IOCSTATUS_SUCCESS:
1269 	case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR:
1270 		ccb->ccb_h.status = CAM_REQ_CMP;
1271 		break;
1272 	case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN:
1273 		/* resid is ignored for this condition */
1274 		ccb->csio.resid = 0;
1275 		ccb->ccb_h.status = CAM_DATA_RUN_ERR;
1276 		break;
1277 	case MPI2_IOCSTATUS_SCSI_INVALID_DEVHANDLE:
1278 	case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
1279 		ccb->ccb_h.status = CAM_DEV_NOT_THERE;
1280 		break;
1281 	case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
1282 		/*
1283 		 * This is one of the responses that comes back when an I/O
1284 		 * has been aborted.  If it is because of a timeout that we
1285 		 * initiated, just set the status to CAM_CMD_TIMEOUT.
1286 		 * Otherwise set it to CAM_REQ_ABORTED.  The effect on the
1287 		 * command is the same (it gets retried, subject to the
1288 		 * retry counter), the only difference is what gets printed
1289 		 * on the console.
1290 		 */
1291 		if (cm->cm_state == MPS_CM_STATE_TIMEDOUT)
1292 			ccb->ccb_h.status = CAM_CMD_TIMEOUT;
1293 		else
1294 			ccb->ccb_h.status = CAM_REQ_ABORTED;
1295 		break;
1296 	case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
1297 	case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
1298 		ccb->ccb_h.status = CAM_REQ_ABORTED;
1299 		break;
1300 	case MPI2_IOCSTATUS_INVALID_SGL:
1301 		mps_print_scsiio_cmd(sc, cm);
1302 		ccb->ccb_h.status = CAM_UNREC_HBA_ERROR;
1303 		break;
1304 	case MPI2_IOCSTATUS_INVALID_FUNCTION:
1305 	case MPI2_IOCSTATUS_INTERNAL_ERROR:
1306 	case MPI2_IOCSTATUS_INVALID_VPID:
1307 	case MPI2_IOCSTATUS_INVALID_FIELD:
1308 	case MPI2_IOCSTATUS_INVALID_STATE:
1309 	case MPI2_IOCSTATUS_OP_STATE_NOT_SUPPORTED:
1310 	case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR:
1311 	case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
1312 	case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
1313 	case MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
1314 	default:
1315 		ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1316 	}
1317 
1318 
1319 	if ((rep->SCSIState & MPI2_SCSI_STATE_NO_SCSI_STATUS) == 0) {
1320 		ccb->csio.scsi_status = rep->SCSIStatus;
1321 
1322 		switch (rep->SCSIStatus) {
1323 		case MPI2_SCSI_STATUS_TASK_SET_FULL:
1324 		case MPI2_SCSI_STATUS_CHECK_CONDITION:
1325 			ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
1326 			break;
1327 		case MPI2_SCSI_STATUS_COMMAND_TERMINATED:
1328 		case MPI2_SCSI_STATUS_TASK_ABORTED:
1329 			ccb->ccb_h.status = CAM_REQ_ABORTED;
1330 			break;
1331 		case MPI2_SCSI_STATUS_GOOD:
1332 		default:
1333 			break;
1334 		}
1335 	}
1336 
1337 	if (rep->SCSIState & MPI2_SCSI_STATE_AUTOSENSE_VALID) {
1338 		sense_len = MIN(rep->SenseCount,
1339 		    sizeof(struct scsi_sense_data));
1340 		if (sense_len < rep->SenseCount)
1341 			ccb->csio.sense_resid = rep->SenseCount - sense_len;
1342 		bcopy(cm->cm_sense, &ccb->csio.sense_data, sense_len);
1343 		ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
1344 	}
1345 
1346 	if (rep->SCSIState & MPI2_SCSI_STATE_AUTOSENSE_FAILED)
1347 		ccb->ccb_h.status = CAM_AUTOSENSE_FAIL;
1348 
1349 	if (rep->SCSIState & MPI2_SCSI_STATE_RESPONSE_INFO_VALID)
1350 		ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1351 
1352 	mps_free_command(sc, cm);
1353 	xpt_done(ccb);
1354 }
1355 
1356 static void
1357 mpssas_action_resetdev(struct mpssas_softc *sassc, union ccb *ccb)
1358 {
1359 	struct mps_softc *sc;
1360 	struct mps_command *cm;
1361 	struct mpssas_target *targ;
1362 	int error;
1363 
1364 	sc = sassc->sc;
1365 	targ = &sassc->targets[ccb->ccb_h.target_id];
1366 
1367 	if (targ->flags & MPSSAS_TARGET_INRECOVERY) {
1368 		ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1369 		xpt_done(ccb);
1370 		return;
1371 	}
1372 
1373 	cm = mps_alloc_command(sc);
1374 	if (cm == NULL) {
1375 		mps_printf(sc, "mpssas_action_resetdev: cannot alloc command\n");
1376 		ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1377 		xpt_done(ccb);
1378 		return;
1379 	}
1380 
1381 	cm->cm_targ = targ;
1382 	cm->cm_complete = mpssas_resetdev_complete;
1383 	cm->cm_complete_data = ccb;
1384 
1385 	error = mpssas_resetdev(sassc, cm);
1386 	if (error) {
1387 		ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1388 		xpt_done(ccb);
1389 		return;
1390 	}
1391 }
1392 
1393 static int
1394 mpssas_resetdev(struct mpssas_softc *sassc, struct mps_command *cm)
1395 {
1396 	MPI2_SCSI_TASK_MANAGE_REQUEST *req;
1397 	struct mps_softc *sc;
1398 	int error;
1399 
1400 	mps_dprint(sassc->sc, MPS_TRACE, "%s\n", __func__);
1401 
1402 	sc = sassc->sc;
1403 
1404 	req = (MPI2_SCSI_TASK_MANAGE_REQUEST *)cm->cm_req;
1405 	req->DevHandle = cm->cm_targ->handle;
1406 	req->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
1407 	req->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
1408 
1409 	/* SAS Hard Link Reset / SATA Link Reset */
1410 	req->MsgFlags = MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET;
1411 
1412 	cm->cm_data = NULL;
1413 	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1414 
1415 	xpt_freeze_simq(sassc->sim, 1);
1416 
1417 	error = mps_map_command(sassc->sc, cm);
1418 
1419 	if (error != 0)
1420 		xpt_release_simq(sassc->sim, 1);
1421 
1422 	return (error);
1423 }
1424 
1425 static void
1426 mpssas_resetdev_complete(struct mps_softc *sc, struct mps_command *cm)
1427 {
1428 	MPI2_SCSI_TASK_MANAGE_REPLY *resp;
1429 	union ccb *ccb;
1430 
1431 	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
1432 
1433 	resp = (MPI2_SCSI_TASK_MANAGE_REPLY *)cm->cm_reply;
1434 	ccb = cm->cm_complete_data;
1435 
1436 	printf("resetdev complete IOCStatus= 0x%x ResponseCode= 0x%x\n",
1437 	    resp->IOCStatus, resp->ResponseCode);
1438 
1439 	if (resp->ResponseCode == MPI2_SCSITASKMGMT_RSP_TM_COMPLETE)
1440 		ccb->ccb_h.status = CAM_REQ_CMP;
1441 	else
1442 		ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1443 
1444 	mps_free_command(sc, cm);
1445 
1446 	xpt_release_simq(sc->sassc->sim, 1);
1447 
1448 	xpt_done(ccb);
1449 }
1450 
1451 static void
1452 mpssas_poll(struct cam_sim *sim)
1453 {
1454 	struct mpssas_softc *sassc;
1455 
1456 	sassc = cam_sim_softc(sim);
1457 	mps_intr_locked(sassc->sc);
1458 }
1459 
1460 static void
1461 mpssas_freeze_device(struct mpssas_softc *sassc, struct mpssas_target *targ)
1462 {
1463 }
1464 
1465 static void
1466 mpssas_unfreeze_device(struct mpssas_softc *sassc, struct mpssas_target *targ)
1467 {
1468 }
1469 
1470