mps_sas.c revision 7f0ccdf947fabcfc0c34dffe169de18e4ee3aa1f
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#include <sys/sglist.h>
45#include <sys/endian.h>
46
47#include <machine/bus.h>
48#include <machine/resource.h>
49#include <sys/rman.h>
50
51#include <cam/cam.h>
52#include <cam/cam_ccb.h>
53#include <cam/cam_debug.h>
54#include <cam/cam_sim.h>
55#include <cam/cam_xpt_sim.h>
56#include <cam/cam_xpt_periph.h>
57#include <cam/cam_periph.h>
58#include <cam/scsi/scsi_all.h>
59#include <cam/scsi/scsi_message.h>
60#if __FreeBSD_version >= 900026
61#include <cam/scsi/smp_all.h>
62#endif
63
64#include <dev/mps/mpi/mpi2_type.h>
65#include <dev/mps/mpi/mpi2.h>
66#include <dev/mps/mpi/mpi2_ioc.h>
67#include <dev/mps/mpi/mpi2_sas.h>
68#include <dev/mps/mpi/mpi2_cnfg.h>
69#include <dev/mps/mpi/mpi2_init.h>
70#include <dev/mps/mpsvar.h>
71#include <dev/mps/mps_table.h>
72
73struct mpssas_target {
74	uint16_t	handle;
75	uint8_t		linkrate;
76	uint64_t	devname;
77	uint64_t	sasaddr;
78	uint32_t	devinfo;
79	uint16_t	encl_handle;
80	uint16_t	encl_slot;
81	uint16_t	parent_handle;
82	int		flags;
83#define MPSSAS_TARGET_INABORT	(1 << 0)
84#define MPSSAS_TARGET_INRESET	(1 << 1)
85#define MPSSAS_TARGET_INCHIPRESET (1 << 2)
86#define MPSSAS_TARGET_INRECOVERY 0x7
87	uint16_t	tid;
88};
89
90struct mpssas_softc {
91	struct mps_softc	*sc;
92	u_int			flags;
93#define MPSSAS_IN_DISCOVERY	(1 << 0)
94#define MPSSAS_IN_STARTUP	(1 << 1)
95#define MPSSAS_DISCOVERY_TIMEOUT_PENDING	(1 << 2)
96#define MPSSAS_QUEUE_FROZEN	(1 << 3)
97	struct mpssas_target	*targets;
98	struct cam_devq		*devq;
99	struct cam_sim		*sim;
100	struct cam_path		*path;
101	struct intr_config_hook	sas_ich;
102	struct callout		discovery_callout;
103	u_int			discovery_timeouts;
104	struct mps_event_handle	*mpssas_eh;
105};
106
107struct mpssas_devprobe {
108	struct mps_config_params	params;
109	u_int			state;
110#define MPSSAS_PROBE_DEV1	0x01
111#define MPSSAS_PROBE_DEV2	0x02
112#define MPSSAS_PROBE_PHY	0x03
113#define MPSSAS_PROBE_EXP	0x04
114#define MPSSAS_PROBE_PHY2	0x05
115#define MPSSAS_PROBE_EXP2	0x06
116	struct mpssas_target	target;
117};
118
119#define MPSSAS_DISCOVERY_TIMEOUT	20
120#define MPSSAS_MAX_DISCOVERY_TIMEOUTS	10 /* 200 seconds */
121
122MALLOC_DEFINE(M_MPSSAS, "MPSSAS", "MPS SAS memory");
123
124static struct mpssas_target * mpssas_alloc_target(struct mpssas_softc *,
125    struct mpssas_target *);
126static struct mpssas_target * mpssas_find_target(struct mpssas_softc *, int,
127     uint16_t);
128static void mpssas_announce_device(struct mpssas_softc *,
129     struct mpssas_target *);
130static void mpssas_startup(void *data);
131static void mpssas_discovery_end(struct mpssas_softc *sassc);
132static void mpssas_discovery_timeout(void *data);
133static void mpssas_prepare_remove(struct mpssas_softc *,
134    MPI2_EVENT_SAS_TOPO_PHY_ENTRY *);
135static void mpssas_remove_device(struct mps_softc *, struct mps_command *);
136static void mpssas_remove_complete(struct mps_softc *, struct mps_command *);
137static void mpssas_action(struct cam_sim *sim, union ccb *ccb);
138static void mpssas_poll(struct cam_sim *sim);
139static void mpssas_probe_device(struct mps_softc *sc, uint16_t handle);
140static void mpssas_probe_device_complete(struct mps_softc *sc,
141     struct mps_config_params *params);
142static void mpssas_scsiio_timeout(void *data);
143static void mpssas_abort_complete(struct mps_softc *sc, struct mps_command *cm);
144static void mpssas_recovery(struct mps_softc *, struct mps_command *);
145static int mpssas_map_tm_request(struct mps_softc *sc, struct mps_command *cm);
146static void mpssas_issue_tm_request(struct mps_softc *sc,
147				    struct mps_command *cm);
148static void mpssas_tm_complete(struct mps_softc *sc, struct mps_command *cm,
149			       int error);
150static int mpssas_complete_tm_request(struct mps_softc *sc,
151				      struct mps_command *cm, int free_cm);
152static void mpssas_action_scsiio(struct mpssas_softc *, union ccb *);
153static void mpssas_scsiio_complete(struct mps_softc *, struct mps_command *);
154#if __FreeBSD_version >= 900026
155static void mpssas_smpio_complete(struct mps_softc *sc, struct mps_command *cm);
156static void mpssas_send_smpcmd(struct mpssas_softc *sassc, union ccb *ccb,
157			       uint64_t sasaddr);
158static void mpssas_action_smpio(struct mpssas_softc *sassc, union ccb *ccb);
159#endif /* __FreeBSD_version >= 900026 */
160static void mpssas_resetdev(struct mpssas_softc *, struct mps_command *);
161static void mpssas_action_resetdev(struct mpssas_softc *, union ccb *);
162static void mpssas_resetdev_complete(struct mps_softc *, struct mps_command *);
163static void mpssas_freeze_device(struct mpssas_softc *, struct mpssas_target *);
164static void mpssas_unfreeze_device(struct mpssas_softc *, struct mpssas_target *) __unused;
165
166static struct mpssas_target *
167mpssas_alloc_target(struct mpssas_softc *sassc, struct mpssas_target *probe)
168{
169	struct mpssas_target *target;
170	int start;
171
172	mps_dprint(sassc->sc, MPS_TRACE, "%s\n", __func__);
173
174	/*
175	 * If it's not a sata or sas target, CAM won't be able to see it.  Put
176	 * it into a high-numbered slot so that it's accessible but not
177	 * interrupting the target numbering sequence of real drives.
178	 */
179	if ((probe->devinfo & (MPI2_SAS_DEVICE_INFO_SSP_TARGET |
180	    MPI2_SAS_DEVICE_INFO_STP_TARGET | MPI2_SAS_DEVICE_INFO_SATA_DEVICE))
181	    == 0) {
182		start = 200;
183	} else {
184		/*
185		 * Use the enclosure number and slot number as a hint for target
186		 * numbering.  If that doesn't produce a sane result, search the
187		 * entire space.
188		 */
189#if 0
190		start = probe->encl_handle * 16 + probe->encl_slot;
191#else
192		start = probe->encl_slot;
193#endif
194		if (start >= sassc->sc->facts->MaxTargets)
195			start = 0;
196	}
197
198	target = mpssas_find_target(sassc, start, 0);
199
200	/*
201	 * Nothing found on the first pass, try a second pass that searches the
202	 * entire space.
203	 */
204	if (target == NULL)
205		target = mpssas_find_target(sassc, 0, 0);
206
207	return (target);
208}
209
210static struct mpssas_target *
211mpssas_find_target(struct mpssas_softc *sassc, int start, uint16_t handle)
212{
213	struct mpssas_target *target;
214	int i;
215
216	for (i = start; i < sassc->sc->facts->MaxTargets; i++) {
217		target = &sassc->targets[i];
218		if (target->handle == handle)
219			return (target);
220	}
221
222	return (NULL);
223}
224
225/*
226 * Start the probe sequence for a given device handle.  This will not
227 * block.
228 */
229static void
230mpssas_probe_device(struct mps_softc *sc, uint16_t handle)
231{
232	struct mpssas_devprobe *probe;
233	struct mps_config_params *params;
234	MPI2_CONFIG_EXTENDED_PAGE_HEADER *hdr;
235	int error;
236
237	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
238
239	probe = malloc(sizeof(*probe), M_MPSSAS, M_NOWAIT | M_ZERO);
240	if (probe == NULL) {
241		mps_dprint(sc, MPS_FAULT, "Out of memory starting probe\n");
242		return;
243	}
244	params = &probe->params;
245	hdr = &params->hdr.Ext;
246
247	params->action = MPI2_CONFIG_ACTION_PAGE_HEADER;
248	params->page_address = MPI2_SAS_DEVICE_PGAD_FORM_HANDLE | handle;
249	hdr->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE;
250	hdr->ExtPageLength = 0;
251	hdr->PageNumber = 0;
252	hdr->PageVersion = 0;
253	params->buffer = NULL;
254	params->length = 0;
255	params->callback = mpssas_probe_device_complete;
256	params->cbdata = probe;
257	probe->target.handle = handle;
258	probe->state = MPSSAS_PROBE_DEV1;
259
260	if ((error = mps_read_config_page(sc, params)) != 0) {
261		free(probe, M_MPSSAS);
262		mps_dprint(sc, MPS_FAULT, "Failure starting device probe\n");
263		return;
264	}
265}
266
267static void
268mpssas_probe_device_complete(struct mps_softc *sc,
269    struct mps_config_params *params)
270{
271	MPI2_CONFIG_EXTENDED_PAGE_HEADER *hdr;
272	struct mpssas_devprobe *probe;
273	int error;
274
275	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
276
277	hdr = &params->hdr.Ext;
278	probe = params->cbdata;
279
280	switch (probe->state) {
281	case MPSSAS_PROBE_DEV1:
282	case MPSSAS_PROBE_PHY:
283	case MPSSAS_PROBE_EXP:
284		if (params->status != MPI2_IOCSTATUS_SUCCESS) {
285			mps_dprint(sc, MPS_FAULT,
286			    "Probe Failure 0x%x state %d\n", params->status,
287			    probe->state);
288			free(probe, M_MPSSAS);
289			return;
290		}
291		params->action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
292		params->length = hdr->ExtPageLength * 4;
293		params->buffer = malloc(params->length, M_MPSSAS,
294		    M_ZERO|M_NOWAIT);
295		if (params->buffer == NULL) {
296			mps_dprint(sc, MPS_FAULT, "Out of memory at state "
297			   "0x%x, size 0x%x\n", probe->state, params->length);
298			free(probe, M_MPSSAS);
299			return;
300		}
301		if (probe->state == MPSSAS_PROBE_DEV1)
302			probe->state = MPSSAS_PROBE_DEV2;
303		else if (probe->state == MPSSAS_PROBE_PHY)
304			probe->state = MPSSAS_PROBE_PHY2;
305		else if (probe->state == MPSSAS_PROBE_EXP)
306			probe->state = MPSSAS_PROBE_EXP2;
307		error = mps_read_config_page(sc, params);
308		break;
309	case MPSSAS_PROBE_DEV2:
310	{
311		MPI2_CONFIG_PAGE_SAS_DEV_0 *buf;
312
313		if (params->status != MPI2_IOCSTATUS_SUCCESS) {
314			mps_dprint(sc, MPS_FAULT,
315			    "Probe Failure 0x%x state %d\n", params->status,
316			    probe->state);
317			free(params->buffer, M_MPSSAS);
318			free(probe, M_MPSSAS);
319			return;
320		}
321		buf = params->buffer;
322		mps_print_sasdev0(sc, buf);
323
324		probe->target.devname = mps_to_u64(&buf->DeviceName);
325		probe->target.devinfo = buf->DeviceInfo;
326		probe->target.encl_handle = buf->EnclosureHandle;
327		probe->target.encl_slot = buf->Slot;
328		probe->target.sasaddr = mps_to_u64(&buf->SASAddress);
329		probe->target.parent_handle = buf->ParentDevHandle;
330
331		if (buf->DeviceInfo & MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH) {
332			params->page_address =
333			    MPI2_SAS_PHY_PGAD_FORM_PHY_NUMBER | buf->PhyNum;
334			hdr->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_PHY;
335			hdr->PageNumber = 0;
336			probe->state = MPSSAS_PROBE_PHY;
337		} else {
338			params->page_address =
339			    MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |
340			    buf->ParentDevHandle | (buf->PhyNum << 16);
341			hdr->ExtPageType = MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
342			hdr->PageNumber = 1;
343			probe->state = MPSSAS_PROBE_EXP;
344		}
345		params->action = MPI2_CONFIG_ACTION_PAGE_HEADER;
346		hdr->ExtPageLength = 0;
347		hdr->PageVersion = 0;
348		params->buffer = NULL;
349		params->length = 0;
350		free(buf, M_MPSSAS);
351		error = mps_read_config_page(sc, params);
352		break;
353	}
354	case MPSSAS_PROBE_PHY2:
355	case MPSSAS_PROBE_EXP2:
356	{
357		MPI2_CONFIG_PAGE_SAS_PHY_0 *phy;
358		MPI2_CONFIG_PAGE_EXPANDER_1 *exp;
359		struct mpssas_softc *sassc;
360		struct mpssas_target *targ;
361		char devstring[80];
362		uint16_t handle;
363
364		if (params->status != MPI2_IOCSTATUS_SUCCESS) {
365			mps_dprint(sc, MPS_FAULT,
366			    "Probe Failure 0x%x state %d\n", params->status,
367			    probe->state);
368			free(params->buffer, M_MPSSAS);
369			free(probe, M_MPSSAS);
370			return;
371		}
372
373		if (probe->state == MPSSAS_PROBE_PHY2) {
374			phy = params->buffer;
375			mps_print_sasphy0(sc, phy);
376			probe->target.linkrate = phy->NegotiatedLinkRate & 0xf;
377		} else {
378			exp = params->buffer;
379			mps_print_expander1(sc, exp);
380			probe->target.linkrate = exp->NegotiatedLinkRate & 0xf;
381		}
382		free(params->buffer, M_MPSSAS);
383
384		sassc = sc->sassc;
385		handle = probe->target.handle;
386		if ((targ = mpssas_find_target(sassc, 0, handle)) != NULL) {
387			mps_printf(sc, "Ignoring dup device handle 0x%04x\n",
388			    handle);
389			free(probe, M_MPSSAS);
390			return;
391		}
392		if ((targ = mpssas_alloc_target(sassc, &probe->target)) == NULL) {
393			mps_printf(sc, "Target table overflow, handle 0x%04x\n",
394			    handle);
395			free(probe, M_MPSSAS);
396			return;
397		}
398
399		*targ = probe->target;	/* Copy the attributes */
400		targ->tid = targ - sassc->targets;
401		mps_describe_devinfo(targ->devinfo, devstring, 80);
402		if (bootverbose)
403			mps_printf(sc, "Found device <%s> <%s> <0x%04x> "
404			    "<%d/%d>\n", devstring,
405			    mps_describe_table(mps_linkrate_names,
406			    targ->linkrate), targ->handle, targ->encl_handle,
407			    targ->encl_slot);
408
409		free(probe, M_MPSSAS);
410		mpssas_announce_device(sassc, targ);
411		break;
412	}
413	default:
414		printf("what?\n");
415	}
416}
417
418/*
419 * The MPT2 firmware performs debounce on the link to avoid transient link errors
420 * and false removals.  When it does decide that link has been lost and a device
421 * need to go away, it expects that the host will perform a target reset and then
422 * an op remove.  The reset has the side-effect of aborting any outstanding
423 * requests for the device, which is required for the op-remove to succeed.  It's
424 * not clear if the host should check for the device coming back alive after the
425 * reset.
426 */
427static void
428mpssas_prepare_remove(struct mpssas_softc *sassc, MPI2_EVENT_SAS_TOPO_PHY_ENTRY *phy)
429{
430	MPI2_SCSI_TASK_MANAGE_REQUEST *req;
431	struct mps_softc *sc;
432	struct mps_command *cm;
433	struct mpssas_target *targ = NULL;
434	uint16_t handle;
435
436	mps_dprint(sassc->sc, MPS_TRACE, "%s\n", __func__);
437
438	handle = phy->AttachedDevHandle;
439	targ = mpssas_find_target(sassc, 0, handle);
440	if (targ == NULL)
441		/* We don't know about this device? */
442		return;
443
444	sc = sassc->sc;
445	cm = mps_alloc_command(sc);
446	if (cm == NULL) {
447		mps_printf(sc, "comand alloc failure in mpssas_prepare_remove\n");
448		return;
449	}
450
451	req = (MPI2_SCSI_TASK_MANAGE_REQUEST *)cm->cm_req;
452	req->DevHandle = targ->handle;
453	req->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
454	req->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
455
456	/* SAS Hard Link Reset / SATA Link Reset */
457	req->MsgFlags = MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET;
458
459	cm->cm_data = NULL;
460	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
461	cm->cm_complete = mpssas_remove_device;
462	cm->cm_targ = targ;
463	mpssas_issue_tm_request(sc, cm);
464}
465
466static void
467mpssas_remove_device(struct mps_softc *sc, struct mps_command *cm)
468{
469	MPI2_SCSI_TASK_MANAGE_REPLY *reply;
470	MPI2_SAS_IOUNIT_CONTROL_REQUEST *req;
471	struct mpssas_target *targ;
472	uint16_t handle;
473
474	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
475
476	reply = (MPI2_SCSI_TASK_MANAGE_REPLY *)cm->cm_reply;
477	handle = cm->cm_targ->handle;
478
479	mpssas_complete_tm_request(sc, cm, /*free_cm*/ 0);
480
481	if (reply->IOCStatus != MPI2_IOCSTATUS_SUCCESS) {
482		mps_printf(sc, "Failure 0x%x reseting device 0x%04x\n",
483		   reply->IOCStatus, handle);
484		mps_free_command(sc, cm);
485		return;
486	}
487
488	mps_printf(sc, "Reset aborted %d commands\n", reply->TerminationCount);
489	mps_free_reply(sc, cm->cm_reply_data);
490
491	/* Reuse the existing command */
492	req = (MPI2_SAS_IOUNIT_CONTROL_REQUEST *)cm->cm_req;
493	req->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
494	req->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
495	req->DevHandle = handle;
496	cm->cm_data = NULL;
497	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
498	cm->cm_flags &= ~MPS_CM_FLAGS_COMPLETE;
499	cm->cm_complete = mpssas_remove_complete;
500
501	mps_map_command(sc, cm);
502
503	mps_dprint(sc, MPS_INFO, "clearing target handle 0x%04x\n", handle);
504	targ = mpssas_find_target(sc->sassc, 0, handle);
505	if (targ != NULL) {
506		targ->handle = 0x0;
507		mpssas_announce_device(sc->sassc, targ);
508	}
509}
510
511static void
512mpssas_remove_complete(struct mps_softc *sc, struct mps_command *cm)
513{
514	MPI2_SAS_IOUNIT_CONTROL_REPLY *reply;
515
516	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
517
518	reply = (MPI2_SAS_IOUNIT_CONTROL_REPLY *)cm->cm_reply;
519
520	mps_printf(sc, "mpssas_remove_complete on target 0x%04x,"
521	   " IOCStatus= 0x%x\n", cm->cm_targ->tid, reply->IOCStatus);
522
523	mps_free_command(sc, cm);
524}
525
526static void
527mpssas_evt_handler(struct mps_softc *sc, uintptr_t data,
528    MPI2_EVENT_NOTIFICATION_REPLY *event)
529{
530	struct mpssas_softc *sassc;
531
532	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
533
534	sassc = sc->sassc;
535	mps_print_evt_sas(sc, event);
536
537	switch (event->Event) {
538	case MPI2_EVENT_SAS_DISCOVERY:
539	{
540		MPI2_EVENT_DATA_SAS_DISCOVERY *data;
541
542		data = (MPI2_EVENT_DATA_SAS_DISCOVERY *)&event->EventData;
543
544		if (data->ReasonCode & MPI2_EVENT_SAS_DISC_RC_STARTED)
545			mps_dprint(sc, MPS_TRACE,"SAS discovery start event\n");
546		if (data->ReasonCode & MPI2_EVENT_SAS_DISC_RC_COMPLETED) {
547			mps_dprint(sc, MPS_TRACE, "SAS discovery end event\n");
548			sassc->flags &= ~MPSSAS_IN_DISCOVERY;
549			mpssas_discovery_end(sassc);
550		}
551		break;
552	}
553	case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
554	{
555		MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *data;
556		MPI2_EVENT_SAS_TOPO_PHY_ENTRY *phy;
557		int i;
558
559		data = (MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *)
560		    &event->EventData;
561
562		if (data->ExpStatus == MPI2_EVENT_SAS_TOPO_ES_ADDED) {
563			if (bootverbose)
564				printf("Expander found at enclosure %d\n",
565				    data->EnclosureHandle);
566			mpssas_probe_device(sc, data->ExpanderDevHandle);
567		}
568
569		for (i = 0; i < data->NumEntries; i++) {
570			phy = &data->PHY[i];
571			switch (phy->PhyStatus & MPI2_EVENT_SAS_TOPO_RC_MASK) {
572			case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
573				mpssas_probe_device(sc, phy->AttachedDevHandle);
574				break;
575			case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
576				mpssas_prepare_remove(sassc, phy);
577				break;
578			case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
579			case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE:
580			case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING:
581			default:
582				break;
583			}
584		}
585
586		break;
587	}
588	case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
589		break;
590	default:
591		break;
592	}
593
594	mps_free_reply(sc, data);
595}
596
597static int
598mpssas_register_events(struct mps_softc *sc)
599{
600	uint8_t events[16];
601
602	bzero(events, 16);
603	setbit(events, MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE);
604	setbit(events, MPI2_EVENT_SAS_DISCOVERY);
605	setbit(events, MPI2_EVENT_SAS_BROADCAST_PRIMITIVE);
606	setbit(events, MPI2_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE);
607	setbit(events, MPI2_EVENT_SAS_INIT_TABLE_OVERFLOW);
608	setbit(events, MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST);
609	setbit(events, MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE);
610
611	mps_register_events(sc, events, mpssas_evt_handler, NULL,
612	    &sc->sassc->mpssas_eh);
613
614	return (0);
615}
616
617int
618mps_attach_sas(struct mps_softc *sc)
619{
620	struct mpssas_softc *sassc;
621	int error = 0;
622	int num_sim_reqs;
623
624	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
625
626	sassc = malloc(sizeof(struct mpssas_softc), M_MPT2, M_WAITOK|M_ZERO);
627	sassc->targets = malloc(sizeof(struct mpssas_target) *
628	    sc->facts->MaxTargets, M_MPT2, M_WAITOK|M_ZERO);
629	sc->sassc = sassc;
630	sassc->sc = sc;
631
632	/*
633	 * Tell CAM that we can handle 5 fewer requests than we have
634	 * allocated.  If we allow the full number of requests, all I/O
635	 * will halt when we run out of resources.  Things work fine with
636	 * just 1 less request slot given to CAM than we have allocated.
637	 * We also need a couple of extra commands so that we can send down
638	 * abort, reset, etc. requests when commands time out.  Otherwise
639	 * we could wind up in a situation with sc->num_reqs requests down
640	 * on the card and no way to send an abort.
641	 *
642	 * XXX KDM need to figure out why I/O locks up if all commands are
643	 * used.
644	 */
645	num_sim_reqs = sc->num_reqs - 5;
646
647	if ((sassc->devq = cam_simq_alloc(num_sim_reqs)) == NULL) {
648		mps_dprint(sc, MPS_FAULT, "Cannot allocate SIMQ\n");
649		error = ENOMEM;
650		goto out;
651	}
652
653	sassc->sim = cam_sim_alloc(mpssas_action, mpssas_poll, "mps", sassc,
654	    device_get_unit(sc->mps_dev), &sc->mps_mtx, num_sim_reqs,
655	    num_sim_reqs, sassc->devq);
656	if (sassc->sim == NULL) {
657		mps_dprint(sc, MPS_FAULT, "Cannot allocate SIM\n");
658		error = EINVAL;
659		goto out;
660	}
661
662	/*
663	 * XXX There should be a bus for every port on the adapter, but since
664	 * we're just going to fake the topology for now, we'll pretend that
665	 * everything is just a target on a single bus.
666	 */
667	mps_lock(sc);
668	if ((error = xpt_bus_register(sassc->sim, sc->mps_dev, 0)) != 0) {
669		mps_dprint(sc, MPS_FAULT, "Error %d registering SCSI bus\n",
670		    error);
671		mps_unlock(sc);
672		goto out;
673	}
674
675	/*
676	 * Assume that discovery events will start right away.  Freezing
677	 * the simq will prevent the CAM boottime scanner from running
678	 * before discovery is complete.
679	 */
680	sassc->flags = MPSSAS_IN_STARTUP | MPSSAS_IN_DISCOVERY;
681	xpt_freeze_simq(sassc->sim, 1);
682
683	mps_unlock(sc);
684
685	callout_init(&sassc->discovery_callout, 1 /*mpsafe*/);
686	sassc->discovery_timeouts = 0;
687
688	mpssas_register_events(sc);
689out:
690	if (error)
691		mps_detach_sas(sc);
692	return (error);
693}
694
695int
696mps_detach_sas(struct mps_softc *sc)
697{
698	struct mpssas_softc *sassc;
699
700	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
701
702	if (sc->sassc == NULL)
703		return (0);
704
705	sassc = sc->sassc;
706
707	/* Make sure CAM doesn't wedge if we had to bail out early. */
708	mps_lock(sc);
709	if (sassc->flags & MPSSAS_IN_STARTUP)
710		xpt_release_simq(sassc->sim, 1);
711	mps_unlock(sc);
712
713	if (sassc->mpssas_eh != NULL)
714		mps_deregister_events(sc, sassc->mpssas_eh);
715
716	mps_lock(sc);
717
718	if (sassc->sim != NULL) {
719		xpt_bus_deregister(cam_sim_path(sassc->sim));
720		cam_sim_free(sassc->sim, FALSE);
721	}
722	mps_unlock(sc);
723
724	if (sassc->devq != NULL)
725		cam_simq_free(sassc->devq);
726
727	free(sassc->targets, M_MPT2);
728	free(sassc, M_MPT2);
729	sc->sassc = NULL;
730
731	return (0);
732}
733
734static void
735mpssas_discovery_end(struct mpssas_softc *sassc)
736{
737	struct mps_softc *sc = sassc->sc;
738
739	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
740
741	if (sassc->flags & MPSSAS_DISCOVERY_TIMEOUT_PENDING)
742		callout_stop(&sassc->discovery_callout);
743
744	if ((sassc->flags & MPSSAS_IN_STARTUP) != 0) {
745		mps_dprint(sc, MPS_INFO,
746		    "mpssas_discovery_end: removing confighook\n");
747		sassc->flags &= ~MPSSAS_IN_STARTUP;
748		xpt_release_simq(sassc->sim, 1);
749	}
750#if 0
751	mpssas_announce_device(sassc, NULL);
752#endif
753
754}
755
756static void
757mpssas_announce_device(struct mpssas_softc *sassc, struct mpssas_target *targ)
758{
759	union ccb *ccb;
760	int bus, tid, lun;
761
762	/*
763	 * Force a rescan, a hackish way to announce devices.
764	 * XXX Doing a scan on an individual device is hackish in that it
765	 *     won't scan the LUNs.
766	 * XXX Does it matter if any of this fails?
767	 */
768	bus = cam_sim_path(sassc->sim);
769	if (targ != NULL) {
770		tid = targ->tid;
771		lun = 0;
772	} else {
773		tid = CAM_TARGET_WILDCARD;
774		lun = CAM_LUN_WILDCARD;
775	}
776	ccb = xpt_alloc_ccb_nowait();
777	if (ccb == NULL)
778		return;
779	if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, bus, tid,
780	    CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
781		xpt_free_ccb(ccb);
782		return;
783	}
784	mps_dprint(sassc->sc, MPS_INFO, "Triggering rescan of %d:%d:-1\n",
785	    bus, tid);
786	xpt_rescan(ccb);
787}
788
789static void
790mpssas_startup(void *data)
791{
792	struct mpssas_softc *sassc = data;
793
794	mps_dprint(sassc->sc, MPS_TRACE, "%s\n", __func__);
795
796	mps_lock(sassc->sc);
797	if ((sassc->flags & MPSSAS_IN_DISCOVERY) == 0) {
798		mpssas_discovery_end(sassc);
799	} else {
800		if (sassc->discovery_timeouts < MPSSAS_MAX_DISCOVERY_TIMEOUTS) {
801			sassc->flags |= MPSSAS_DISCOVERY_TIMEOUT_PENDING;
802			callout_reset(&sassc->discovery_callout,
803			    MPSSAS_DISCOVERY_TIMEOUT * hz,
804			    mpssas_discovery_timeout, sassc);
805			sassc->discovery_timeouts++;
806		} else {
807			mps_dprint(sassc->sc, MPS_FAULT,
808			    "Discovery timed out, continuing.\n");
809			sassc->flags &= ~MPSSAS_IN_DISCOVERY;
810			mpssas_discovery_end(sassc);
811		}
812	}
813	mps_unlock(sassc->sc);
814
815	return;
816}
817
818static void
819mpssas_discovery_timeout(void *data)
820{
821	struct mpssas_softc *sassc = data;
822	struct mps_softc *sc;
823
824	sc = sassc->sc;
825	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
826
827	mps_lock(sc);
828	mps_printf(sc,
829	    "Timeout waiting for discovery, interrupts may not be working!\n");
830	sassc->flags &= ~MPSSAS_DISCOVERY_TIMEOUT_PENDING;
831
832	/* Poll the hardware for events in case interrupts aren't working */
833	mps_intr_locked(sc);
834	mps_unlock(sc);
835
836	/* Check the status of discovery and re-arm the timeout if needed */
837	mpssas_startup(sassc);
838}
839
840static void
841mpssas_action(struct cam_sim *sim, union ccb *ccb)
842{
843	struct mpssas_softc *sassc;
844
845	sassc = cam_sim_softc(sim);
846
847	mps_dprint(sassc->sc, MPS_TRACE, "%s func 0x%x\n", __func__,
848	    ccb->ccb_h.func_code);
849
850	switch (ccb->ccb_h.func_code) {
851	case XPT_PATH_INQ:
852	{
853		struct ccb_pathinq *cpi = &ccb->cpi;
854
855		cpi->version_num = 1;
856		cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
857		cpi->target_sprt = 0;
858		cpi->hba_misc = PIM_NOBUSRESET;
859		cpi->hba_eng_cnt = 0;
860		cpi->max_target = sassc->sc->facts->MaxTargets - 1;
861		cpi->max_lun = 0;
862		cpi->initiator_id = 255;
863		strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
864		strncpy(cpi->hba_vid, "LSILogic", HBA_IDLEN);
865		strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
866		cpi->unit_number = cam_sim_unit(sim);
867		cpi->bus_id = cam_sim_bus(sim);
868		cpi->base_transfer_speed = 150000;
869		cpi->transport = XPORT_SAS;
870		cpi->transport_version = 0;
871		cpi->protocol = PROTO_SCSI;
872		cpi->protocol_version = SCSI_REV_SPC;
873		cpi->ccb_h.status = CAM_REQ_CMP;
874		break;
875	}
876	case XPT_GET_TRAN_SETTINGS:
877	{
878		struct ccb_trans_settings	*cts;
879		struct ccb_trans_settings_sas	*sas;
880		struct ccb_trans_settings_scsi	*scsi;
881		struct mpssas_target *targ;
882
883		cts = &ccb->cts;
884		sas = &cts->xport_specific.sas;
885		scsi = &cts->proto_specific.scsi;
886
887		targ = &sassc->targets[cts->ccb_h.target_id];
888		if (targ->handle == 0x0) {
889			cts->ccb_h.status = CAM_TID_INVALID;
890			break;
891		}
892
893		cts->protocol_version = SCSI_REV_SPC2;
894		cts->transport = XPORT_SAS;
895		cts->transport_version = 0;
896
897		sas->valid = CTS_SAS_VALID_SPEED;
898		switch (targ->linkrate) {
899		case 0x08:
900			sas->bitrate = 150000;
901			break;
902		case 0x09:
903			sas->bitrate = 300000;
904			break;
905		case 0x0a:
906			sas->bitrate = 600000;
907			break;
908		default:
909			sas->valid = 0;
910		}
911
912		cts->protocol = PROTO_SCSI;
913		scsi->valid = CTS_SCSI_VALID_TQ;
914		scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
915
916		cts->ccb_h.status = CAM_REQ_CMP;
917		break;
918	}
919	case XPT_CALC_GEOMETRY:
920		cam_calc_geometry(&ccb->ccg, /*extended*/1);
921		ccb->ccb_h.status = CAM_REQ_CMP;
922		break;
923	case XPT_RESET_DEV:
924		mpssas_action_resetdev(sassc, ccb);
925		return;
926	case XPT_RESET_BUS:
927	case XPT_ABORT:
928	case XPT_TERM_IO:
929		ccb->ccb_h.status = CAM_REQ_CMP;
930		break;
931	case XPT_SCSI_IO:
932		mpssas_action_scsiio(sassc, ccb);
933		return;
934#if __FreeBSD_version >= 900026
935	case XPT_SMP_IO:
936		mpssas_action_smpio(sassc, ccb);
937		return;
938#endif /* __FreeBSD_version >= 900026 */
939	default:
940		ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
941		break;
942	}
943	xpt_done(ccb);
944
945}
946
947#if 0
948static void
949mpssas_resettimeout_complete(struct mps_softc *sc, struct mps_command *cm)
950{
951	MPI2_SCSI_TASK_MANAGE_REPLY *resp;
952	uint16_t code;
953
954	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
955
956	resp = (MPI2_SCSI_TASK_MANAGE_REPLY *)cm->cm_reply;
957	code = resp->ResponseCode;
958
959	mps_free_command(sc, cm);
960	mpssas_unfreeze_device(sassc, targ);
961
962	if (code != MPI2_SCSITASKMGMT_RSP_TM_COMPLETE) {
963		mps_reset_controller(sc);
964	}
965
966	return;
967}
968#endif
969
970static void
971mpssas_scsiio_timeout(void *data)
972{
973	union ccb *ccb;
974	struct mps_softc *sc;
975	struct mps_command *cm;
976	struct mpssas_target *targ;
977#if 0
978	char cdb_str[(SCSI_MAX_CDBLEN * 3) + 1];
979#endif
980
981	cm = (struct mps_command *)data;
982	sc = cm->cm_sc;
983
984	/*
985	 * Run the interrupt handler to make sure it's not pending.  This
986	 * isn't perfect because the command could have already completed
987	 * and been re-used, though this is unlikely.
988	 */
989	mps_lock(sc);
990	mps_intr_locked(sc);
991	if (cm->cm_state == MPS_CM_STATE_FREE) {
992		mps_unlock(sc);
993		return;
994	}
995
996	ccb = cm->cm_complete_data;
997	targ = cm->cm_targ;
998	if (targ == 0x00)
999		/* Driver bug */
1000		targ = &sc->sassc->targets[ccb->ccb_h.target_id];
1001
1002	xpt_print(ccb->ccb_h.path, "SCSI command timeout on device handle "
1003		  "0x%04x SMID %d\n", targ->handle, cm->cm_desc.Default.SMID);
1004	/*
1005	 * XXX KDM this is useful for debugging purposes, but the existing
1006	 * scsi_op_desc() implementation can't handle a NULL value for
1007	 * inq_data.  So this will remain commented out until I bring in
1008	 * those changes as well.
1009	 */
1010#if 0
1011	xpt_print(ccb->ccb_h.path, "Timed out command: %s. CDB %s\n",
1012		  scsi_op_desc((ccb->ccb_h.flags & CAM_CDB_POINTER) ?
1013		  		ccb->csio.cdb_io.cdb_ptr[0] :
1014				ccb->csio.cdb_io.cdb_bytes[0], NULL),
1015		  scsi_cdb_string((ccb->ccb_h.flags & CAM_CDB_POINTER) ?
1016				   ccb->csio.cdb_io.cdb_ptr :
1017				   ccb->csio.cdb_io.cdb_bytes, cdb_str,
1018		  		   sizeof(cdb_str)));
1019#endif
1020
1021	/* Inform CAM about the timeout and that recovery is starting. */
1022#if 0
1023	if ((targ->flags & MPSSAS_TARGET_INRECOVERY) == 0) {
1024		mpssas_freeze_device(sc->sassc, targ);
1025		ccb->ccb_h.status = CAM_CMD_TIMEOUT;
1026		xpt_done(ccb);
1027	}
1028#endif
1029	mpssas_freeze_device(sc->sassc, targ);
1030	ccb->ccb_h.status = CAM_CMD_TIMEOUT;
1031
1032	/*
1033	 * recycle the command into recovery so that there's no risk of
1034	 * command allocation failure.
1035	 */
1036	cm->cm_state = MPS_CM_STATE_TIMEDOUT;
1037	mpssas_recovery(sc, cm);
1038	mps_unlock(sc);
1039}
1040
1041static void
1042mpssas_abort_complete(struct mps_softc *sc, struct mps_command *cm)
1043{
1044	MPI2_SCSI_TASK_MANAGE_REQUEST *req;
1045
1046	req = (MPI2_SCSI_TASK_MANAGE_REQUEST *)cm->cm_req;
1047
1048	mps_printf(sc, "%s: abort request on handle %#04x SMID %d "
1049		   "complete\n", __func__, req->DevHandle, req->TaskMID);
1050
1051	mpssas_complete_tm_request(sc, cm, /*free_cm*/ 1);
1052}
1053
1054static void
1055mpssas_recovery(struct mps_softc *sc, struct mps_command *abort_cm)
1056{
1057	struct mps_command *cm;
1058	MPI2_SCSI_TASK_MANAGE_REQUEST *req, *orig_req;
1059
1060	cm = mps_alloc_command(sc);
1061	if (cm == NULL) {
1062		mps_printf(sc, "%s: command allocation failure\n", __func__);
1063		return;
1064	}
1065
1066	cm->cm_targ = abort_cm->cm_targ;
1067	cm->cm_complete = mpssas_abort_complete;
1068
1069	req = (MPI2_SCSI_TASK_MANAGE_REQUEST *)cm->cm_req;
1070	orig_req = (MPI2_SCSI_TASK_MANAGE_REQUEST *)abort_cm->cm_req;
1071	req->DevHandle = abort_cm->cm_targ->handle;
1072	req->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
1073	req->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK;
1074	memcpy(req->LUN, orig_req->LUN, sizeof(req->LUN));
1075	req->TaskMID = abort_cm->cm_desc.Default.SMID;
1076
1077	cm->cm_data = NULL;
1078	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1079
1080	mpssas_issue_tm_request(sc, cm);
1081
1082}
1083
1084/*
1085 * Can return 0 or EINPROGRESS on success.  Any other value means failure.
1086 */
1087static int
1088mpssas_map_tm_request(struct mps_softc *sc, struct mps_command *cm)
1089{
1090	int error;
1091
1092	error = 0;
1093
1094	cm->cm_flags |= MPS_CM_FLAGS_ACTIVE;
1095	error = mps_map_command(sc, cm);
1096	if ((error == 0)
1097	 || (error == EINPROGRESS))
1098		sc->tm_cmds_active++;
1099
1100	return (error);
1101}
1102
1103static void
1104mpssas_issue_tm_request(struct mps_softc *sc, struct mps_command *cm)
1105{
1106	int freeze_queue, send_command, error;
1107
1108	freeze_queue = 0;
1109	send_command = 0;
1110	error = 0;
1111
1112	mtx_assert(&sc->mps_mtx, MA_OWNED);
1113
1114	/*
1115	 * If there are no other pending task management commands, go
1116	 * ahead and send this one.  There is a small amount of anecdotal
1117	 * evidence that sending lots of task management commands at once
1118	 * may cause the controller to lock up.  Or, if the user has
1119	 * configured the driver (via the allow_multiple_tm_cmds variable) to
1120	 * not serialize task management commands, go ahead and send the
1121	 * command if even other task management commands are pending.
1122	 */
1123	if (TAILQ_FIRST(&sc->tm_list) == NULL) {
1124		send_command = 1;
1125		freeze_queue = 1;
1126	} else if (sc->allow_multiple_tm_cmds != 0)
1127		send_command = 1;
1128
1129	TAILQ_INSERT_TAIL(&sc->tm_list, cm, cm_link);
1130	if (send_command != 0) {
1131		/*
1132		 * Freeze the SIM queue while we issue the task management
1133		 * command.  According to the Fusion-MPT 2.0 spec, task
1134		 * management requests are serialized, and so the host
1135		 * should not send any I/O requests while task management
1136		 * requests are pending.
1137		 */
1138		if (freeze_queue != 0)
1139			xpt_freeze_simq(sc->sassc->sim, 1);
1140
1141		error = mpssas_map_tm_request(sc, cm);
1142
1143		/*
1144		 * At present, there is no error path back from
1145		 * mpssas_map_tm_request() (which calls mps_map_command())
1146		 * when cm->cm_data == NULL.  But since there is a return
1147		 * value, we check it just in case the implementation
1148		 * changes later.
1149		 */
1150		if ((error != 0)
1151		 && (error != EINPROGRESS))
1152			mpssas_tm_complete(sc, cm,
1153			    MPI2_SCSITASKMGMT_RSP_TM_FAILED);
1154	}
1155}
1156
1157static void
1158mpssas_tm_complete(struct mps_softc *sc, struct mps_command *cm, int error)
1159{
1160	MPI2_SCSI_TASK_MANAGE_REPLY *resp;
1161
1162	resp = (MPI2_SCSI_TASK_MANAGE_REPLY *)cm->cm_reply;
1163
1164	resp->ResponseCode = error;
1165
1166	/*
1167	 * Call the callback for this command, it will be
1168	 * removed from the list and freed via the callback.
1169	 */
1170	cm->cm_complete(sc, cm);
1171}
1172
1173/*
1174 * Complete a task management request.  The basic completion operation will
1175 * always succeed.  Returns status for sending any further task management
1176 * commands that were queued.
1177 */
1178static int
1179mpssas_complete_tm_request(struct mps_softc *sc, struct mps_command *cm,
1180			   int free_cm)
1181{
1182	int error;
1183
1184	error = 0;
1185
1186	mtx_assert(&sc->mps_mtx, MA_OWNED);
1187
1188	TAILQ_REMOVE(&sc->tm_list, cm, cm_link);
1189	cm->cm_flags &= ~MPS_CM_FLAGS_ACTIVE;
1190	sc->tm_cmds_active--;
1191
1192	if (free_cm != 0)
1193		mps_free_command(sc, cm);
1194
1195	if (TAILQ_FIRST(&sc->tm_list) == NULL) {
1196		/*
1197		 * Release the SIM queue, we froze it when we sent the first
1198		 * task management request.
1199		 */
1200		xpt_release_simq(sc->sassc->sim, 1);
1201	} else if ((sc->tm_cmds_active == 0)
1202		|| (sc->allow_multiple_tm_cmds != 0)) {
1203		int error;
1204		struct mps_command *cm2;
1205
1206restart_traversal:
1207
1208		/*
1209		 * We don't bother using TAILQ_FOREACH_SAFE here, but
1210		 * rather use the standard version and just restart the
1211		 * list traversal if we run into the error case.
1212		 * TAILQ_FOREACH_SAFE allows safe removal of the current
1213		 * list element, but if you have a queue of task management
1214		 * commands, all of which have mapping errors, you'll end
1215		 * up with recursive calls to this routine and so you could
1216		 * wind up removing more than just the current list element.
1217		 */
1218		TAILQ_FOREACH(cm2, &sc->tm_list, cm_link) {
1219			MPI2_SCSI_TASK_MANAGE_REQUEST *req;
1220
1221			/* This command is active, no need to send it again */
1222			if (cm2->cm_flags & MPS_CM_FLAGS_ACTIVE)
1223				continue;
1224
1225			req = (MPI2_SCSI_TASK_MANAGE_REQUEST *)cm2->cm_req;
1226
1227			mps_printf(sc, "%s: sending deferred task management "
1228			    "request for handle %#04x SMID %d\n", __func__,
1229			    req->DevHandle, req->TaskMID);
1230
1231			error = mpssas_map_tm_request(sc, cm2);
1232
1233			/*
1234			 * Check for errors.  If we had an error, complete
1235			 * this command with an error, and keep going through
1236			 * the list until we are able to send at least one
1237			 * command or all of them are completed with errors.
1238			 *
1239			 * We don't want to wind up in a situation where
1240			 * we're stalled out with no way for queued task
1241			 * management commands to complete.
1242			 *
1243			 * Note that there is not currently an error path
1244			 * back from mpssas_map_tm_request() (which calls
1245			 * mps_map_command()) when cm->cm_data == NULL.
1246			 * But we still want to check for errors here in
1247			 * case the implementation changes, or in case
1248			 * there is some reason for a data payload here.
1249			 */
1250			if ((error != 0)
1251			 && (error != EINPROGRESS)) {
1252				mpssas_tm_complete(sc, cm,
1253				    MPI2_SCSITASKMGMT_RSP_TM_FAILED);
1254
1255				/*
1256				 * If we don't currently have any commands
1257				 * active, go back to the beginning and see
1258				 * if there are any more that can be started.
1259				 * Otherwise, we're done here.
1260				 */
1261				if (sc->tm_cmds_active == 0)
1262					goto restart_traversal;
1263				else
1264					break;
1265			}
1266
1267			/*
1268			 * If the user only wants one task management command
1269			 * active at a time, we're done, since we've
1270			 * already successfully sent a command at this point.
1271			 */
1272			if (sc->allow_multiple_tm_cmds == 0)
1273				break;
1274		}
1275	}
1276
1277	return (error);
1278}
1279
1280static void
1281mpssas_action_scsiio(struct mpssas_softc *sassc, union ccb *ccb)
1282{
1283	MPI2_SCSI_IO_REQUEST *req;
1284	struct ccb_scsiio *csio;
1285	struct mps_softc *sc;
1286	struct mpssas_target *targ;
1287	struct mps_command *cm;
1288
1289	mps_dprint(sassc->sc, MPS_TRACE, "%s\n", __func__);
1290
1291	sc = sassc->sc;
1292
1293	csio = &ccb->csio;
1294	targ = &sassc->targets[csio->ccb_h.target_id];
1295	if (targ->handle == 0x0) {
1296		csio->ccb_h.status = CAM_SEL_TIMEOUT;
1297		xpt_done(ccb);
1298		return;
1299	}
1300
1301	cm = mps_alloc_command(sc);
1302	if (cm == NULL) {
1303		if ((sassc->flags & MPSSAS_QUEUE_FROZEN) == 0) {
1304			xpt_freeze_simq(sassc->sim, 1);
1305			sassc->flags |= MPSSAS_QUEUE_FROZEN;
1306		}
1307		ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1308		ccb->ccb_h.status |= CAM_REQUEUE_REQ;
1309		xpt_done(ccb);
1310		return;
1311	}
1312
1313	req = (MPI2_SCSI_IO_REQUEST *)cm->cm_req;
1314	req->DevHandle = targ->handle;
1315	req->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
1316	req->MsgFlags = 0;
1317	req->SenseBufferLowAddress = cm->cm_sense_busaddr;
1318	req->SenseBufferLength = MPS_SENSE_LEN;
1319	req->SGLFlags = 0;
1320	req->ChainOffset = 0;
1321	req->SGLOffset0 = 24;	/* 32bit word offset to the SGL */
1322	req->SGLOffset1= 0;
1323	req->SGLOffset2= 0;
1324	req->SGLOffset3= 0;
1325	req->SkipCount = 0;
1326	req->DataLength = csio->dxfer_len;
1327	req->BidirectionalDataLength = 0;
1328	req->IoFlags = csio->cdb_len;
1329	req->EEDPFlags = 0;
1330
1331	/* Note: BiDirectional transfers are not supported */
1332	switch (csio->ccb_h.flags & CAM_DIR_MASK) {
1333	case CAM_DIR_IN:
1334		req->Control = MPI2_SCSIIO_CONTROL_READ;
1335		cm->cm_flags |= MPS_CM_FLAGS_DATAIN;
1336		break;
1337	case CAM_DIR_OUT:
1338		req->Control = MPI2_SCSIIO_CONTROL_WRITE;
1339		cm->cm_flags |= MPS_CM_FLAGS_DATAOUT;
1340		break;
1341	case CAM_DIR_NONE:
1342	default:
1343		req->Control = MPI2_SCSIIO_CONTROL_NODATATRANSFER;
1344		break;
1345	}
1346
1347	/*
1348	 * It looks like the hardware doesn't require an explicit tag
1349	 * number for each transaction.  SAM Task Management not supported
1350	 * at the moment.
1351	 */
1352	switch (csio->tag_action) {
1353	case MSG_HEAD_OF_Q_TAG:
1354		req->Control |= MPI2_SCSIIO_CONTROL_HEADOFQ;
1355		break;
1356	case MSG_ORDERED_Q_TAG:
1357		req->Control |= MPI2_SCSIIO_CONTROL_ORDEREDQ;
1358		break;
1359	case MSG_ACA_TASK:
1360		req->Control |= MPI2_SCSIIO_CONTROL_ACAQ;
1361		break;
1362	case CAM_TAG_ACTION_NONE:
1363	case MSG_SIMPLE_Q_TAG:
1364	default:
1365		req->Control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
1366		break;
1367	}
1368
1369	/* XXX Need to handle multi-level LUNs */
1370	if (csio->ccb_h.target_lun > 255) {
1371		mps_free_command(sc, cm);
1372		ccb->ccb_h.status = CAM_LUN_INVALID;
1373		xpt_done(ccb);
1374		return;
1375	}
1376	req->LUN[1] = csio->ccb_h.target_lun;
1377
1378	if (csio->ccb_h.flags & CAM_CDB_POINTER)
1379		bcopy(csio->cdb_io.cdb_ptr, &req->CDB.CDB32[0], csio->cdb_len);
1380	else
1381		bcopy(csio->cdb_io.cdb_bytes, &req->CDB.CDB32[0],csio->cdb_len);
1382	req->IoFlags = csio->cdb_len;
1383
1384	/*
1385	 * XXX need to handle S/G lists and physical addresses here.
1386	 */
1387	cm->cm_data = csio->data_ptr;
1388	cm->cm_length = csio->dxfer_len;
1389	cm->cm_sge = &req->SGL;
1390	cm->cm_sglsize = (32 - 24) * 4;
1391	cm->cm_desc.SCSIIO.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
1392	cm->cm_desc.SCSIIO.DevHandle = targ->handle;
1393	cm->cm_complete = mpssas_scsiio_complete;
1394	cm->cm_complete_data = ccb;
1395	cm->cm_targ = targ;
1396
1397	callout_reset(&cm->cm_callout, (ccb->ccb_h.timeout * hz) / 1000,
1398	   mpssas_scsiio_timeout, cm);
1399
1400	mps_map_command(sc, cm);
1401	return;
1402}
1403
1404static void
1405mpssas_scsiio_complete(struct mps_softc *sc, struct mps_command *cm)
1406{
1407	MPI2_SCSI_IO_REPLY *rep;
1408	union ccb *ccb;
1409	struct mpssas_softc *sassc;
1410	u_int sense_len;
1411	int dir = 0;
1412
1413	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
1414
1415	callout_stop(&cm->cm_callout);
1416
1417	sassc = sc->sassc;
1418	ccb = cm->cm_complete_data;
1419	rep = (MPI2_SCSI_IO_REPLY *)cm->cm_reply;
1420
1421	if (cm->cm_data != NULL) {
1422		if (cm->cm_flags & MPS_CM_FLAGS_DATAIN)
1423			dir = BUS_DMASYNC_POSTREAD;
1424		else if (cm->cm_flags & MPS_CM_FLAGS_DATAOUT)
1425			dir = BUS_DMASYNC_POSTWRITE;;
1426		bus_dmamap_sync(sc->buffer_dmat, cm->cm_dmamap, dir);
1427		bus_dmamap_unload(sc->buffer_dmat, cm->cm_dmamap);
1428	}
1429
1430	if (sassc->flags & MPSSAS_QUEUE_FROZEN) {
1431		ccb->ccb_h.flags |= CAM_RELEASE_SIMQ;
1432		sassc->flags &= ~MPSSAS_QUEUE_FROZEN;
1433	}
1434
1435	/* Take the fast path to completion */
1436	if (cm->cm_reply == NULL) {
1437		ccb->ccb_h.status = CAM_REQ_CMP;
1438		ccb->csio.scsi_status = SCSI_STATUS_OK;
1439		mps_free_command(sc, cm);
1440		xpt_done(ccb);
1441		return;
1442	}
1443
1444	mps_dprint(sc, MPS_INFO, "(%d:%d:%d) IOCStatus= 0x%x, "
1445	    "ScsiStatus= 0x%x, SCSIState= 0x%x TransferCount= 0x%x\n",
1446	    xpt_path_path_id(ccb->ccb_h.path),
1447	    xpt_path_target_id(ccb->ccb_h.path),
1448	    xpt_path_lun_id(ccb->ccb_h.path), rep->IOCStatus,
1449	    rep->SCSIStatus, rep->SCSIState, rep->TransferCount);
1450
1451	switch (rep->IOCStatus & MPI2_IOCSTATUS_MASK) {
1452	case MPI2_IOCSTATUS_BUSY:
1453	case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
1454		/*
1455		 * The controller is overloaded, try waiting a bit for it
1456		 * to free up.
1457		 */
1458		ccb->ccb_h.status = CAM_BUSY;
1459		break;
1460	case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN:
1461		ccb->csio.resid = cm->cm_length - rep->TransferCount;
1462		/* FALLTHROUGH */
1463	case MPI2_IOCSTATUS_SUCCESS:
1464	case MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR:
1465		ccb->ccb_h.status = CAM_REQ_CMP;
1466		break;
1467	case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN:
1468		/* resid is ignored for this condition */
1469		ccb->csio.resid = 0;
1470		ccb->ccb_h.status = CAM_DATA_RUN_ERR;
1471		break;
1472	case MPI2_IOCSTATUS_SCSI_INVALID_DEVHANDLE:
1473	case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
1474		ccb->ccb_h.status = CAM_DEV_NOT_THERE;
1475		break;
1476	case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
1477		/*
1478		 * This is one of the responses that comes back when an I/O
1479		 * has been aborted.  If it is because of a timeout that we
1480		 * initiated, just set the status to CAM_CMD_TIMEOUT.
1481		 * Otherwise set it to CAM_REQ_ABORTED.  The effect on the
1482		 * command is the same (it gets retried, subject to the
1483		 * retry counter), the only difference is what gets printed
1484		 * on the console.
1485		 */
1486		if (cm->cm_state == MPS_CM_STATE_TIMEDOUT)
1487			ccb->ccb_h.status = CAM_CMD_TIMEOUT;
1488		else
1489			ccb->ccb_h.status = CAM_REQ_ABORTED;
1490		break;
1491	case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
1492	case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
1493		ccb->ccb_h.status = CAM_REQ_ABORTED;
1494		break;
1495	case MPI2_IOCSTATUS_INVALID_SGL:
1496		mps_print_scsiio_cmd(sc, cm);
1497		ccb->ccb_h.status = CAM_UNREC_HBA_ERROR;
1498		break;
1499	case MPI2_IOCSTATUS_INVALID_FUNCTION:
1500	case MPI2_IOCSTATUS_INTERNAL_ERROR:
1501	case MPI2_IOCSTATUS_INVALID_VPID:
1502	case MPI2_IOCSTATUS_INVALID_FIELD:
1503	case MPI2_IOCSTATUS_INVALID_STATE:
1504	case MPI2_IOCSTATUS_OP_STATE_NOT_SUPPORTED:
1505	case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR:
1506	case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
1507	case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
1508	case MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
1509	default:
1510		ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1511	}
1512
1513
1514	if ((rep->SCSIState & MPI2_SCSI_STATE_NO_SCSI_STATUS) == 0) {
1515		ccb->csio.scsi_status = rep->SCSIStatus;
1516
1517		switch (rep->SCSIStatus) {
1518		case MPI2_SCSI_STATUS_TASK_SET_FULL:
1519		case MPI2_SCSI_STATUS_CHECK_CONDITION:
1520			ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
1521			break;
1522		case MPI2_SCSI_STATUS_COMMAND_TERMINATED:
1523		case MPI2_SCSI_STATUS_TASK_ABORTED:
1524			ccb->ccb_h.status = CAM_REQ_ABORTED;
1525			break;
1526		case MPI2_SCSI_STATUS_GOOD:
1527		default:
1528			break;
1529		}
1530	}
1531
1532	if (rep->SCSIState & MPI2_SCSI_STATE_AUTOSENSE_VALID) {
1533		sense_len = MIN(rep->SenseCount,
1534		    sizeof(struct scsi_sense_data));
1535		if (sense_len < rep->SenseCount)
1536			ccb->csio.sense_resid = rep->SenseCount - sense_len;
1537		bcopy(cm->cm_sense, &ccb->csio.sense_data, sense_len);
1538		ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
1539	}
1540
1541	if (rep->SCSIState & MPI2_SCSI_STATE_AUTOSENSE_FAILED)
1542		ccb->ccb_h.status = CAM_AUTOSENSE_FAIL;
1543
1544	if (rep->SCSIState & MPI2_SCSI_STATE_RESPONSE_INFO_VALID)
1545		ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1546
1547	mps_free_command(sc, cm);
1548	xpt_done(ccb);
1549}
1550
1551#if __FreeBSD_version >= 900026
1552static void
1553mpssas_smpio_complete(struct mps_softc *sc, struct mps_command *cm)
1554{
1555	MPI2_SMP_PASSTHROUGH_REPLY *rpl;
1556	MPI2_SMP_PASSTHROUGH_REQUEST *req;
1557	uint64_t sasaddr;
1558	union ccb *ccb;
1559
1560	ccb = cm->cm_complete_data;
1561	rpl = (MPI2_SMP_PASSTHROUGH_REPLY *)cm->cm_reply;
1562	if (rpl == NULL) {
1563		mps_dprint(sc, MPS_INFO, "%s: NULL cm_reply!\n", __func__);
1564		ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1565		goto bailout;
1566	}
1567
1568	req = (MPI2_SMP_PASSTHROUGH_REQUEST *)cm->cm_req;
1569	sasaddr = le32toh(req->SASAddress.Low);
1570	sasaddr |= ((uint64_t)(le32toh(req->SASAddress.High))) << 32;
1571
1572	if ((rpl->IOCStatus & MPI2_IOCSTATUS_MASK) != MPI2_IOCSTATUS_SUCCESS ||
1573	    rpl->SASStatus != MPI2_SASSTATUS_SUCCESS) {
1574		mps_dprint(sc, MPS_INFO, "%s: IOCStatus %04x SASStatus %02x\n",
1575		    __func__, rpl->IOCStatus, rpl->SASStatus);
1576		ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1577		goto bailout;
1578	}
1579
1580	mps_dprint(sc, MPS_INFO, "%s: SMP request to SAS address "
1581		   "%#jx completed successfully\n", __func__,
1582		   (uintmax_t)sasaddr);
1583
1584	if (ccb->smpio.smp_response[2] == SMP_FR_ACCEPTED)
1585		ccb->ccb_h.status = CAM_REQ_CMP;
1586	else
1587		ccb->ccb_h.status = CAM_SMP_STATUS_ERROR;
1588
1589bailout:
1590	/*
1591	 * We sync in both directions because we had DMAs in the S/G list
1592	 * in both directions.
1593	 */
1594	bus_dmamap_sync(sc->buffer_dmat, cm->cm_dmamap,
1595			BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
1596	bus_dmamap_unload(sc->buffer_dmat, cm->cm_dmamap);
1597	mps_free_command(sc, cm);
1598	xpt_done(ccb);
1599}
1600
1601static void
1602mpssas_send_smpcmd(struct mpssas_softc *sassc, union ccb *ccb, uint64_t sasaddr)
1603{
1604	struct mps_command *cm;
1605	uint8_t *request, *response;
1606	MPI2_SMP_PASSTHROUGH_REQUEST *req;
1607	struct mps_softc *sc;
1608	struct sglist *sg;
1609	int error;
1610
1611	sc = sassc->sc;
1612	sg = NULL;
1613	error = 0;
1614
1615	/*
1616	 * XXX We don't yet support physical addresses here.
1617	 */
1618	if (ccb->ccb_h.flags & (CAM_DATA_PHYS|CAM_SG_LIST_PHYS)) {
1619		mps_printf(sc, "%s: physical addresses not supported\n",
1620			   __func__);
1621		ccb->ccb_h.status = CAM_REQ_INVALID;
1622		xpt_done(ccb);
1623		return;
1624	}
1625
1626	/*
1627	 * If the user wants to send an S/G list, check to make sure they
1628	 * have single buffers.
1629	 */
1630	if (ccb->ccb_h.flags & CAM_SCATTER_VALID) {
1631		/*
1632		 * The chip does not support more than one buffer for the
1633		 * request or response.
1634		 */
1635	 	if ((ccb->smpio.smp_request_sglist_cnt > 1)
1636		  || (ccb->smpio.smp_response_sglist_cnt > 1)) {
1637			mps_printf(sc, "%s: multiple request or response "
1638				   "buffer segments not supported for SMP\n",
1639				   __func__);
1640			ccb->ccb_h.status = CAM_REQ_INVALID;
1641			xpt_done(ccb);
1642			return;
1643		}
1644
1645		/*
1646		 * The CAM_SCATTER_VALID flag was originally implemented
1647		 * for the XPT_SCSI_IO CCB, which only has one data pointer.
1648		 * We have two.  So, just take that flag to mean that we
1649		 * might have S/G lists, and look at the S/G segment count
1650		 * to figure out whether that is the case for each individual
1651		 * buffer.
1652		 */
1653		if (ccb->smpio.smp_request_sglist_cnt != 0) {
1654			bus_dma_segment_t *req_sg;
1655
1656			req_sg = (bus_dma_segment_t *)ccb->smpio.smp_request;
1657			request = (uint8_t *)req_sg[0].ds_addr;
1658		} else
1659			request = ccb->smpio.smp_request;
1660
1661		if (ccb->smpio.smp_response_sglist_cnt != 0) {
1662			bus_dma_segment_t *rsp_sg;
1663
1664			rsp_sg = (bus_dma_segment_t *)ccb->smpio.smp_response;
1665			response = (uint8_t *)rsp_sg[0].ds_addr;
1666		} else
1667			response = ccb->smpio.smp_response;
1668	} else {
1669		request = ccb->smpio.smp_request;
1670		response = ccb->smpio.smp_response;
1671	}
1672
1673	cm = mps_alloc_command(sc);
1674	if (cm == NULL) {
1675		mps_printf(sc, "%s: cannot allocate command\n", __func__);
1676		ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1677		xpt_done(ccb);
1678		return;
1679	}
1680
1681	req = (MPI2_SMP_PASSTHROUGH_REQUEST *)cm->cm_req;
1682	bzero(req, sizeof(*req));
1683	req->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
1684
1685	/* Allow the chip to use any route to this SAS address. */
1686	req->PhysicalPort = 0xff;
1687
1688	req->RequestDataLength = ccb->smpio.smp_request_len;
1689	req->SGLFlags =
1690	    MPI2_SGLFLAGS_SYSTEM_ADDRESS_SPACE | MPI2_SGLFLAGS_SGL_TYPE_MPI;
1691
1692	mps_dprint(sc, MPS_INFO, "%s: sending SMP request to SAS "
1693		   "address %#jx\n", __func__, (uintmax_t)sasaddr);
1694
1695	mpi_init_sge(cm, req, &req->SGL);
1696
1697	/*
1698	 * Set up a uio to pass into mps_map_command().  This allows us to
1699	 * do one map command, and one busdma call in there.
1700	 */
1701	cm->cm_uio.uio_iov = cm->cm_iovec;
1702	cm->cm_uio.uio_iovcnt = 2;
1703	cm->cm_uio.uio_segflg = UIO_SYSSPACE;
1704
1705	/*
1706	 * The read/write flag isn't used by busdma, but set it just in
1707	 * case.  This isn't exactly accurate, either, since we're going in
1708	 * both directions.
1709	 */
1710	cm->cm_uio.uio_rw = UIO_WRITE;
1711
1712	cm->cm_iovec[0].iov_base = request;
1713	cm->cm_iovec[0].iov_len = req->RequestDataLength;
1714	cm->cm_iovec[1].iov_base = response;
1715	cm->cm_iovec[1].iov_len = ccb->smpio.smp_response_len;
1716
1717	cm->cm_uio.uio_resid = cm->cm_iovec[0].iov_len +
1718			       cm->cm_iovec[1].iov_len;
1719
1720	/*
1721	 * Trigger a warning message in mps_data_cb() for the user if we
1722	 * wind up exceeding two S/G segments.  The chip expects one
1723	 * segment for the request and another for the response.
1724	 */
1725	cm->cm_max_segs = 2;
1726
1727	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1728	cm->cm_complete = mpssas_smpio_complete;
1729	cm->cm_complete_data = ccb;
1730
1731	/*
1732	 * Tell the mapping code that we're using a uio, and that this is
1733	 * an SMP passthrough request.  There is a little special-case
1734	 * logic there (in mps_data_cb()) to handle the bidirectional
1735	 * transfer.
1736	 */
1737	cm->cm_flags |= MPS_CM_FLAGS_USE_UIO | MPS_CM_FLAGS_SMP_PASS |
1738			MPS_CM_FLAGS_DATAIN | MPS_CM_FLAGS_DATAOUT;
1739
1740	/* The chip data format is little endian. */
1741	req->SASAddress.High = htole32(sasaddr >> 32);
1742	req->SASAddress.Low = htole32(sasaddr);
1743
1744	/*
1745	 * XXX Note that we don't have a timeout/abort mechanism here.
1746	 * From the manual, it looks like task management requests only
1747	 * work for SCSI IO and SATA passthrough requests.  We may need to
1748	 * have a mechanism to retry requests in the event of a chip reset
1749	 * at least.  Hopefully the chip will insure that any errors short
1750	 * of that are relayed back to the driver.
1751	 */
1752	error = mps_map_command(sc, cm);
1753	if ((error != 0) && (error != EINPROGRESS)) {
1754		mps_printf(sc, "%s: error %d returned from mps_map_command()\n",
1755			   __func__, error);
1756		goto bailout_error;
1757	}
1758
1759	return;
1760
1761bailout_error:
1762	mps_free_command(sc, cm);
1763	ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1764	xpt_done(ccb);
1765	return;
1766
1767}
1768
1769static void
1770mpssas_action_smpio(struct mpssas_softc *sassc, union ccb *ccb)
1771{
1772	struct mps_softc *sc;
1773	struct mpssas_target *targ;
1774	uint64_t sasaddr = 0;
1775
1776	sc = sassc->sc;
1777
1778	/*
1779	 * Make sure the target exists.
1780	 */
1781	targ = &sassc->targets[ccb->ccb_h.target_id];
1782	if (targ->handle == 0x0) {
1783		mps_printf(sc, "%s: target %d does not exist!\n", __func__,
1784			   ccb->ccb_h.target_id);
1785		ccb->ccb_h.status = CAM_SEL_TIMEOUT;
1786		xpt_done(ccb);
1787		return;
1788	}
1789
1790	/*
1791	 * If this device has an embedded SMP target, we'll talk to it
1792	 * directly.
1793	 * figure out what the expander's address is.
1794	 */
1795	if ((targ->devinfo & MPI2_SAS_DEVICE_INFO_SMP_TARGET) != 0)
1796		sasaddr = targ->sasaddr;
1797
1798	/*
1799	 * If we don't have a SAS address for the expander yet, try
1800	 * grabbing it from the page 0x83 information cached in the
1801	 * transport layer for this target.  LSI expanders report the
1802	 * expander SAS address as the port-associated SAS address in
1803	 * Inquiry VPD page 0x83.  Maxim expanders don't report it in page
1804	 * 0x83.
1805	 *
1806	 * XXX KDM disable this for now, but leave it commented out so that
1807	 * it is obvious that this is another possible way to get the SAS
1808	 * address.
1809	 *
1810	 * The parent handle method below is a little more reliable, and
1811	 * the other benefit is that it works for devices other than SES
1812	 * devices.  So you can send a SMP request to a da(4) device and it
1813	 * will get routed to the expander that device is attached to.
1814	 * (Assuming the da(4) device doesn't contain an SMP target...)
1815	 */
1816#if 0
1817	if (sasaddr == 0)
1818		sasaddr = xpt_path_sas_addr(ccb->ccb_h.path);
1819#endif
1820
1821	/*
1822	 * If we still don't have a SAS address for the expander, look for
1823	 * the parent device of this device, which is probably the expander.
1824	 */
1825	if (sasaddr == 0) {
1826		struct mpssas_target *parent_target;
1827
1828		if (targ->parent_handle == 0x0) {
1829			mps_printf(sc, "%s: handle %d does not have a valid "
1830				   "parent handle!\n", __func__, targ->handle);
1831			ccb->ccb_h.status = CAM_REQ_INVALID;
1832			goto bailout;
1833		}
1834		parent_target = mpssas_find_target(sassc, 0,
1835						   targ->parent_handle);
1836
1837		if (parent_target == NULL) {
1838			mps_printf(sc, "%s: handle %d does not have a valid "
1839				   "parent target!\n", __func__, targ->handle);
1840			ccb->ccb_h.status = CAM_REQ_INVALID;
1841			goto bailout;
1842		}
1843
1844		if ((parent_target->devinfo &
1845		     MPI2_SAS_DEVICE_INFO_SMP_TARGET) == 0) {
1846			mps_printf(sc, "%s: handle %d parent %d does not "
1847				   "have an SMP target!\n", __func__,
1848				   targ->handle, parent_target->handle);
1849			ccb->ccb_h.status = CAM_REQ_INVALID;
1850			goto bailout;
1851
1852		}
1853
1854		sasaddr = parent_target->sasaddr;
1855	}
1856
1857	if (sasaddr == 0) {
1858		mps_printf(sc, "%s: unable to find SAS address for handle %d\n",
1859			   __func__, targ->handle);
1860		ccb->ccb_h.status = CAM_REQ_INVALID;
1861		goto bailout;
1862	}
1863	mpssas_send_smpcmd(sassc, ccb, sasaddr);
1864
1865	return;
1866
1867bailout:
1868	xpt_done(ccb);
1869
1870}
1871
1872#endif /* __FreeBSD_version >= 900026 */
1873
1874static void
1875mpssas_action_resetdev(struct mpssas_softc *sassc, union ccb *ccb)
1876{
1877	struct mps_softc *sc;
1878	struct mps_command *cm;
1879	struct mpssas_target *targ;
1880
1881	sc = sassc->sc;
1882	targ = &sassc->targets[ccb->ccb_h.target_id];
1883
1884	if (targ->flags & MPSSAS_TARGET_INRECOVERY) {
1885		ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1886		xpt_done(ccb);
1887		return;
1888	}
1889
1890	cm = mps_alloc_command(sc);
1891	if (cm == NULL) {
1892		mps_printf(sc, "%s: cannot alloc command\n", __func__);
1893		ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1894		xpt_done(ccb);
1895		return;
1896	}
1897
1898	cm->cm_targ = targ;
1899	cm->cm_complete = mpssas_resetdev_complete;
1900	cm->cm_complete_data = ccb;
1901
1902	mpssas_resetdev(sassc, cm);
1903}
1904
1905static void
1906mpssas_resetdev(struct mpssas_softc *sassc, struct mps_command *cm)
1907{
1908	MPI2_SCSI_TASK_MANAGE_REQUEST *req;
1909	struct mps_softc *sc;
1910
1911	mps_dprint(sassc->sc, MPS_TRACE, "%s\n", __func__);
1912
1913	sc = sassc->sc;
1914
1915	req = (MPI2_SCSI_TASK_MANAGE_REQUEST *)cm->cm_req;
1916	req->DevHandle = cm->cm_targ->handle;
1917	req->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
1918	req->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
1919
1920	/* SAS Hard Link Reset / SATA Link Reset */
1921	req->MsgFlags = MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET;
1922
1923	cm->cm_data = NULL;
1924	cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1925
1926	mpssas_issue_tm_request(sc, cm);
1927}
1928
1929static void
1930mpssas_resetdev_complete(struct mps_softc *sc, struct mps_command *cm)
1931{
1932	MPI2_SCSI_TASK_MANAGE_REPLY *resp;
1933	union ccb *ccb;
1934
1935	mps_dprint(sc, MPS_TRACE, "%s\n", __func__);
1936
1937	resp = (MPI2_SCSI_TASK_MANAGE_REPLY *)cm->cm_reply;
1938	ccb = cm->cm_complete_data;
1939
1940	printf("resetdev complete IOCStatus= 0x%x ResponseCode= 0x%x\n",
1941	    resp->IOCStatus, resp->ResponseCode);
1942
1943	if (resp->ResponseCode == MPI2_SCSITASKMGMT_RSP_TM_COMPLETE)
1944		ccb->ccb_h.status = CAM_REQ_CMP;
1945	else
1946		ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1947
1948	mpssas_complete_tm_request(sc, cm, /*free_cm*/ 1);
1949
1950	xpt_done(ccb);
1951}
1952
1953static void
1954mpssas_poll(struct cam_sim *sim)
1955{
1956	struct mpssas_softc *sassc;
1957
1958	sassc = cam_sim_softc(sim);
1959	mps_intr_locked(sassc->sc);
1960}
1961
1962static void
1963mpssas_freeze_device(struct mpssas_softc *sassc, struct mpssas_target *targ)
1964{
1965}
1966
1967static void
1968mpssas_unfreeze_device(struct mpssas_softc *sassc, struct mpssas_target *targ)
1969{
1970}
1971
1972