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