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 		atomic_dec_uint(&lmrc->l_fw_outstanding_cmds);
412 		return (0);
413 	}
414 
415 	mpt = lmrc_get_mpt(lmrc);
416 	ASSERT(mutex_owned(&mpt->mpt_lock));
417 
418 	bzero(mpt->mpt_io_frame, LMRC_MPI2_RAID_DEFAULT_IO_FRAME_SIZE);
419 	tm_req = mpt->mpt_io_frame;
420 	tm_reply = mpt->mpt_io_frame + 128;
421 	pd_ld_flags = (uint64_t *)tm_reply;
422 
423 
424 	tm_req->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
425 	tm_req->TaskType = type;
426 	tm_req->TaskMID = smid;
427 	tm_req->DevHandle = tgt->tgt_dev_id;
428 
429 	/*
430 	 * The uint32_t immediately following the MPI2 task management request
431 	 * contains two flags indicating whether the target is a LD or PD.
432 	 */
433 	if (tgt->tgt_pd_info == NULL)
434 		*pd_ld_flags = 1<<0;
435 	else
436 		*pd_ld_flags = 1<<1;
437 
438 	VERIFY3S(ddi_dma_sync(lmrc->l_ioreq_dma.ld_hdl,
439 	    (void *)tm_req - lmrc->l_ioreq_dma.ld_buf,
440 	    LMRC_MPI2_RAID_DEFAULT_IO_FRAME_SIZE, DDI_DMA_SYNC_FORDEV),
441 	    ==, DDI_SUCCESS);
442 
443 	req_desc = lmrc_build_atomic_request(lmrc, mpt,
444 	    MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY);
445 
446 	lmrc_send_atomic_request(lmrc, req_desc);
447 
448 	/* Poll for completion if we're called while the system is panicked. */
449 	if (ddi_in_panic()) {
450 		ret = lmrc_poll_for_reply(lmrc, mpt);
451 	} else {
452 		clock_t timeout = drv_usectohz(LMRC_RESET_WAIT_TIME * MICROSEC);
453 
454 		timeout += ddi_get_lbolt();
455 		do {
456 			ret = cv_timedwait(&mpt->mpt_cv, &mpt->mpt_lock,
457 			    timeout);
458 		} while (mpt->mpt_complete == B_FALSE && ret != -1);
459 	}
460 
461 	atomic_dec_uint(&lmrc->l_fw_outstanding_cmds);
462 	lmrc_put_mpt(mpt);
463 	rw_exit(&tgt->tgt_lock);
464 
465 	if (ret >= 0)
466 		return (1);
467 	else
468 		return (-1);
469 }
470 
471 /*
472  * lmrc_abort_mpt
473  *
474  * Abort a MPT command by sending a TASK MGMT ABORT TASK command.
475  */
476 int
477 lmrc_abort_mpt(lmrc_t *lmrc, lmrc_tgt_t *tgt, lmrc_mpt_cmd_t *mpt)
478 {
479 	ASSERT(mutex_owned(&tgt->tgt_mpt_active_lock));
480 	ASSERT(mutex_owned(&mpt->mpt_lock));
481 
482 	return (lmrc_task_mgmt(lmrc, tgt, MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
483 	    mpt->mpt_smid));
484 }
485 
486 /*
487  * lmrc_tran_abort
488  *
489  * Send a SCSI TASK MGMT request to abort a packet.
490  */
491 static int
492 lmrc_tran_abort(struct scsi_address *sa, struct scsi_pkt *pkt)
493 {
494 	struct scsi_device *sd = scsi_address_device(sa);
495 	lmrc_tgt_t *tgt = scsi_device_hba_private_get(sd);
496 	lmrc_t *lmrc = tgt->tgt_lmrc;
497 	lmrc_scsa_cmd_t *cmd;
498 	lmrc_mpt_cmd_t *mpt;
499 	int ret = 0;
500 
501 	VERIFY(lmrc != NULL);
502 
503 	if (lmrc->l_fw_fault)
504 		return (0);
505 
506 	/*
507 	 * If no pkt was given, abort all outstanding pkts for this target.
508 	 */
509 	if (pkt == NULL) {
510 		mutex_enter(&tgt->tgt_mpt_active_lock);
511 		for (mpt = lmrc_tgt_first_active_mpt(tgt);
512 		    mpt != NULL;
513 		    mpt = lmrc_tgt_next_active_mpt(tgt, mpt)) {
514 			ASSERT(mutex_owned(&mpt->mpt_lock));
515 			if (mpt->mpt_complete)
516 				continue;
517 			if (mpt->mpt_pkt == NULL)
518 				continue;
519 
520 			if (lmrc_abort_mpt(lmrc, tgt, mpt) > 0)
521 				ret = 1;
522 		}
523 		mutex_exit(&tgt->tgt_mpt_active_lock);
524 
525 		return (ret);
526 	}
527 
528 	cmd = pkt->pkt_ha_private;
529 
530 	VERIFY(cmd != NULL);
531 	VERIFY(cmd->sc_tgt == tgt);
532 
533 	mpt = cmd->sc_mpt;
534 	VERIFY(mpt != NULL);
535 
536 	mutex_enter(&mpt->mpt_lock);
537 	ret = lmrc_abort_mpt(lmrc, tgt, mpt);
538 	mutex_exit(&mpt->mpt_lock);
539 
540 	if (ret == -1) {
541 		dev_err(lmrc->l_dip, CE_WARN, "!target reset timed out, "
542 		    "tgt %d", tgt->tgt_dev_id);
543 		return (0);
544 	}
545 
546 	return (ret);
547 }
548 
549 /*
550  * lmrc_tran_reset
551  *
552  * Reset a target. There's no support for RESET_LUN or RESET_ALL.
553  */
554 static int
555 lmrc_tran_reset(struct scsi_address *sa, int level)
556 {
557 	struct scsi_device *sd = scsi_address_device(sa);
558 	lmrc_tgt_t *tgt = scsi_device_hba_private_get(sd);
559 	lmrc_t *lmrc = tgt->tgt_lmrc;
560 	int ret = 0;
561 
562 	VERIFY(lmrc != NULL);
563 
564 	if (lmrc->l_fw_fault)
565 		return (0);
566 
567 	switch (level) {
568 	case RESET_ALL:
569 	case RESET_LUN:
570 	case RESET_TARGET:
571 		rw_enter(&tgt->tgt_lock, RW_READER);
572 		ret = lmrc_task_mgmt(lmrc, tgt,
573 		    MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0);
574 		rw_exit(&tgt->tgt_lock);
575 
576 		if (ret == -1) {
577 			dev_err(lmrc->l_dip, CE_WARN,
578 			    "!target reset timed out, tgt %d",
579 			    tgt->tgt_dev_id);
580 			return (0);
581 		}
582 
583 		break;
584 	}
585 
586 	/*
587 	 * Fake a successful return in the case of RESET_ALL for the benefit of
588 	 * being able to save kernel core dumps. sddump() wants to reset the
589 	 * device and errors out if that fails, even if that happens not because
590 	 * of an error but because of a reset not being supported.
591 	 */
592 	if (ret == 0 && level == RESET_ALL)
593 		ret = 1;
594 
595 	return (ret);
596 }
597 
598 /*
599  * lmrc_tran_setup_pkt
600  *
601  * Set up a MPT command for a scsi_pkt, and initialize scsi_pkt members as
602  * needed:
603  * - pkt_cdbp will point to the CDB structure embedded in the MPT I/O frame
604  * - pkt_scbp will point to the struct scsi_arq_status in the sense DMA memory
605  *   allocated for the MPT command
606  * - pkt_scblen will be set to the size of the sense DMA memory, minus alignment
607  * - SenseBufferLowAddress and SenseBufferLength in the MPT I/O frame will be
608  *   set to the sense DMA address and length, respectively, adjusted to account
609  *   for the space needed for the ARQ pkt and alignment.
610  * - There is no SenseBufferHighAddress.
611  * - rc_timeout is set to pkt_time, but it is unknown if that has any effect
612  *
613  * The procedure is the same irrespective of whether the command is sent to a
614  * physical device or RAID volume.
615  */
616 static int
617 lmrc_tran_setup_pkt(struct scsi_pkt *pkt, int (*callback)(caddr_t),
618     caddr_t arg)
619 {
620 	struct scsi_address *sa;
621 	struct scsi_device *sd;
622 	lmrc_tgt_t *tgt;
623 	lmrc_t *lmrc;
624 	lmrc_scsa_cmd_t *cmd;
625 	lmrc_mpt_cmd_t *mpt;
626 	Mpi25SCSIIORequest_t *io_req;
627 	lmrc_raidctx_g35_t *rc;
628 
629 	if (pkt->pkt_cdblen > sizeof (io_req->CDB.CDB32))
630 		return (-1);
631 
632 	sa = &pkt->pkt_address;
633 	VERIFY(sa != NULL);
634 
635 	sd = scsi_address_device(sa);
636 	VERIFY(sd != NULL);
637 
638 	tgt = scsi_device_hba_private_get(sd);
639 	VERIFY(tgt != NULL);
640 
641 	rw_enter(&tgt->tgt_lock, RW_READER);
642 
643 	lmrc = tgt->tgt_lmrc;
644 	VERIFY(lmrc != NULL);
645 
646 	cmd = pkt->pkt_ha_private;
647 	ASSERT(cmd != NULL);
648 
649 	mpt = lmrc_get_mpt(lmrc);
650 	ASSERT(mutex_owned(&mpt->mpt_lock));
651 
652 	io_req = mpt->mpt_io_frame;
653 
654 	pkt->pkt_cdbp = io_req->CDB.CDB32;
655 
656 	/* Just the CDB length now, but other flags may be set later. */
657 	io_req->IoFlags = pkt->pkt_cdblen;
658 
659 	/*
660 	 * Set up sense buffer. The DMA memory was setup to holds the whole ARQ
661 	 * structure aligned so that its sts_sensedata is aligned to 64 bytes.
662 	 * Point SenseBufferLowAddress to sts_sensedata and reduce the length
663 	 * accordingly.
664 	 */
665 	pkt->pkt_scbp = mpt->mpt_sense;
666 	pkt->pkt_scblen = lmrc_dma_get_size(&mpt->mpt_sense_dma) - 64 +
667 	    offsetof(struct scsi_arq_status, sts_sensedata);
668 
669 	lmrc_dma_set_addr32(&mpt->mpt_sense_dma,
670 	    &io_req->SenseBufferLowAddress);
671 	io_req->SenseBufferLowAddress +=
672 	    P2ROUNDUP(offsetof(struct scsi_arq_status, sts_sensedata), 64);
673 	io_req->SenseBufferLength = pkt->pkt_scblen -
674 	    offsetof(struct scsi_arq_status, sts_sensedata);
675 
676 	rc = &io_req->VendorRegion;
677 	rc->rc_timeout = pkt->pkt_time;
678 
679 	cmd->sc_mpt = mpt;
680 	cmd->sc_tgt = tgt;
681 	mpt->mpt_pkt = pkt;
682 	mutex_exit(&mpt->mpt_lock);
683 	rw_exit(&tgt->tgt_lock);
684 
685 	return (0);
686 }
687 
688 /*
689  * lmrc_tran_teardown_pkt
690  *
691  * Return the MPT command to the free list. It'll be cleared later before
692  * it is reused.
693  */
694 static void
695 lmrc_tran_teardown_pkt(struct scsi_pkt *pkt)
696 {
697 	lmrc_scsa_cmd_t *cmd;
698 	lmrc_mpt_cmd_t *mpt;
699 
700 	cmd = pkt->pkt_ha_private;
701 	ASSERT(cmd != NULL);
702 
703 	mpt = cmd->sc_mpt;
704 	ASSERT(mpt != NULL);
705 
706 	mutex_enter(&mpt->mpt_lock);
707 	lmrc_put_mpt(mpt);
708 }
709 
710 /*
711  * lmrc_hba_attach
712  *
713  * Set up the HBA functions of lmrc. This is a SAS controller and uses complex
714  * addressing for targets, presenting physical devices (PDs) and RAID volumes
715  * (LD) as separate iports.
716  */
717 int
718 lmrc_hba_attach(lmrc_t *lmrc)
719 {
720 	scsi_hba_tran_t	*tran;
721 	ddi_dma_attr_t tran_attr = lmrc->l_dma_attr_32;
722 
723 	tran = scsi_hba_tran_alloc(lmrc->l_dip, SCSI_HBA_CANSLEEP);
724 	if (tran == NULL) {
725 		dev_err(lmrc->l_dip, CE_WARN, "!scsi_hba_tran_alloc failed");
726 		return (DDI_FAILURE);
727 	}
728 
729 	tran->tran_hba_private = lmrc;
730 
731 	tran->tran_tgt_init = lmrc_tran_tgt_init;
732 	tran->tran_tgt_free = lmrc_tran_tgt_free;
733 
734 	tran->tran_tgt_probe = scsi_hba_probe;
735 
736 	tran->tran_start = lmrc_tran_start;
737 	tran->tran_abort = lmrc_tran_abort;
738 	tran->tran_reset = lmrc_tran_reset;
739 
740 	tran->tran_getcap = lmrc_getcap;
741 	tran->tran_setcap = lmrc_setcap;
742 
743 	tran->tran_setup_pkt = lmrc_tran_setup_pkt;
744 	tran->tran_teardown_pkt = lmrc_tran_teardown_pkt;
745 	tran->tran_hba_len = sizeof (lmrc_scsa_cmd_t);
746 	tran->tran_interconnect_type = INTERCONNECT_SAS;
747 
748 	if (lmrc_relaxed_ordering)
749 		tran_attr.dma_attr_flags |= DDI_DMA_RELAXED_ORDERING;
750 	tran_attr.dma_attr_sgllen = lmrc->l_max_num_sge;
751 
752 	if (scsi_hba_attach_setup(lmrc->l_dip, &tran_attr, tran,
753 	    SCSI_HBA_HBA | SCSI_HBA_ADDR_COMPLEX) != DDI_SUCCESS)
754 		goto fail;
755 
756 	lmrc->l_hba_tran = tran;
757 
758 	if (scsi_hba_iport_register(lmrc->l_dip, LMRC_IPORT_RAID) !=
759 	    DDI_SUCCESS)
760 		goto fail;
761 
762 	if (scsi_hba_iport_register(lmrc->l_dip, LMRC_IPORT_PHYS) !=
763 	    DDI_SUCCESS)
764 		goto fail;
765 
766 	return (DDI_SUCCESS);
767 
768 fail:
769 	dev_err(lmrc->l_dip, CE_WARN,
770 	    "!could not attach to SCSA framework");
771 	lmrc_hba_detach(lmrc);
772 
773 	return (DDI_FAILURE);
774 }
775 
776 void
777 lmrc_hba_detach(lmrc_t *lmrc)
778 {
779 	if (lmrc->l_hba_tran == NULL)
780 		return;
781 
782 	(void) scsi_hba_detach(lmrc->l_dip);
783 	scsi_hba_tran_free(lmrc->l_hba_tran);
784 	lmrc->l_hba_tran = NULL;
785 }
786