1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2023 Racktop Systems, Inc.
14  */
15 
16 /*
17  * This file implements the basic HBA interface to SCSAv3.
18  *
19  * For target initialization, we'll look up the driver target state by the
20  * device address and set it as HBA private in the struct scsi_device.
21  *
22  * The tran_reset(9e) and tran_abort(9e) entry points are implemented by a
23  * common function that sends the appropriate task management request to the
24  * target, iff the target supports task management requests. There is no support
25  * for bus resets. The case of RESET_ALL is special: sd(4d) issues a RESET_ALL
26  * in sddump() and errors out if that fails, so even if task management is
27  * unsupported by a target or the reset fails for any other reason, we return
28  * success. Any I/O errors due to an unsuccessful reset will be caught later.
29  *
30  * The tran_start(9e) code paths are almost identical for physical and logical
31  * devices, the major difference being that PDs will have the DevHandle in the
32  * MPT I/O frame set to the invalid DevHandle (0xffff), while LDs will use the
33  * target ID. Also, special settings are applied for LDs and PDs in the RAID
34  * context (VendorRegion of the MPT I/O frame). There is no support for fastpath
35  * I/O.
36  *
37  * In tran_setup_pkt(9e), a MPT command is allocated for the scsi_pkt, and its
38  * members are initialized as follows:
39  * - pkt_cdbp will point to the CDB structure embedded in the MPT I/O frame
40  * - pkt_scbp will point to the struct scsi_arq_status in the sense DMA memory
41  *   allocated for the MPT command
42  * - pkt_scblen will be set to the size of the sense DMA memory, minus alignment
43  * - SenseBufferLowAddress and SenseBufferLength in the MPT I/O frame will be
44  *   set to the sense DMA address and length, respectively, adjusted to account
45  *   for the space needed for the ARQ pkt and alignment.
46  * - There is no SenseBufferHighAddress.
47  * - rc_timeout is set to pkt_time, but it is unknown if that has any effect
48  */
49 
50 #include <sys/types.h>
51 #include <sys/ddi.h>
52 #include <sys/sunddi.h>
53 #include <sys/scsi/scsi.h>
54 
55 #include "lmrc.h"
56 #include "lmrc_reg.h"
57 
58 static int lmrc_getcap(struct scsi_address *, char *, int);
59 static int lmrc_setcap(struct scsi_address *, char *, int, int);
60 
61 static int lmrc_tran_tgt_init(dev_info_t *, dev_info_t *,
62     scsi_hba_tran_t *, struct scsi_device *);
63 static void lmrc_tran_tgt_free(dev_info_t *, dev_info_t *,
64     scsi_hba_tran_t *, struct scsi_device *);
65 
66 static int lmrc_tran_abort(struct scsi_address *, struct scsi_pkt *);
67 static int lmrc_tran_reset(struct scsi_address *, int);
68 
69 static int lmrc_tran_setup_pkt(struct scsi_pkt *, int (*)(caddr_t), caddr_t);
70 static void lmrc_tran_teardown_pkt(struct scsi_pkt *);
71 
72 boolean_t lmrc_relaxed_ordering = B_TRUE;
73 
74 static int
75 lmrc_getcap(struct scsi_address *sa, char *cap, int whom)
76 {
77 	struct scsi_device *sd = scsi_address_device(sa);
78 	lmrc_tgt_t *tgt = scsi_device_hba_private_get(sd);
79 	lmrc_t *lmrc = tgt->tgt_lmrc;
80 	int index;
81 
82 	VERIFY(lmrc != NULL);
83 
84 	if ((index = scsi_hba_lookup_capstr(cap)) == DDI_FAILURE)
85 		return (-1);
86 
87 	switch (index) {
88 	case SCSI_CAP_CDB_LEN:
89 		return (sizeof (((Mpi25SCSIIORequest_t *)NULL)->CDB.CDB32));
90 
91 	case SCSI_CAP_DMA_MAX:
92 		if (lmrc->l_dma_attr.dma_attr_maxxfer > INT_MAX)
93 			return (INT_MAX);
94 		return (lmrc->l_dma_attr.dma_attr_maxxfer);
95 
96 	case SCSI_CAP_SECTOR_SIZE:
97 		if (lmrc->l_dma_attr.dma_attr_granular > INT_MAX)
98 			return (INT_MAX);
99 		return (lmrc->l_dma_attr.dma_attr_granular);
100 
101 	case SCSI_CAP_INTERCONNECT_TYPE: {
102 		uint8_t interconnect_type;
103 
104 		rw_enter(&tgt->tgt_lock, RW_READER);
105 		interconnect_type = tgt->tgt_interconnect_type;
106 		rw_exit(&tgt->tgt_lock);
107 		return (interconnect_type);
108 	}
109 	case SCSI_CAP_MSG_OUT:
110 	case SCSI_CAP_WIDE_XFER:
111 	case SCSI_CAP_TAGGED_QING:
112 	case SCSI_CAP_UNTAGGED_QING:
113 	case SCSI_CAP_PARITY:
114 	case SCSI_CAP_ARQ:
115 		return (1);
116 
117 	case SCSI_CAP_RESET_NOTIFICATION:
118 	case SCSI_CAP_DISCONNECT:
119 	case SCSI_CAP_SYNCHRONOUS:
120 	case SCSI_CAP_LINKED_CMDS:
121 	case SCSI_CAP_INITIATOR_ID:
122 		return (0);
123 
124 	default:
125 		return (-1);
126 	}
127 }
128 
129 static int
130 lmrc_setcap(struct scsi_address *sa, char *cap, int value, int whom)
131 {
132 	struct scsi_device *sd = scsi_address_device(sa);
133 	lmrc_tgt_t *tgt = scsi_device_hba_private_get(sd);
134 	lmrc_t *lmrc = tgt->tgt_lmrc;
135 	int index;
136 
137 	VERIFY(lmrc != NULL);
138 
139 	if ((index = scsi_hba_lookup_capstr(cap)) == DDI_FAILURE)
140 		return (-1);
141 
142 	if (whom == 0)
143 		return (-1);
144 
145 	switch (index) {
146 	case SCSI_CAP_DMA_MAX:
147 		if (value <= lmrc->l_dma_attr.dma_attr_maxxfer)
148 			return (1);
149 		else
150 			return (0);
151 
152 	case SCSI_CAP_MSG_OUT:
153 	case SCSI_CAP_WIDE_XFER:
154 	case SCSI_CAP_TAGGED_QING:
155 	case SCSI_CAP_UNTAGGED_QING:
156 	case SCSI_CAP_PARITY:
157 	case SCSI_CAP_ARQ:
158 		if (value == 1)
159 			return (1);
160 		else
161 			return (0);
162 
163 	case SCSI_CAP_RESET_NOTIFICATION:
164 	case SCSI_CAP_DISCONNECT:
165 	case SCSI_CAP_SYNCHRONOUS:
166 	case SCSI_CAP_LINKED_CMDS:
167 	case SCSI_CAP_INITIATOR_ID:
168 		if (value == 0)
169 			return (1);
170 		else
171 			return (0);
172 
173 	case SCSI_CAP_SECTOR_SIZE:
174 	case SCSI_CAP_TOTAL_SECTORS:
175 		return (0);
176 
177 	default:
178 		return (-1);
179 	}
180 }
181 
182 /*
183  * lmrc_tran_tgt_init
184  *
185  * Find the driver target state and link it with the scsi_device.
186  */
187 static int
188 lmrc_tran_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
189     scsi_hba_tran_t *hba_tran, struct scsi_device *sd)
190 {
191 	lmrc_t *lmrc = hba_tran->tran_hba_private;
192 	lmrc_tgt_t *tgt;
193 
194 	VERIFY(lmrc != NULL);
195 
196 	tgt = lmrc_tgt_find(lmrc, sd);
197 	if (tgt == NULL)
198 		return (DDI_FAILURE);
199 
200 	/* lmrc_tgt_find() returns the target read-locked. */
201 	scsi_device_hba_private_set(sd, tgt);
202 	rw_exit(&tgt->tgt_lock);
203 
204 
205 	return (DDI_SUCCESS);
206 }
207 
208 static void
209 lmrc_tran_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip,
210     scsi_hba_tran_t *hba_tran, struct scsi_device *sd)
211 {
212 	scsi_device_hba_private_set(sd, NULL);
213 }
214 
215 /*
216  * lmrc_tran_start
217  *
218  * Start I/O of a scsi_pkt. Set up the MPT frame, the RAID context and if
219  * necessary the SGL for the transfer. Wait for a reply if this is polled I/O.
220  *
221  * There are subtle differences in the way I/O is done for LDs and PDs.
222  *
223  * There is no support for fastpath I/O.
224  */
225 static int
226 lmrc_tran_start(struct scsi_address *sa, struct scsi_pkt *pkt)
227 {
228 	Mpi25SCSIIORequest_t *io_req;
229 	lmrc_atomic_req_desc_t req_desc;
230 	lmrc_raidctx_g35_t *rc;
231 	struct scsi_device *sd;
232 	lmrc_scsa_cmd_t *cmd;
233 	lmrc_mpt_cmd_t *mpt;
234 	lmrc_tgt_t *tgt;
235 	lmrc_t *lmrc;
236 	uint8_t req_flags = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
237 	boolean_t intr = (pkt->pkt_flags & FLAG_NOINTR) == 0;
238 	int ret = TRAN_BADPKT;
239 
240 	/*
241 	 * FLAG_NOINTR was set but we're not panicked. This may theoretically
242 	 * happen if scsi_transport() is called from an interrupt thread, and
243 	 * we don't support this.
244 	 */
245 	if (!intr && !ddi_in_panic())
246 		return (ret);
247 
248 	sd = scsi_address_device(sa);
249 	VERIFY(sd != NULL);
250 
251 	tgt = scsi_device_hba_private_get(sd);
252 	VERIFY(tgt != NULL);
253 
254 	cmd = pkt->pkt_ha_private;
255 	VERIFY(cmd != NULL);
256 
257 	VERIFY(cmd->sc_tgt == tgt);
258 
259 	lmrc = tgt->tgt_lmrc;
260 	VERIFY(lmrc != NULL);
261 
262 	if (lmrc->l_fw_fault)
263 		return (TRAN_FATAL_ERROR);
264 
265 	if (atomic_inc_uint_nv(&lmrc->l_fw_outstanding_cmds) >
266 	    lmrc->l_max_scsi_cmds) {
267 		atomic_dec_uint(&lmrc->l_fw_outstanding_cmds);
268 		return (TRAN_BUSY);
269 	}
270 
271 	rw_enter(&tgt->tgt_lock, RW_READER);
272 
273 	mpt = cmd->sc_mpt;
274 	VERIFY(mpt != NULL);
275 	mutex_enter(&mpt->mpt_lock);
276 
277 	io_req = mpt->mpt_io_frame;
278 
279 	io_req->Function = LMRC_MPI2_FUNCTION_LD_IO_REQUEST;
280 
281 	rc = &io_req->VendorRegion;
282 	rc->rc_ld_tgtid = tgt->tgt_dev_id;
283 
284 	rw_enter(&lmrc->l_raidmap_lock, RW_READER);
285 	rc->rc_timeout = lmrc->l_raidmap->rm_fp_pd_io_timeout;
286 	rw_exit(&lmrc->l_raidmap_lock);
287 
288 	if (tgt->tgt_pd_info == NULL) {
289 		/* This is LD I/O */
290 		io_req->DevHandle = tgt->tgt_dev_id;
291 
292 		if (lmrc_cmd_is_rw(pkt->pkt_cdbp[0])) {
293 			rc->rc_type = MPI2_TYPE_CUDA;
294 			rc->rc_nseg = 1;
295 			rc->rc_routing_flags.rf_sqn = 1;
296 		}
297 	} else {
298 		/* This is PD I/O */
299 		io_req->DevHandle = LMRC_DEVHDL_INVALID;
300 		rc->rc_raid_flags.rf_io_subtype = LMRC_RF_IO_SUBTYPE_SYSTEM_PD;
301 
302 		if (tgt->tgt_type == DTYPE_DIRECT &&
303 		    lmrc->l_use_seqnum_jbod_fp) {
304 			lmrc_pd_cfg_t *pdcfg;
305 
306 			rw_enter(&lmrc->l_pdmap_lock, RW_READER);
307 			pdcfg = &lmrc->l_pdmap->pm_pdcfg[tgt->tgt_dev_id];
308 
309 			if (lmrc->l_pdmap_tgtid_support)
310 				rc->rc_ld_tgtid = pdcfg->pd_tgtid;
311 
312 			rc->rc_cfg_seqnum = pdcfg->pd_seqnum;
313 			io_req->DevHandle = pdcfg->pd_devhdl;
314 			rw_exit(&lmrc->l_pdmap_lock);
315 
316 			if (lmrc_cmd_is_rw(pkt->pkt_cdbp[0])) {
317 				/*
318 				 * MPI2_TYPE_CUDA is valid only if FW supports
319 				 * JBOD Sequence number
320 				 */
321 				rc->rc_type = MPI2_TYPE_CUDA;
322 				rc->rc_nseg = 1;
323 				rc->rc_routing_flags.rf_sqn = 1;
324 
325 				io_req->Function =
326 				    MPI2_FUNCTION_SCSI_IO_REQUEST;
327 				io_req->IoFlags |=
328 				    MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH;
329 				req_flags =
330 				    MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO;
331 			}
332 		}
333 
334 	}
335 
336 	if (pkt->pkt_numcookies > 0) {
337 		if ((pkt->pkt_dma_flags & DDI_DMA_READ) != 0)
338 			io_req->Control |= MPI2_SCSIIO_CONTROL_READ;
339 
340 		if ((pkt->pkt_dma_flags & DDI_DMA_WRITE) != 0)
341 			io_req->Control |= MPI2_SCSIIO_CONTROL_WRITE;
342 
343 		lmrc_dma_build_sgl(lmrc, mpt, pkt->pkt_cookies,
344 		    pkt->pkt_numcookies);
345 
346 		io_req->DataLength = pkt->pkt_dma_len;
347 
348 		rc->rc_num_sge = pkt->pkt_numcookies;
349 	}
350 
351 	VERIFY3S(ddi_dma_sync(lmrc->l_ioreq_dma.ld_hdl,
352 	    (void *)io_req - lmrc->l_ioreq_dma.ld_buf,
353 	    LMRC_MPI2_RAID_DEFAULT_IO_FRAME_SIZE, DDI_DMA_SYNC_FORDEV),
354 	    ==, DDI_SUCCESS);
355 
356 	req_desc = lmrc_build_atomic_request(lmrc, mpt, req_flags);
357 
358 	mpt->mpt_timeout = gethrtime() + pkt->pkt_time * NANOSEC;
359 	lmrc_send_atomic_request(lmrc, req_desc);
360 
361 	if (intr) {
362 		/* normal interrupt driven I/O processing */
363 		lmrc_tgt_add_active_mpt(tgt, mpt);
364 		ret = TRAN_ACCEPT;
365 	} else {
366 		/* FLAG_NOINTR was set and we're panicked */
367 		VERIFY(ddi_in_panic());
368 
369 		ret = lmrc_poll_for_reply(lmrc, mpt);
370 		atomic_dec_uint(&lmrc->l_fw_outstanding_cmds);
371 	}
372 
373 	mutex_exit(&mpt->mpt_lock);
374 	rw_exit(&tgt->tgt_lock);
375 
376 	return (ret);
377 }
378 
379 /*
380  * lmrc_task_mgmt
381  *
382  * Send a TASK MGMT command to a target, provied it is TM capable.
383  */
384 static int
385 lmrc_task_mgmt(lmrc_t *lmrc, lmrc_tgt_t *tgt, uint8_t type, uint16_t smid)
386 {
387 	Mpi2SCSITaskManagementRequest_t *tm_req;
388 	Mpi2SCSITaskManagementReply_t *tm_reply;
389 	uint64_t *pd_ld_flags;
390 	lmrc_atomic_req_desc_t req_desc;
391 	lmrc_mpt_cmd_t *mpt;
392 	clock_t ret;
393 	boolean_t tm_capable;
394 
395 	rw_enter(&tgt->tgt_lock, RW_READER);
396 
397 	/* Make sure the target can handle task mgmt commands. */
398 	if (tgt->tgt_pd_info == NULL) {
399 		tm_capable = lmrc_ld_tm_capable(lmrc, tgt->tgt_dev_id);
400 	} else {
401 		tm_capable = lmrc_pd_tm_capable(lmrc, tgt->tgt_dev_id);
402 	}
403 
404 	if (!tm_capable) {
405 		rw_exit(&tgt->tgt_lock);
406 		return (0);
407 	}
408 
409 	if (atomic_inc_uint_nv(&lmrc->l_fw_outstanding_cmds) >
410 	    lmrc->l_max_scsi_cmds) {
411 		rw_exit(&tgt->tgt_lock);
412 		atomic_dec_uint(&lmrc->l_fw_outstanding_cmds);
413 		return (0);
414 	}
415 
416 	mpt = lmrc_get_mpt(lmrc);
417 	if (mpt == NULL) {
418 		rw_exit(&tgt->tgt_lock);
419 		atomic_dec_uint(&lmrc->l_fw_outstanding_cmds);
420 		return (0);
421 	}
422 	ASSERT(mutex_owned(&mpt->mpt_lock));
423 
424 
425 	bzero(mpt->mpt_io_frame, LMRC_MPI2_RAID_DEFAULT_IO_FRAME_SIZE);
426 	tm_req = mpt->mpt_io_frame;
427 	tm_reply = mpt->mpt_io_frame + 128;
428 	pd_ld_flags = (uint64_t *)tm_reply;
429 
430 
431 	tm_req->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
432 	tm_req->TaskType = type;
433 	tm_req->TaskMID = smid;
434 	tm_req->DevHandle = tgt->tgt_dev_id;
435 
436 	/*
437 	 * The uint32_t immediately following the MPI2 task management request
438 	 * contains two flags indicating whether the target is a LD or PD.
439 	 */
440 	if (tgt->tgt_pd_info == NULL)
441 		*pd_ld_flags = 1<<0;
442 	else
443 		*pd_ld_flags = 1<<1;
444 
445 	VERIFY3S(ddi_dma_sync(lmrc->l_ioreq_dma.ld_hdl,
446 	    (void *)tm_req - lmrc->l_ioreq_dma.ld_buf,
447 	    LMRC_MPI2_RAID_DEFAULT_IO_FRAME_SIZE, DDI_DMA_SYNC_FORDEV),
448 	    ==, DDI_SUCCESS);
449 
450 	req_desc = lmrc_build_atomic_request(lmrc, mpt,
451 	    MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY);
452 
453 	lmrc_send_atomic_request(lmrc, req_desc);
454 
455 	/* Poll for completion if we're called while the system is panicked. */
456 	if (ddi_in_panic()) {
457 		ret = lmrc_poll_for_reply(lmrc, mpt);
458 	} else {
459 		clock_t timeout = drv_usectohz(LMRC_RESET_WAIT_TIME * MICROSEC);
460 
461 		timeout += ddi_get_lbolt();
462 		do {
463 			ret = cv_timedwait(&mpt->mpt_cv, &mpt->mpt_lock,
464 			    timeout);
465 		} while (mpt->mpt_complete == B_FALSE && ret != -1);
466 	}
467 
468 	atomic_dec_uint(&lmrc->l_fw_outstanding_cmds);
469 	lmrc_put_mpt(mpt);
470 	rw_exit(&tgt->tgt_lock);
471 
472 	if (ret >= 0)
473 		return (1);
474 	else
475 		return (-1);
476 }
477 
478 /*
479  * lmrc_abort_mpt
480  *
481  * Abort a MPT command by sending a TASK MGMT ABORT TASK command.
482  */
483 int
484 lmrc_abort_mpt(lmrc_t *lmrc, lmrc_tgt_t *tgt, lmrc_mpt_cmd_t *mpt)
485 {
486 	ASSERT(mutex_owned(&tgt->tgt_mpt_active_lock));
487 	ASSERT(mutex_owned(&mpt->mpt_lock));
488 
489 	return (lmrc_task_mgmt(lmrc, tgt, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
490 	    mpt->mpt_smid));
491 }
492 
493 /*
494  * lmrc_tran_abort
495  *
496  * Send a SCSI TASK MGMT request to abort a packet.
497  */
498 static int
499 lmrc_tran_abort(struct scsi_address *sa, struct scsi_pkt *pkt)
500 {
501 	struct scsi_device *sd = scsi_address_device(sa);
502 	lmrc_tgt_t *tgt = scsi_device_hba_private_get(sd);
503 	lmrc_t *lmrc = tgt->tgt_lmrc;
504 	lmrc_scsa_cmd_t *cmd;
505 	lmrc_mpt_cmd_t *mpt;
506 	int ret = 0;
507 
508 	VERIFY(lmrc != NULL);
509 
510 	if (lmrc->l_fw_fault)
511 		return (0);
512 
513 	/*
514 	 * If no pkt was given, abort all outstanding pkts for this target.
515 	 */
516 	if (pkt == NULL) {
517 		mutex_enter(&tgt->tgt_mpt_active_lock);
518 		for (mpt = lmrc_tgt_first_active_mpt(tgt);
519 		    mpt != NULL;
520 		    mpt = lmrc_tgt_next_active_mpt(tgt, mpt)) {
521 			ASSERT(mutex_owned(&mpt->mpt_lock));
522 			if (mpt->mpt_complete)
523 				continue;
524 			if (mpt->mpt_pkt == NULL)
525 				continue;
526 
527 			if (lmrc_abort_mpt(lmrc, tgt, mpt) > 0)
528 				ret = 1;
529 		}
530 		mutex_exit(&tgt->tgt_mpt_active_lock);
531 
532 		return (ret);
533 	}
534 
535 	cmd = pkt->pkt_ha_private;
536 
537 	VERIFY(cmd != NULL);
538 	VERIFY(cmd->sc_tgt == tgt);
539 
540 	mpt = cmd->sc_mpt;
541 	VERIFY(mpt != NULL);
542 
543 	mutex_enter(&mpt->mpt_lock);
544 	ret = lmrc_abort_mpt(lmrc, tgt, mpt);
545 	mutex_exit(&mpt->mpt_lock);
546 
547 	if (ret == -1) {
548 		dev_err(lmrc->l_dip, CE_WARN, "!target reset timed out, "
549 		    "tgt %d", tgt->tgt_dev_id);
550 		return (0);
551 	}
552 
553 	return (ret);
554 }
555 
556 /*
557  * lmrc_tran_reset
558  *
559  * Reset a target. There's no support for RESET_LUN or RESET_ALL.
560  */
561 static int
562 lmrc_tran_reset(struct scsi_address *sa, int level)
563 {
564 	struct scsi_device *sd = scsi_address_device(sa);
565 	lmrc_tgt_t *tgt = scsi_device_hba_private_get(sd);
566 	lmrc_t *lmrc = tgt->tgt_lmrc;
567 	int ret = 0;
568 
569 	VERIFY(lmrc != NULL);
570 
571 	if (lmrc->l_fw_fault)
572 		return (0);
573 
574 	switch (level) {
575 	case RESET_ALL:
576 	case RESET_LUN:
577 	case RESET_TARGET:
578 		rw_enter(&tgt->tgt_lock, RW_READER);
579 		ret = lmrc_task_mgmt(lmrc, tgt,
580 		    MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0);
581 		rw_exit(&tgt->tgt_lock);
582 
583 		if (ret == -1) {
584 			dev_err(lmrc->l_dip, CE_WARN,
585 			    "!target reset timed out, tgt %d",
586 			    tgt->tgt_dev_id);
587 			return (0);
588 		}
589 
590 		break;
591 	}
592 
593 	/*
594 	 * Fake a successful return in the case of RESET_ALL for the benefit of
595 	 * being able to save kernel core dumps. sddump() wants to reset the
596 	 * device and errors out if that fails, even if that happens not because
597 	 * of an error but because of a reset not being supported.
598 	 */
599 	if (ret == 0 && level == RESET_ALL)
600 		ret = 1;
601 
602 	return (ret);
603 }
604 
605 /*
606  * lmrc_tran_setup_pkt
607  *
608  * Set up a MPT command for a scsi_pkt, and initialize scsi_pkt members as
609  * needed:
610  * - pkt_cdbp will point to the CDB structure embedded in the MPT I/O frame
611  * - pkt_scbp will point to the struct scsi_arq_status in the sense DMA memory
612  *   allocated for the MPT command
613  * - pkt_scblen will be set to the size of the sense DMA memory, minus alignment
614  * - SenseBufferLowAddress and SenseBufferLength in the MPT I/O frame will be
615  *   set to the sense DMA address and length, respectively, adjusted to account
616  *   for the space needed for the ARQ pkt and alignment.
617  * - There is no SenseBufferHighAddress.
618  * - rc_timeout is set to pkt_time, but it is unknown if that has any effect
619  *
620  * The procedure is the same irrespective of whether the command is sent to a
621  * physical device or RAID volume.
622  */
623 static int
624 lmrc_tran_setup_pkt(struct scsi_pkt *pkt, int (*callback)(caddr_t),
625     caddr_t arg)
626 {
627 	struct scsi_address *sa;
628 	struct scsi_device *sd;
629 	lmrc_tgt_t *tgt;
630 	lmrc_t *lmrc;
631 	lmrc_scsa_cmd_t *cmd;
632 	lmrc_mpt_cmd_t *mpt;
633 	Mpi25SCSIIORequest_t *io_req;
634 	lmrc_raidctx_g35_t *rc;
635 
636 	if (pkt->pkt_cdblen > sizeof (io_req->CDB.CDB32))
637 		return (-1);
638 
639 	sa = &pkt->pkt_address;
640 	VERIFY(sa != NULL);
641 
642 	sd = scsi_address_device(sa);
643 	VERIFY(sd != NULL);
644 
645 	tgt = scsi_device_hba_private_get(sd);
646 	VERIFY(tgt != NULL);
647 
648 	rw_enter(&tgt->tgt_lock, RW_READER);
649 
650 	lmrc = tgt->tgt_lmrc;
651 	VERIFY(lmrc != NULL);
652 
653 	cmd = pkt->pkt_ha_private;
654 	ASSERT(cmd != NULL);
655 
656 	mpt = lmrc_get_mpt(lmrc);
657 	if (mpt == NULL) {
658 		rw_exit(&tgt->tgt_lock);
659 		return (-1);
660 	}
661 	ASSERT(mutex_owned(&mpt->mpt_lock));
662 
663 
664 	io_req = mpt->mpt_io_frame;
665 
666 	pkt->pkt_cdbp = io_req->CDB.CDB32;
667 
668 	/* Just the CDB length now, but other flags may be set later. */
669 	io_req->IoFlags = pkt->pkt_cdblen;
670 
671 	/*
672 	 * Set up sense buffer. The DMA memory was setup to holds the whole ARQ
673 	 * structure aligned so that its sts_sensedata is aligned to 64 bytes.
674 	 * Point SenseBufferLowAddress to sts_sensedata and reduce the length
675 	 * accordingly.
676 	 */
677 	pkt->pkt_scbp = mpt->mpt_sense;
678 	pkt->pkt_scblen = lmrc_dma_get_size(&mpt->mpt_sense_dma) - 64 +
679 	    offsetof(struct scsi_arq_status, sts_sensedata);
680 
681 	lmrc_dma_set_addr32(&mpt->mpt_sense_dma,
682 	    &io_req->SenseBufferLowAddress);
683 	io_req->SenseBufferLowAddress +=
684 	    P2ROUNDUP(offsetof(struct scsi_arq_status, sts_sensedata), 64);
685 	io_req->SenseBufferLength = pkt->pkt_scblen -
686 	    offsetof(struct scsi_arq_status, sts_sensedata);
687 
688 	rc = &io_req->VendorRegion;
689 	rc->rc_timeout = pkt->pkt_time;
690 
691 	cmd->sc_mpt = mpt;
692 	cmd->sc_tgt = tgt;
693 	mpt->mpt_pkt = pkt;
694 	mutex_exit(&mpt->mpt_lock);
695 	rw_exit(&tgt->tgt_lock);
696 
697 	return (0);
698 }
699 
700 /*
701  * lmrc_tran_teardown_pkt
702  *
703  * Return the MPT command to the free list. It'll be cleared later before
704  * it is reused.
705  */
706 static void
707 lmrc_tran_teardown_pkt(struct scsi_pkt *pkt)
708 {
709 	lmrc_scsa_cmd_t *cmd;
710 	lmrc_mpt_cmd_t *mpt;
711 
712 	cmd = pkt->pkt_ha_private;
713 	ASSERT(cmd != NULL);
714 
715 	mpt = cmd->sc_mpt;
716 	ASSERT(mpt != NULL);
717 
718 	mutex_enter(&mpt->mpt_lock);
719 	lmrc_put_mpt(mpt);
720 }
721 
722 /*
723  * lmrc_hba_attach
724  *
725  * Set up the HBA functions of lmrc. This is a SAS controller and uses complex
726  * addressing for targets, presenting physical devices (PDs) and RAID volumes
727  * (LD) as separate iports.
728  */
729 int
730 lmrc_hba_attach(lmrc_t *lmrc)
731 {
732 	scsi_hba_tran_t	*tran;
733 	ddi_dma_attr_t tran_attr = lmrc->l_dma_attr_32;
734 
735 	tran = scsi_hba_tran_alloc(lmrc->l_dip, SCSI_HBA_CANSLEEP);
736 	if (tran == NULL) {
737 		dev_err(lmrc->l_dip, CE_WARN, "!scsi_hba_tran_alloc failed");
738 		return (DDI_FAILURE);
739 	}
740 
741 	tran->tran_hba_private = lmrc;
742 
743 	tran->tran_tgt_init = lmrc_tran_tgt_init;
744 	tran->tran_tgt_free = lmrc_tran_tgt_free;
745 
746 	tran->tran_tgt_probe = scsi_hba_probe;
747 
748 	tran->tran_start = lmrc_tran_start;
749 	tran->tran_abort = lmrc_tran_abort;
750 	tran->tran_reset = lmrc_tran_reset;
751 
752 	tran->tran_getcap = lmrc_getcap;
753 	tran->tran_setcap = lmrc_setcap;
754 
755 	tran->tran_setup_pkt = lmrc_tran_setup_pkt;
756 	tran->tran_teardown_pkt = lmrc_tran_teardown_pkt;
757 	tran->tran_hba_len = sizeof (lmrc_scsa_cmd_t);
758 	tran->tran_interconnect_type = INTERCONNECT_SAS;
759 
760 	if (lmrc_relaxed_ordering)
761 		tran_attr.dma_attr_flags |= DDI_DMA_RELAXED_ORDERING;
762 	tran_attr.dma_attr_sgllen = lmrc->l_max_num_sge;
763 
764 	if (scsi_hba_attach_setup(lmrc->l_dip, &tran_attr, tran,
765 	    SCSI_HBA_HBA | SCSI_HBA_ADDR_COMPLEX) != DDI_SUCCESS)
766 		goto fail;
767 
768 	lmrc->l_hba_tran = tran;
769 
770 	if (scsi_hba_iport_register(lmrc->l_dip, LMRC_IPORT_RAID) !=
771 	    DDI_SUCCESS)
772 		goto fail;
773 
774 	if (scsi_hba_iport_register(lmrc->l_dip, LMRC_IPORT_PHYS) !=
775 	    DDI_SUCCESS)
776 		goto fail;
777 
778 	return (DDI_SUCCESS);
779 
780 fail:
781 	dev_err(lmrc->l_dip, CE_WARN,
782 	    "!could not attach to SCSA framework");
783 	lmrc_hba_detach(lmrc);
784 
785 	return (DDI_FAILURE);
786 }
787 
788 void
789 lmrc_hba_detach(lmrc_t *lmrc)
790 {
791 	if (lmrc->l_hba_tran == NULL)
792 		return;
793 
794 	(void) scsi_hba_detach(lmrc->l_dip);
795 	scsi_hba_tran_free(lmrc->l_hba_tran);
796 	lmrc->l_hba_tran = NULL;
797 }
798