1 /*-
2 * Copyright (c) 2017 Broadcom. All rights reserved.
3 * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 * $FreeBSD$
32 */
33
34 /**
35 * @defgroup scsi_api_target SCSI Target API
36 * @defgroup scsi_api_initiator SCSI Initiator API
37 * @defgroup cam_api Common Access Method (CAM) API
38 * @defgroup cam_io CAM IO
39 */
40
41 /**
42 * @file
43 * Provides CAM functionality.
44 */
45
46 #include "ocs.h"
47 #include "ocs_scsi.h"
48 #include "ocs_device.h"
49
50 /* Default IO timeout value for initiators is 30 seconds */
51 #define OCS_CAM_IO_TIMEOUT 30
52
53 typedef struct {
54 ocs_scsi_sgl_t *sgl;
55 uint32_t sgl_max;
56 uint32_t sgl_count;
57 int32_t rc;
58 } ocs_dmamap_load_arg_t;
59
60 static void ocs_action(struct cam_sim *, union ccb *);
61 static void ocs_poll(struct cam_sim *);
62
63 static ocs_tgt_resource_t *ocs_tgt_resource_get(ocs_fcport *,
64 struct ccb_hdr *, uint32_t *);
65 static int32_t ocs_tgt_resource_abort(struct ocs_softc *, ocs_tgt_resource_t *);
66 static uint32_t ocs_abort_initiator_io(struct ocs_softc *ocs, union ccb *accb);
67 static void ocs_abort_inot(struct ocs_softc *ocs, union ccb *ccb);
68 static void ocs_abort_atio(struct ocs_softc *ocs, union ccb *ccb);
69 static int32_t ocs_target_tmf_cb(ocs_io_t *, ocs_scsi_io_status_e, uint32_t, void *);
70 static int32_t ocs_io_abort_cb(ocs_io_t *, ocs_scsi_io_status_e, uint32_t, void *);
71 static int32_t ocs_task_set_full_or_busy(ocs_io_t *io);
72 static int32_t ocs_initiator_tmf_cb(ocs_io_t *, ocs_scsi_io_status_e,
73 ocs_scsi_cmd_resp_t *, uint32_t, void *);
74 static uint32_t
75 ocs_fcp_change_role(struct ocs_softc *ocs, ocs_fcport *fcp, uint32_t new_role);
76
77 static void ocs_ldt(void *arg);
78 static void ocs_ldt_task(void *arg, int pending);
79 static void ocs_delete_target(ocs_t *ocs, ocs_fcport *fcp, int tgt);
80 uint32_t ocs_add_new_tgt(ocs_node_t *node, ocs_fcport *fcp);
81 uint32_t ocs_update_tgt(ocs_node_t *node, ocs_fcport *fcp, uint32_t tgt_id);
82
83 int32_t ocs_tgt_find(ocs_fcport *fcp, ocs_node_t *node);
84
85 static inline ocs_io_t *ocs_scsi_find_io(struct ocs_softc *ocs, uint32_t tag)
86 {
87
88 return ocs_io_get_instance(ocs, tag);
89 }
90
91 static inline void ocs_target_io_free(ocs_io_t *io)
92 {
93 io->tgt_io.state = OCS_CAM_IO_FREE;
94 io->tgt_io.flags = 0;
95 io->tgt_io.app = NULL;
96 ocs_scsi_io_complete(io);
97 if(io->ocs->io_in_use != 0)
98 atomic_subtract_acq_32(&io->ocs->io_in_use, 1);
99 }
100
101 static int32_t
102 ocs_attach_port(ocs_t *ocs, int chan)
103 {
104
105 struct cam_sim *sim = NULL;
106 struct cam_path *path = NULL;
107 uint32_t max_io = ocs_scsi_get_property(ocs, OCS_SCSI_MAX_IOS);
108 ocs_fcport *fcp = FCPORT(ocs, chan);
109
110 if (NULL == (sim = cam_sim_alloc(ocs_action, ocs_poll,
111 device_get_name(ocs->dev), ocs,
112 device_get_unit(ocs->dev), &ocs->sim_lock,
113 max_io, max_io, ocs->devq))) {
114 device_printf(ocs->dev, "Can't allocate SIM\n");
115 return 1;
116 }
117
118 mtx_lock(&ocs->sim_lock);
119 if (CAM_SUCCESS != xpt_bus_register(sim, ocs->dev, chan)) {
120 device_printf(ocs->dev, "Can't register bus %d\n", 0);
121 mtx_unlock(&ocs->sim_lock);
122 cam_sim_free(sim, FALSE);
123 return 1;
124 }
125 mtx_unlock(&ocs->sim_lock);
126
127 if (CAM_REQ_CMP != xpt_create_path(&path, NULL, cam_sim_path(sim),
128 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD)) {
129 device_printf(ocs->dev, "Can't create path\n");
130 xpt_bus_deregister(cam_sim_path(sim));
131 mtx_unlock(&ocs->sim_lock);
132 cam_sim_free(sim, FALSE);
133 return 1;
134 }
135
136 fcp->ocs = ocs;
137 fcp->sim = sim;
138 fcp->path = path;
139
140 callout_init_mtx(&fcp->ldt, &ocs->sim_lock, 0);
141 TASK_INIT(&fcp->ltask, 1, ocs_ldt_task, fcp);
142
143 return 0;
144 }
145
146 static int32_t
147 ocs_detach_port(ocs_t *ocs, int32_t chan)
148 {
149 ocs_fcport *fcp = NULL;
150 struct cam_sim *sim = NULL;
151 struct cam_path *path = NULL;
152 fcp = FCPORT(ocs, chan);
153
154 sim = fcp->sim;
155 path = fcp->path;
156
157 callout_drain(&fcp->ldt);
158 ocs_ldt_task(fcp, 0);
159
160 if (fcp->sim) {
161 mtx_lock(&ocs->sim_lock);
162 ocs_tgt_resource_abort(ocs, &fcp->targ_rsrc_wildcard);
163 if (path) {
164 xpt_async(AC_LOST_DEVICE, path, NULL);
165 xpt_free_path(path);
166 fcp->path = NULL;
167 }
168 xpt_bus_deregister(cam_sim_path(sim));
169
170 cam_sim_free(sim, FALSE);
171 fcp->sim = NULL;
172 mtx_unlock(&ocs->sim_lock);
173 }
174
175 return 0;
176 }
177
178 int32_t
179 ocs_cam_attach(ocs_t *ocs)
180 {
181 struct cam_devq *devq = NULL;
182 int i = 0;
183 uint32_t max_io = ocs_scsi_get_property(ocs, OCS_SCSI_MAX_IOS);
184
185 if (NULL == (devq = cam_simq_alloc(max_io))) {
186 device_printf(ocs->dev, "Can't allocate SIMQ\n");
187 return -1;
188 }
189
190 ocs->devq = devq;
191
192 if (mtx_initialized(&ocs->sim_lock) == 0) {
193 mtx_init(&ocs->sim_lock, "ocs_sim_lock", NULL, MTX_DEF);
194 }
195
196 for (i = 0; i < (ocs->num_vports + 1); i++) {
197 if (ocs_attach_port(ocs, i)) {
198 ocs_log_err(ocs, "Attach port failed for chan: %d\n", i);
199 goto detach_port;
200 }
201 }
202
203 ocs->io_high_watermark = max_io;
204 ocs->io_in_use = 0;
205 return 0;
206
207 detach_port:
208 while (--i >= 0) {
209 ocs_detach_port(ocs, i);
210 }
211
212 cam_simq_free(ocs->devq);
213
214 if (mtx_initialized(&ocs->sim_lock))
215 mtx_destroy(&ocs->sim_lock);
216
217 return 1;
218 }
219
220 int32_t
221 ocs_cam_detach(ocs_t *ocs)
222 {
223 int i = 0;
224
225 for (i = (ocs->num_vports); i >= 0; i--) {
226 ocs_detach_port(ocs, i);
227 }
228
229 cam_simq_free(ocs->devq);
230
231 if (mtx_initialized(&ocs->sim_lock))
232 mtx_destroy(&ocs->sim_lock);
233
234 return 0;
235 }
236
237 /***************************************************************************
238 * Functions required by SCSI base driver API
239 */
240
241 /**
242 * @ingroup scsi_api_target
243 * @brief Attach driver to the BSD SCSI layer (a.k.a CAM)
244 *
245 * Allocates + initializes CAM related resources and attaches to the CAM
246 *
247 * @param ocs the driver instance's software context
248 *
249 * @return 0 on success, non-zero otherwise
250 */
251 int32_t
252 ocs_scsi_tgt_new_device(ocs_t *ocs)
253 {
254 ocs->enable_task_set_full = ocs_scsi_get_property(ocs,
255 OCS_SCSI_ENABLE_TASK_SET_FULL);
256 ocs_log_debug(ocs, "task set full processing is %s\n",
257 ocs->enable_task_set_full ? "enabled" : "disabled");
258
259 return 0;
260 }
261
262 /**
263 * @ingroup scsi_api_target
264 * @brief Tears down target members of ocs structure.
265 *
266 * Called by OS code when device is removed.
267 *
268 * @param ocs pointer to ocs
269 *
270 * @return returns 0 for success, a negative error code value for failure.
271 */
272 int32_t
273 ocs_scsi_tgt_del_device(ocs_t *ocs)
274 {
275
276 return 0;
277 }
278
279 /**
280 * @ingroup scsi_api_target
281 * @brief accept new domain notification
282 *
283 * Called by base drive when new domain is discovered. A target-server
284 * will use this call to prepare for new remote node notifications
285 * arising from ocs_scsi_new_initiator().
286 *
287 * The domain context has an element <b>ocs_scsi_tgt_domain_t tgt_domain</b>
288 * which is declared by the target-server code and is used for target-server
289 * private data.
290 *
291 * This function will only be called if the base-driver has been enabled for
292 * target capability.
293 *
294 * Note that this call is made to target-server backends,
295 * the ocs_scsi_ini_new_domain() function is called to initiator-client backends.
296 *
297 * @param domain pointer to domain
298 *
299 * @return returns 0 for success, a negative error code value for failure.
300 */
301 int32_t
302 ocs_scsi_tgt_new_domain(ocs_domain_t *domain)
303 {
304 return 0;
305 }
306
307 /**
308 * @ingroup scsi_api_target
309 * @brief accept domain lost notification
310 *
311 * Called by base-driver when a domain goes away. A target-server will
312 * use this call to clean up all domain scoped resources.
313 *
314 * Note that this call is made to target-server backends,
315 * the ocs_scsi_ini_del_domain() function is called to initiator-client backends.
316 *
317 * @param domain pointer to domain
318 *
319 * @return returns 0 for success, a negative error code value for failure.
320 */
321 void
322 ocs_scsi_tgt_del_domain(ocs_domain_t *domain)
323 {
324 }
325
326 /**
327 * @ingroup scsi_api_target
328 * @brief accept new sli port (sport) notification
329 *
330 * Called by base drive when new sport is discovered. A target-server
331 * will use this call to prepare for new remote node notifications
332 * arising from ocs_scsi_new_initiator().
333 *
334 * The domain context has an element <b>ocs_scsi_tgt_sport_t tgt_sport</b>
335 * which is declared by the target-server code and is used for
336 * target-server private data.
337 *
338 * This function will only be called if the base-driver has been enabled for
339 * target capability.
340 *
341 * Note that this call is made to target-server backends,
342 * the ocs_scsi_tgt_new_domain() is called to initiator-client backends.
343 *
344 * @param sport pointer to SLI port
345 *
346 * @return returns 0 for success, a negative error code value for failure.
347 */
348 int32_t
349 ocs_scsi_tgt_new_sport(ocs_sport_t *sport)
350 {
351 ocs_t *ocs = sport->ocs;
352
353 if(!sport->is_vport) {
354 sport->tgt_data = FCPORT(ocs, 0);
355 }
356
357 return 0;
358 }
359
360 /**
361 * @ingroup scsi_api_target
362 * @brief accept SLI port gone notification
363 *
364 * Called by base-driver when a sport goes away. A target-server will
365 * use this call to clean up all sport scoped resources.
366 *
367 * Note that this call is made to target-server backends,
368 * the ocs_scsi_ini_del_sport() is called to initiator-client backends.
369 *
370 * @param sport pointer to SLI port
371 *
372 * @return returns 0 for success, a negative error code value for failure.
373 */
374 void
375 ocs_scsi_tgt_del_sport(ocs_sport_t *sport)
376 {
377 return;
378 }
379
380 /**
381 * @ingroup scsi_api_target
382 * @brief receive notification of a new SCSI initiator node
383 *
384 * Sent by base driver to notify a target-server of the presense of a new
385 * remote initiator. The target-server may use this call to prepare for
386 * inbound IO from this node.
387 *
388 * The ocs_node_t structure has and elment of type ocs_scsi_tgt_node_t named
389 * tgt_node that is declared and used by a target-server for private
390 * information.
391 *
392 * This function is only called if the target capability is enabled in driver.
393 *
394 * @param node pointer to new remote initiator node
395 *
396 * @return returns 0 for success, a negative error code value for failure.
397 *
398 * @note
399 */
400 int32_t
401 ocs_scsi_new_initiator(ocs_node_t *node)
402 {
403 ocs_t *ocs = node->ocs;
404 struct ac_contract ac;
405 struct ac_device_changed *adc;
406
407 ocs_fcport *fcp = NULL;
408
409 fcp = node->sport->tgt_data;
410 if (fcp == NULL) {
411 ocs_log_err(ocs, "FCP is NULL \n");
412 return 1;
413 }
414
415 /*
416 * Update the IO watermark by decrementing it by the
417 * number of IOs reserved for each initiator.
418 */
419 atomic_subtract_acq_32(&ocs->io_high_watermark, OCS_RSVD_INI_IO);
420
421 ac.contract_number = AC_CONTRACT_DEV_CHG;
422 adc = (struct ac_device_changed *) ac.contract_data;
423 adc->wwpn = ocs_node_get_wwpn(node);
424 adc->port = node->rnode.fc_id;
425 adc->target = node->instance_index;
426 adc->arrived = 1;
427 xpt_async(AC_CONTRACT, fcp->path, &ac);
428
429 return 0;
430 }
431
432 /**
433 * @ingroup scsi_api_target
434 * @brief validate new initiator
435 *
436 * Sent by base driver to validate a remote initiatiator. The target-server
437 * returns TRUE if this initiator should be accepted.
438 *
439 * This function is only called if the target capability is enabled in driver.
440 *
441 * @param node pointer to remote initiator node to validate
442 *
443 * @return TRUE if initiator should be accepted, FALSE if it should be rejected
444 *
445 * @note
446 */
447
448 int32_t
449 ocs_scsi_validate_initiator(ocs_node_t *node)
450 {
451 return 1;
452 }
453
454 /**
455 * @ingroup scsi_api_target
456 * @brief Delete a SCSI initiator node
457 *
458 * Sent by base driver to notify a target-server that a remote initiator
459 * is now gone. The base driver will have terminated all outstanding IOs
460 * and the target-server will receive appropriate completions.
461 *
462 * This function is only called if the base driver is enabled for
463 * target capability.
464 *
465 * @param node pointer node being deleted
466 * @param reason Reason why initiator is gone.
467 *
468 * @return OCS_SCSI_CALL_COMPLETE to indicate that all work was completed
469 *
470 * @note
471 */
472 int32_t
473 ocs_scsi_del_initiator(ocs_node_t *node, ocs_scsi_del_initiator_reason_e reason)
474 {
475 ocs_t *ocs = node->ocs;
476
477 struct ac_contract ac;
478 struct ac_device_changed *adc;
479 ocs_fcport *fcp = NULL;
480
481 fcp = node->sport->tgt_data;
482 if (fcp == NULL) {
483 ocs_log_err(ocs, "FCP is NULL \n");
484 return 1;
485 }
486
487 ac.contract_number = AC_CONTRACT_DEV_CHG;
488 adc = (struct ac_device_changed *) ac.contract_data;
489 adc->wwpn = ocs_node_get_wwpn(node);
490 adc->port = node->rnode.fc_id;
491 adc->target = node->instance_index;
492 adc->arrived = 0;
493 xpt_async(AC_CONTRACT, fcp->path, &ac);
494
495 if (reason == OCS_SCSI_INITIATOR_MISSING) {
496 return OCS_SCSI_CALL_COMPLETE;
497 }
498
499 /*
500 * Update the IO watermark by incrementing it by the
501 * number of IOs reserved for each initiator.
502 */
503 atomic_add_acq_32(&ocs->io_high_watermark, OCS_RSVD_INI_IO);
504
505 return OCS_SCSI_CALL_COMPLETE;
506 }
507
508 /**
509 * @ingroup scsi_api_target
510 * @brief receive FCP SCSI Command
511 *
512 * Called by the base driver when a new SCSI command has been received. The
513 * target-server will process the command, and issue data and/or response phase
514 * requests to the base driver.
515 *
516 * The IO context (ocs_io_t) structure has and element of type
517 * ocs_scsi_tgt_io_t named tgt_io that is declared and used by
518 * a target-server for private information.
519 *
520 * @param io pointer to IO context
521 * @param lun LUN for this IO
522 * @param cdb pointer to SCSI CDB
523 * @param cdb_len length of CDB in bytes
524 * @param flags command flags
525 *
526 * @return returns 0 for success, a negative error code value for failure.
527 */
528 int32_t ocs_scsi_recv_cmd(ocs_io_t *io, uint64_t lun, uint8_t *cdb,
529 uint32_t cdb_len, uint32_t flags)
530 {
531 ocs_t *ocs = io->ocs;
532 struct ccb_accept_tio *atio = NULL;
533 ocs_node_t *node = io->node;
534 ocs_tgt_resource_t *trsrc = NULL;
535 int32_t rc = -1;
536 ocs_fcport *fcp = NULL;
537
538 fcp = node->sport->tgt_data;
539 if (fcp == NULL) {
540 ocs_log_err(ocs, "FCP is NULL \n");
541 return 1;
542 }
543
544 atomic_add_acq_32(&ocs->io_in_use, 1);
545
546 /* set target io timeout */
547 io->timeout = ocs->target_io_timer_sec;
548
549 if (ocs->enable_task_set_full &&
550 (ocs->io_in_use >= ocs->io_high_watermark)) {
551 return ocs_task_set_full_or_busy(io);
552 } else {
553 atomic_store_rel_32(&io->node->tgt_node.busy_sent, FALSE);
554 }
555
556 if ((lun < OCS_MAX_LUN) && fcp->targ_rsrc[lun].enabled) {
557 trsrc = &fcp->targ_rsrc[lun];
558 } else if (fcp->targ_rsrc_wildcard.enabled) {
559 trsrc = &fcp->targ_rsrc_wildcard;
560 }
561
562 if (trsrc) {
563 atio = (struct ccb_accept_tio *)STAILQ_FIRST(&trsrc->atio);
564 }
565
566 if (atio) {
567 STAILQ_REMOVE_HEAD(&trsrc->atio, sim_links.stqe);
568
569 atio->ccb_h.status = CAM_CDB_RECVD;
570 atio->ccb_h.target_lun = lun;
571 atio->sense_len = 0;
572
573 atio->init_id = node->instance_index;
574 atio->tag_id = io->tag;
575 atio->ccb_h.ccb_io_ptr = io;
576
577 if (flags & OCS_SCSI_CMD_SIMPLE)
578 atio->tag_action = MSG_SIMPLE_Q_TAG;
579 else if (flags & OCS_SCSI_CMD_HEAD_OF_QUEUE)
580 atio->tag_action = MSG_HEAD_OF_Q_TAG;
581 else if (flags & OCS_SCSI_CMD_ORDERED)
582 atio->tag_action = MSG_ORDERED_Q_TAG;
583 else if (flags & OCS_SCSI_CMD_ACA)
584 atio->tag_action = MSG_ACA_TASK;
585 else
586 atio->tag_action = CAM_TAG_ACTION_NONE;
587 atio->priority = (flags & OCS_SCSI_PRIORITY_MASK) >>
588 OCS_SCSI_PRIORITY_SHIFT;
589
590 atio->cdb_len = cdb_len;
591 ocs_memcpy(atio->cdb_io.cdb_bytes, cdb, cdb_len);
592
593 io->tgt_io.flags = 0;
594 io->tgt_io.state = OCS_CAM_IO_COMMAND;
595 io->tgt_io.lun = lun;
596
597 xpt_done((union ccb *)atio);
598
599 rc = 0;
600 } else {
601 device_printf(
602 ocs->dev, "%s: no ATIO for LUN %lx (en=%s) OX_ID %#x\n",
603 __func__, (unsigned long)lun,
604 trsrc ? (trsrc->enabled ? "T" : "F") : "X",
605 be16toh(io->init_task_tag));
606
607 io->tgt_io.state = OCS_CAM_IO_MAX;
608 ocs_target_io_free(io);
609 }
610
611 return rc;
612 }
613
614 /**
615 * @ingroup scsi_api_target
616 * @brief receive FCP SCSI Command with first burst data.
617 *
618 * Receive a new FCP SCSI command from the base driver with first burst data.
619 *
620 * @param io pointer to IO context
621 * @param lun LUN for this IO
622 * @param cdb pointer to SCSI CDB
623 * @param cdb_len length of CDB in bytes
624 * @param flags command flags
625 * @param first_burst_buffers first burst buffers
626 * @param first_burst_buffer_count The number of bytes received in the first burst
627 *
628 * @return returns 0 for success, a negative error code value for failure.
629 */
630 int32_t ocs_scsi_recv_cmd_first_burst(ocs_io_t *io, uint64_t lun, uint8_t *cdb,
631 uint32_t cdb_len, uint32_t flags,
632 ocs_dma_t first_burst_buffers[],
633 uint32_t first_burst_buffer_count)
634 {
635 return -1;
636 }
637
638 /**
639 * @ingroup scsi_api_target
640 * @brief receive a TMF command IO
641 *
642 * Called by the base driver when a SCSI TMF command has been received. The
643 * target-server will process the command, aborting commands as needed, and post
644 * a response using ocs_scsi_send_resp()
645 *
646 * The IO context (ocs_io_t) structure has and element of type ocs_scsi_tgt_io_t named
647 * tgt_io that is declared and used by a target-server for private information.
648 *
649 * If the target-server walks the nodes active_ios linked list, and starts IO
650 * abort processing, the code <b>must</b> be sure not to abort the IO passed into the
651 * ocs_scsi_recv_tmf() command.
652 *
653 * @param tmfio pointer to IO context
654 * @param lun logical unit value
655 * @param cmd command request
656 * @param abortio pointer to IO object to abort for TASK_ABORT (NULL for all other TMF)
657 * @param flags flags
658 *
659 * @return returns 0 for success, a negative error code value for failure.
660 */
661 int32_t ocs_scsi_recv_tmf(ocs_io_t *tmfio, uint64_t lun, ocs_scsi_tmf_cmd_e cmd,
662 ocs_io_t *abortio, uint32_t flags)
663 {
664 ocs_t *ocs = tmfio->ocs;
665 ocs_node_t *node = tmfio->node;
666 ocs_tgt_resource_t *trsrc = NULL;
667 struct ccb_immediate_notify *inot = NULL;
668 int32_t rc = -1;
669 ocs_fcport *fcp = NULL;
670
671 fcp = node->sport->tgt_data;
672 if (fcp == NULL) {
673 ocs_log_err(ocs, "FCP is NULL \n");
674 return 1;
675 }
676
677 if ((lun < OCS_MAX_LUN) && fcp->targ_rsrc[lun].enabled) {
678 trsrc = &fcp->targ_rsrc[lun];
679 } else if (fcp->targ_rsrc_wildcard.enabled) {
680 trsrc = &fcp->targ_rsrc_wildcard;
681 }
682
683 device_printf(tmfio->ocs->dev, "%s: io=%p cmd=%#x LU=%lx en=%s\n",
684 __func__, tmfio, cmd, (unsigned long)lun,
685 trsrc ? (trsrc->enabled ? "T" : "F") : "X");
686 if (trsrc) {
687 inot = (struct ccb_immediate_notify *)STAILQ_FIRST(&trsrc->inot);
688 }
689
690 if (!inot) {
691 device_printf(
692 ocs->dev, "%s: no INOT for LUN %llx (en=%s) OX_ID %#x\n",
693 __func__, (unsigned long long)lun, trsrc ? (trsrc->enabled ? "T" : "F") : "X",
694 be16toh(tmfio->init_task_tag));
695
696 if (abortio) {
697 ocs_scsi_io_complete(abortio);
698 }
699 ocs_scsi_io_complete(tmfio);
700 goto ocs_scsi_recv_tmf_out;
701 }
702
703 tmfio->tgt_io.app = abortio;
704
705 STAILQ_REMOVE_HEAD(&trsrc->inot, sim_links.stqe);
706
707 inot->tag_id = tmfio->tag;
708 inot->seq_id = tmfio->tag;
709
710 if ((lun < OCS_MAX_LUN) && fcp->targ_rsrc[lun].enabled) {
711 inot->initiator_id = node->instance_index;
712 } else {
713 inot->initiator_id = CAM_TARGET_WILDCARD;
714 }
715
716 inot->ccb_h.status = CAM_MESSAGE_RECV;
717 inot->ccb_h.target_lun = lun;
718
719 switch (cmd) {
720 case OCS_SCSI_TMF_ABORT_TASK:
721 inot->arg = MSG_ABORT_TASK;
722 inot->seq_id = abortio->tag;
723 device_printf(ocs->dev, "%s: ABTS IO.%#x st=%#x\n",
724 __func__, abortio->tag, abortio->tgt_io.state);
725 abortio->tgt_io.flags |= OCS_CAM_IO_F_ABORT_RECV;
726 abortio->tgt_io.flags |= OCS_CAM_IO_F_ABORT_NOTIFY;
727 break;
728 case OCS_SCSI_TMF_QUERY_TASK_SET:
729 device_printf(ocs->dev,
730 "%s: OCS_SCSI_TMF_QUERY_TASK_SET not supported\n",
731 __func__);
732 STAILQ_INSERT_TAIL(&trsrc->inot, &inot->ccb_h, sim_links.stqe);
733 ocs_scsi_io_complete(tmfio);
734 goto ocs_scsi_recv_tmf_out;
735 break;
736 case OCS_SCSI_TMF_ABORT_TASK_SET:
737 inot->arg = MSG_ABORT_TASK_SET;
738 break;
739 case OCS_SCSI_TMF_CLEAR_TASK_SET:
740 inot->arg = MSG_CLEAR_TASK_SET;
741 break;
742 case OCS_SCSI_TMF_QUERY_ASYNCHRONOUS_EVENT:
743 inot->arg = MSG_QUERY_ASYNC_EVENT;
744 break;
745 case OCS_SCSI_TMF_LOGICAL_UNIT_RESET:
746 inot->arg = MSG_LOGICAL_UNIT_RESET;
747 break;
748 case OCS_SCSI_TMF_CLEAR_ACA:
749 inot->arg = MSG_CLEAR_ACA;
750 break;
751 case OCS_SCSI_TMF_TARGET_RESET:
752 inot->arg = MSG_TARGET_RESET;
753 break;
754 default:
755 device_printf(ocs->dev, "%s: unsupported TMF %#x\n",
756 __func__, cmd);
757 STAILQ_INSERT_TAIL(&trsrc->inot, &inot->ccb_h, sim_links.stqe);
758 goto ocs_scsi_recv_tmf_out;
759 }
760
761 rc = 0;
762
763 xpt_print(inot->ccb_h.path, "%s: func=%#x stat=%#x id=%#x lun=%#x"
764 " flags=%#x tag=%#x seq=%#x ini=%#x arg=%#x\n",
765 __func__, inot->ccb_h.func_code, inot->ccb_h.status,
766 inot->ccb_h.target_id,
767 (unsigned int)inot->ccb_h.target_lun, inot->ccb_h.flags,
768 inot->tag_id, inot->seq_id, inot->initiator_id,
769 inot->arg);
770 xpt_done((union ccb *)inot);
771
772 if (abortio) {
773 abortio->tgt_io.flags |= OCS_CAM_IO_F_ABORT_DEV;
774 rc = ocs_scsi_tgt_abort_io(abortio, ocs_io_abort_cb, tmfio);
775 }
776
777 ocs_scsi_recv_tmf_out:
778 return rc;
779 }
780
781 /**
782 * @ingroup scsi_api_initiator
783 * @brief Initializes any initiator fields on the ocs structure.
784 *
785 * Called by OS initialization code when a new device is discovered.
786 *
787 * @param ocs pointer to ocs
788 *
789 * @return returns 0 for success, a negative error code value for failure.
790 */
791 int32_t
792 ocs_scsi_ini_new_device(ocs_t *ocs)
793 {
794
795 return 0;
796 }
797
798 /**
799 * @ingroup scsi_api_initiator
800 * @brief Tears down initiator members of ocs structure.
801 *
802 * Called by OS code when device is removed.
803 *
804 * @param ocs pointer to ocs
805 *
806 * @return returns 0 for success, a negative error code value for failure.
807 */
808
809 int32_t
810 ocs_scsi_ini_del_device(ocs_t *ocs)
811 {
812
813 return 0;
814 }
815
816 /**
817 * @ingroup scsi_api_initiator
818 * @brief accept new domain notification
819 *
820 * Called by base drive when new domain is discovered. An initiator-client
821 * will accept this call to prepare for new remote node notifications
822 * arising from ocs_scsi_new_target().
823 *
824 * The domain context has the element <b>ocs_scsi_ini_domain_t ini_domain</b>
825 * which is declared by the initiator-client code and is used for
826 * initiator-client private data.
827 *
828 * This function will only be called if the base-driver has been enabled for
829 * initiator capability.
830 *
831 * Note that this call is made to initiator-client backends,
832 * the ocs_scsi_tgt_new_domain() function is called to target-server backends.
833 *
834 * @param domain pointer to domain
835 *
836 * @return returns 0 for success, a negative error code value for failure.
837 */
838 int32_t
839 ocs_scsi_ini_new_domain(ocs_domain_t *domain)
840 {
841 return 0;
842 }
843
844 /**
845 * @ingroup scsi_api_initiator
846 * @brief accept domain lost notification
847 *
848 * Called by base-driver when a domain goes away. An initiator-client will
849 * use this call to clean up all domain scoped resources.
850 *
851 * This function will only be called if the base-driver has been enabled for
852 * initiator capability.
853 *
854 * Note that this call is made to initiator-client backends,
855 * the ocs_scsi_tgt_del_domain() function is called to target-server backends.
856 *
857 * @param domain pointer to domain
858 *
859 * @return returns 0 for success, a negative error code value for failure.
860 */
861 void
862 ocs_scsi_ini_del_domain(ocs_domain_t *domain)
863 {
864 }
865
866 /**
867 * @ingroup scsi_api_initiator
868 * @brief accept new sli port notification
869 *
870 * Called by base drive when new sli port (sport) is discovered.
871 * A target-server will use this call to prepare for new remote node
872 * notifications arising from ocs_scsi_new_initiator().
873 *
874 * This function will only be called if the base-driver has been enabled for
875 * target capability.
876 *
877 * Note that this call is made to target-server backends,
878 * the ocs_scsi_ini_new_sport() function is called to initiator-client backends.
879 *
880 * @param sport pointer to sport
881 *
882 * @return returns 0 for success, a negative error code value for failure.
883 */
884 int32_t
885 ocs_scsi_ini_new_sport(ocs_sport_t *sport)
886 {
887 ocs_t *ocs = sport->ocs;
888 ocs_fcport *fcp = FCPORT(ocs, 0);
889
890 if (!sport->is_vport) {
891 sport->tgt_data = fcp;
892 fcp->fc_id = sport->fc_id;
893 }
894
895 return 0;
896 }
897
898 /**
899 * @ingroup scsi_api_initiator
900 * @brief accept sli port gone notification
901 *
902 * Called by base-driver when a sport goes away. A target-server will
903 * use this call to clean up all sport scoped resources.
904 *
905 * Note that this call is made to target-server backends,
906 * the ocs_scsi_ini_del_sport() function is called to initiator-client backends.
907 *
908 * @param sport pointer to SLI port
909 *
910 * @return returns 0 for success, a negative error code value for failure.
911 */
912 void
913 ocs_scsi_ini_del_sport(ocs_sport_t *sport)
914 {
915 ocs_t *ocs = sport->ocs;
916 ocs_fcport *fcp = FCPORT(ocs, 0);
917
918 if (!sport->is_vport) {
919 fcp->fc_id = 0;
920 }
921 }
922
923 void
924 ocs_scsi_sport_deleted(ocs_sport_t *sport)
925 {
926 ocs_t *ocs = sport->ocs;
927 ocs_fcport *fcp = NULL;
928
929 ocs_xport_stats_t value;
930
931 if (!sport->is_vport) {
932 return;
933 }
934
935 fcp = sport->tgt_data;
936
937 ocs_xport_status(ocs->xport, OCS_XPORT_PORT_STATUS, &value);
938
939 if (value.value == 0) {
940 ocs_log_debug(ocs, "PORT offline,.. skipping\n");
941 return;
942 }
943
944 if ((fcp->role != KNOB_ROLE_NONE)) {
945 if(fcp->vport->sport != NULL) {
946 ocs_log_debug(ocs,"sport is not NULL, skipping\n");
947 return;
948 }
949
950 ocs_sport_vport_alloc(ocs->domain, fcp->vport);
951 return;
952 }
953
954 }
955
956 int32_t
957 ocs_tgt_find(ocs_fcport *fcp, ocs_node_t *node)
958 {
959 ocs_fc_target_t *tgt = NULL;
960 uint32_t i;
961
962 for (i = 0; i < OCS_MAX_TARGETS; i++) {
963 tgt = &fcp->tgt[i];
964
965 if (tgt->state == OCS_TGT_STATE_NONE)
966 continue;
967
968 if (ocs_node_get_wwpn(node) == tgt->wwpn) {
969 return i;
970 }
971 }
972
973 return -1;
974 }
975
976 /**
977 * @ingroup scsi_api_initiator
978 * @brief receive notification of a new SCSI target node
979 *
980 * Sent by base driver to notify an initiator-client of the presense of a new
981 * remote target. The initiator-server may use this call to prepare for
982 * inbound IO from this node.
983 *
984 * This function is only called if the base driver is enabled for
985 * initiator capability.
986 *
987 * @param node pointer to new remote initiator node
988 *
989 * @return none
990 *
991 * @note
992 */
993
994 uint32_t
995 ocs_update_tgt(ocs_node_t *node, ocs_fcport *fcp, uint32_t tgt_id)
996 {
997 ocs_fc_target_t *tgt = NULL;
998
999 tgt = &fcp->tgt[tgt_id];
1000
1001 tgt->node_id = node->instance_index;
1002 tgt->state = OCS_TGT_STATE_VALID;
1003
1004 tgt->port_id = node->rnode.fc_id;
1005 tgt->wwpn = ocs_node_get_wwpn(node);
1006 tgt->wwnn = ocs_node_get_wwnn(node);
1007 return 0;
1008 }
1009
1010 uint32_t
1011 ocs_add_new_tgt(ocs_node_t *node, ocs_fcport *fcp)
1012 {
1013 uint32_t i;
1014
1015 struct ocs_softc *ocs = node->ocs;
1016 union ccb *ccb = NULL;
1017 for (i = 0; i < OCS_MAX_TARGETS; i++) {
1018 if (fcp->tgt[i].state == OCS_TGT_STATE_NONE)
1019 break;
1020 }
1021
1022 if (NULL == (ccb = xpt_alloc_ccb_nowait())) {
1023 device_printf(ocs->dev, "%s: ccb allocation failed\n", __func__);
1024 return -1;
1025 }
1026
1027 if (CAM_REQ_CMP != xpt_create_path(&ccb->ccb_h.path, xpt_periph,
1028 cam_sim_path(fcp->sim),
1029 i, CAM_LUN_WILDCARD)) {
1030 device_printf(
1031 ocs->dev, "%s: target path creation failed\n", __func__);
1032 xpt_free_ccb(ccb);
1033 return -1;
1034 }
1035
1036 ocs_update_tgt(node, fcp, i);
1037 xpt_rescan(ccb);
1038 return 0;
1039 }
1040
1041 int32_t
1042 ocs_scsi_new_target(ocs_node_t *node)
1043 {
1044 ocs_fcport *fcp = NULL;
1045 int32_t i;
1046
1047 fcp = node->sport->tgt_data;
1048 if (fcp == NULL) {
1049 printf("%s:FCP is NULL \n", __func__);
1050 return 0;
1051 }
1052
1053 i = ocs_tgt_find(fcp, node);
1054
1055 if (i < 0) {
1056 ocs_add_new_tgt(node, fcp);
1057 return 0;
1058 }
1059
1060 ocs_update_tgt(node, fcp, i);
1061 return 0;
1062 }
1063
1064 static void
1065 ocs_delete_target(ocs_t *ocs, ocs_fcport *fcp, int tgt)
1066 {
1067 struct cam_path *cpath = NULL;
1068
1069 if (!fcp->sim) {
1070 device_printf(ocs->dev, "%s: calling with NULL sim\n", __func__);
1071 return;
1072 }
1073
1074 if (CAM_REQ_CMP == xpt_create_path(&cpath, NULL, cam_sim_path(fcp->sim),
1075 tgt, CAM_LUN_WILDCARD)) {
1076 xpt_async(AC_LOST_DEVICE, cpath, NULL);
1077
1078 xpt_free_path(cpath);
1079 }
1080 }
1081
1082 /*
1083 * Device Lost Timer Function- when we have decided that a device was lost,
1084 * we wait a specific period of time prior to telling the OS about lost device.
1085 *
1086 * This timer function gets activated when the device was lost.
1087 * This function fires once a second and then scans the port database
1088 * for devices that are marked dead but still have a virtual target assigned.
1089 * We decrement a counter for that port database entry, and when it hits zero,
1090 * we tell the OS the device was lost. Timer will be stopped when the device
1091 * comes back active or removed from the OS.
1092 */
1093 static void
1094 ocs_ldt(void *arg)
1095 {
1096 ocs_fcport *fcp = arg;
1097 taskqueue_enqueue(taskqueue_thread, &fcp->ltask);
1098 }
1099
1100 static void
1101 ocs_ldt_task(void *arg, int pending)
1102 {
1103 ocs_fcport *fcp = arg;
1104 ocs_t *ocs = fcp->ocs;
1105 int i, more_to_do = 0;
1106 ocs_fc_target_t *tgt = NULL;
1107
1108 for (i = 0; i < OCS_MAX_TARGETS; i++) {
1109 tgt = &fcp->tgt[i];
1110
1111 if (tgt->state != OCS_TGT_STATE_LOST) {
1112 continue;
1113 }
1114
1115 if ((tgt->gone_timer != 0) && (ocs->attached)){
1116 tgt->gone_timer -= 1;
1117 more_to_do++;
1118 continue;
1119 }
1120
1121 ocs_delete_target(ocs, fcp, i);
1122
1123 tgt->state = OCS_TGT_STATE_NONE;
1124 }
1125
1126 if (more_to_do) {
1127 callout_reset(&fcp->ldt, hz, ocs_ldt, fcp);
1128 } else {
1129 callout_deactivate(&fcp->ldt);
1130 }
1131
1132 }
1133
1134 /**
1135 * @ingroup scsi_api_initiator
1136 * @brief Delete a SCSI target node
1137 *
1138 * Sent by base driver to notify a initiator-client that a remote target
1139 * is now gone. The base driver will have terminated all outstanding IOs
1140 * and the initiator-client will receive appropriate completions.
1141 *
1142 * The ocs_node_t structure has and elment of type ocs_scsi_ini_node_t named
1143 * ini_node that is declared and used by a target-server for private
1144 * information.
1145 *
1146 * This function is only called if the base driver is enabled for
1147 * initiator capability.
1148 *
1149 * @param node pointer node being deleted
1150 * @param reason reason for deleting the target
1151 *
1152 * @return Returns OCS_SCSI_CALL_ASYNC if target delete is queued for async
1153 * completion and OCS_SCSI_CALL_COMPLETE if call completed or error.
1154 *
1155 * @note
1156 */
1157 int32_t
1158 ocs_scsi_del_target(ocs_node_t *node, ocs_scsi_del_target_reason_e reason)
1159 {
1160 struct ocs_softc *ocs = node->ocs;
1161 ocs_fcport *fcp = NULL;
1162 ocs_fc_target_t *tgt = NULL;
1163 int32_t tgt_id;
1164
1165 if (ocs == NULL) {
1166 ocs_log_err(ocs,"OCS is NULL \n");
1167 return -1;
1168 }
1169
1170 fcp = node->sport->tgt_data;
1171 if (fcp == NULL) {
1172 ocs_log_err(ocs,"FCP is NULL \n");
1173 return -1;
1174 }
1175
1176 tgt_id = ocs_tgt_find(fcp, node);
1177 if (tgt_id == -1) {
1178 ocs_log_err(ocs,"target is invalid\n");
1179 return -1;
1180 }
1181
1182 tgt = &fcp->tgt[tgt_id];
1183
1184 // IF in shutdown delete target.
1185 if(!ocs->attached) {
1186 ocs_delete_target(ocs, fcp, tgt_id);
1187 } else {
1188 tgt->state = OCS_TGT_STATE_LOST;
1189 tgt->gone_timer = 30;
1190 if (!callout_active(&fcp->ldt)) {
1191 callout_reset(&fcp->ldt, hz, ocs_ldt, fcp);
1192 }
1193 }
1194
1195 return 0;
1196 }
1197
1198 /**
1199 * @brief Initialize SCSI IO
1200 *
1201 * Initialize SCSI IO, this function is called once per IO during IO pool
1202 * allocation so that the target server may initialize any of its own private
1203 * data.
1204 *
1205 * @param io pointer to SCSI IO object
1206 *
1207 * @return returns 0 for success, a negative error code value for failure.
1208 */
1209 int32_t
1210 ocs_scsi_tgt_io_init(ocs_io_t *io)
1211 {
1212 return 0;
1213 }
1214
1215 /**
1216 * @brief Uninitialize SCSI IO
1217 *
1218 * Uninitialize target server private data in a SCSI io object
1219 *
1220 * @param io pointer to SCSI IO object
1221 *
1222 * @return returns 0 for success, a negative error code value for failure.
1223 */
1224 int32_t
1225 ocs_scsi_tgt_io_exit(ocs_io_t *io)
1226 {
1227 return 0;
1228 }
1229
1230 /**
1231 * @brief Initialize SCSI IO
1232 *
1233 * Initialize SCSI IO, this function is called once per IO during IO pool
1234 * allocation so that the initiator client may initialize any of its own private
1235 * data.
1236 *
1237 * @param io pointer to SCSI IO object
1238 *
1239 * @return returns 0 for success, a negative error code value for failure.
1240 */
1241 int32_t
1242 ocs_scsi_ini_io_init(ocs_io_t *io)
1243 {
1244 return 0;
1245 }
1246
1247 /**
1248 * @brief Uninitialize SCSI IO
1249 *
1250 * Uninitialize initiator client private data in a SCSI io object
1251 *
1252 * @param io pointer to SCSI IO object
1253 *
1254 * @return returns 0 for success, a negative error code value for failure.
1255 */
1256 int32_t
1257 ocs_scsi_ini_io_exit(ocs_io_t *io)
1258 {
1259 return 0;
1260 }
1261 /*
1262 * End of functions required by SCSI base driver API
1263 ***************************************************************************/
1264
1265 static __inline void
1266 ocs_set_ccb_status(union ccb *ccb, cam_status status)
1267 {
1268 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
1269 ccb->ccb_h.status |= status;
1270 }
1271
1272 static int32_t
1273 ocs_task_set_full_or_busy_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status,
1274 uint32_t flags, void *arg)
1275 {
1276
1277 ocs_target_io_free(io);
1278
1279 return 0;
1280 }
1281
1282 /**
1283 * @brief send SCSI task set full or busy status
1284 *
1285 * A SCSI task set full or busy response is sent depending on whether
1286 * another IO is already active on the LUN.
1287 *
1288 * @param io pointer to IO context
1289 *
1290 * @return returns 0 for success, a negative error code value for failure.
1291 */
1292
1293 static int32_t
1294 ocs_task_set_full_or_busy(ocs_io_t *io)
1295 {
1296 ocs_scsi_cmd_resp_t rsp = { 0 };
1297 ocs_t *ocs = io->ocs;
1298
1299 /*
1300 * If there is another command for the LUN, then send task set full,
1301 * if this is the first one, then send the busy status.
1302 *
1303 * if 'busy sent' is FALSE, set it to TRUE and send BUSY
1304 * otherwise send FULL
1305 */
1306 if (atomic_cmpset_acq_32(&io->node->tgt_node.busy_sent, FALSE, TRUE)) {
1307 rsp.scsi_status = SCSI_STATUS_BUSY; /* Busy */
1308 printf("%s: busy [%s] tag=%x iiu=%d ihw=%d\n", __func__,
1309 io->node->display_name, io->tag,
1310 io->ocs->io_in_use, io->ocs->io_high_watermark);
1311 } else {
1312 rsp.scsi_status = SCSI_STATUS_TASK_SET_FULL; /* Task set full */
1313 printf("%s: full tag=%x iiu=%d\n", __func__, io->tag,
1314 io->ocs->io_in_use);
1315 }
1316
1317 /* Log a message here indicating a busy or task set full state */
1318 if (OCS_LOG_ENABLE_Q_FULL_BUSY_MSG(ocs)) {
1319 /* Log Task Set Full */
1320 if (rsp.scsi_status == SCSI_STATUS_TASK_SET_FULL) {
1321 /* Task Set Full Message */
1322 ocs_log_info(ocs, "OCS CAM TASK SET FULL. Tasks >= %d\n",
1323 ocs->io_high_watermark);
1324 }
1325 else if (rsp.scsi_status == SCSI_STATUS_BUSY) {
1326 /* Log Busy Message */
1327 ocs_log_info(ocs, "OCS CAM SCSI BUSY\n");
1328 }
1329 }
1330
1331 /* Send the response */
1332 return
1333 ocs_scsi_send_resp(io, 0, &rsp, ocs_task_set_full_or_busy_cb, NULL);
1334 }
1335
1336 /**
1337 * @ingroup cam_io
1338 * @brief Process target IO completions
1339 *
1340 * @param io
1341 * @param scsi_status did the IO complete successfully
1342 * @param flags
1343 * @param arg application specific pointer provided in the call to ocs_target_io()
1344 *
1345 * @todo
1346 */
1347 static int32_t ocs_scsi_target_io_cb(ocs_io_t *io,
1348 ocs_scsi_io_status_e scsi_status,
1349 uint32_t flags, void *arg)
1350 {
1351 union ccb *ccb = arg;
1352 struct ccb_scsiio *csio = &ccb->csio;
1353 struct ocs_softc *ocs = csio->ccb_h.ccb_ocs_ptr;
1354 uint32_t cam_dir = ccb->ccb_h.flags & CAM_DIR_MASK;
1355 uint32_t io_is_done =
1356 (ccb->ccb_h.flags & CAM_SEND_STATUS) == CAM_SEND_STATUS;
1357
1358 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1359
1360 if (CAM_DIR_NONE != cam_dir) {
1361 bus_dmasync_op_t op;
1362
1363 if (CAM_DIR_IN == cam_dir) {
1364 op = BUS_DMASYNC_POSTREAD;
1365 } else {
1366 op = BUS_DMASYNC_POSTWRITE;
1367 }
1368 /* Synchronize the DMA memory with the CPU and free the mapping */
1369 bus_dmamap_sync(ocs->buf_dmat, io->tgt_io.dmap, op);
1370 if (io->tgt_io.flags & OCS_CAM_IO_F_DMAPPED) {
1371 bus_dmamap_unload(ocs->buf_dmat, io->tgt_io.dmap);
1372 }
1373 }
1374
1375 if (io->tgt_io.sendresp) {
1376 io->tgt_io.sendresp = 0;
1377 ocs_scsi_cmd_resp_t resp = { 0 };
1378 io->tgt_io.state = OCS_CAM_IO_RESP;
1379 resp.scsi_status = scsi_status;
1380 if (ccb->ccb_h.flags & CAM_SEND_SENSE) {
1381 resp.sense_data = (uint8_t *)&csio->sense_data;
1382 resp.sense_data_length = csio->sense_len;
1383 }
1384 resp.residual = io->exp_xfer_len - io->transferred;
1385
1386 return ocs_scsi_send_resp(io, 0, &resp, ocs_scsi_target_io_cb, ccb);
1387 }
1388
1389 switch (scsi_status) {
1390 case OCS_SCSI_STATUS_GOOD:
1391 ocs_set_ccb_status(ccb, CAM_REQ_CMP);
1392 break;
1393 case OCS_SCSI_STATUS_ABORTED:
1394 ocs_set_ccb_status(ccb, CAM_REQ_ABORTED);
1395 break;
1396 default:
1397 ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
1398 }
1399
1400 if (io_is_done) {
1401 if ((io->tgt_io.flags & OCS_CAM_IO_F_ABORT_NOTIFY) == 0) {
1402 ocs_target_io_free(io);
1403 }
1404 } else {
1405 io->tgt_io.state = OCS_CAM_IO_DATA_DONE;
1406 /*device_printf(ocs->dev, "%s: CTIO state=%d tag=%#x\n",
1407 __func__, io->tgt_io.state, io->tag);*/
1408 }
1409
1410 xpt_done(ccb);
1411
1412 return 0;
1413 }
1414
1415 /**
1416 * @note 1. Since the CCB is assigned to the ocs_io_t on an XPT_CONT_TARGET_IO
1417 * action, if an initiator aborts a command prior to the SIM receiving
1418 * a CTIO, the IO's CCB will be NULL.
1419 */
1420 static int32_t
1421 ocs_io_abort_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, uint32_t flags, void *arg)
1422 {
1423 struct ocs_softc *ocs = NULL;
1424 ocs_io_t *tmfio = arg;
1425 ocs_scsi_tmf_resp_e tmf_resp = OCS_SCSI_TMF_FUNCTION_COMPLETE;
1426 int32_t rc = 0;
1427
1428 ocs = io->ocs;
1429
1430 io->tgt_io.flags &= ~OCS_CAM_IO_F_ABORT_DEV;
1431
1432 /* A good status indicates the IO was aborted and will be completed in
1433 * the IO's completion handler. Handle the other cases here. */
1434 switch (scsi_status) {
1435 case OCS_SCSI_STATUS_GOOD:
1436 break;
1437 case OCS_SCSI_STATUS_NO_IO:
1438 break;
1439 default:
1440 device_printf(ocs->dev, "%s: unhandled status %d\n",
1441 __func__, scsi_status);
1442 tmf_resp = OCS_SCSI_TMF_FUNCTION_REJECTED;
1443 rc = -1;
1444 }
1445
1446 ocs_scsi_send_tmf_resp(tmfio, tmf_resp, NULL, ocs_target_tmf_cb, NULL);
1447
1448 return rc;
1449 }
1450
1451 /**
1452 * @ingroup cam_io
1453 * @brief Process initiator IO completions
1454 *
1455 * @param io
1456 * @param scsi_status did the IO complete successfully
1457 * @param rsp pointer to response buffer
1458 * @param flags
1459 * @param arg application specific pointer provided in the call to ocs_target_io()
1460 *
1461 * @todo
1462 */
1463 static int32_t ocs_scsi_initiator_io_cb(ocs_io_t *io,
1464 ocs_scsi_io_status_e scsi_status,
1465 ocs_scsi_cmd_resp_t *rsp,
1466 uint32_t flags, void *arg)
1467 {
1468 union ccb *ccb = arg;
1469 struct ccb_scsiio *csio = &ccb->csio;
1470 struct ocs_softc *ocs = csio->ccb_h.ccb_ocs_ptr;
1471 uint32_t cam_dir = ccb->ccb_h.flags & CAM_DIR_MASK;
1472 cam_status ccb_status= CAM_REQ_CMP_ERR;
1473
1474 if (CAM_DIR_NONE != cam_dir) {
1475 bus_dmasync_op_t op;
1476
1477 if (CAM_DIR_IN == cam_dir) {
1478 op = BUS_DMASYNC_POSTREAD;
1479 } else {
1480 op = BUS_DMASYNC_POSTWRITE;
1481 }
1482 /* Synchronize the DMA memory with the CPU and free the mapping */
1483 bus_dmamap_sync(ocs->buf_dmat, io->tgt_io.dmap, op);
1484 if (io->tgt_io.flags & OCS_CAM_IO_F_DMAPPED) {
1485 bus_dmamap_unload(ocs->buf_dmat, io->tgt_io.dmap);
1486 }
1487 }
1488
1489 if (scsi_status == OCS_SCSI_STATUS_CHECK_RESPONSE) {
1490 csio->scsi_status = rsp->scsi_status;
1491 if (SCSI_STATUS_OK != rsp->scsi_status)
1492 ccb_status = CAM_SCSI_STATUS_ERROR;
1493 else
1494 ccb_status = CAM_REQ_CMP;
1495
1496 csio->resid = rsp->residual;
1497
1498 /*
1499 * If we've already got a SCSI error, prefer that because it
1500 * will have more detail.
1501 */
1502 if ((rsp->residual < 0) && (ccb_status == CAM_REQ_CMP)) {
1503 ccb_status = CAM_DATA_RUN_ERR;
1504 }
1505
1506 if ((rsp->sense_data_length) &&
1507 !(ccb->ccb_h.flags & (CAM_SENSE_PHYS | CAM_SENSE_PTR))) {
1508 uint32_t sense_len = 0;
1509
1510 ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
1511 if (rsp->sense_data_length < csio->sense_len) {
1512 csio->sense_resid =
1513 csio->sense_len - rsp->sense_data_length;
1514 sense_len = rsp->sense_data_length;
1515 } else {
1516 csio->sense_resid = 0;
1517 sense_len = csio->sense_len;
1518 }
1519 ocs_memcpy(&csio->sense_data, rsp->sense_data, sense_len);
1520 }
1521 } else if (scsi_status != OCS_SCSI_STATUS_GOOD) {
1522 ccb_status = CAM_REQ_CMP_ERR;
1523 } else {
1524 ccb_status = CAM_REQ_CMP;
1525 }
1526
1527 ocs_set_ccb_status(ccb, ccb_status);
1528
1529 ocs_scsi_io_free(io);
1530
1531 csio->ccb_h.ccb_io_ptr = NULL;
1532 csio->ccb_h.ccb_ocs_ptr = NULL;
1533
1534 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1535
1536 if ((ccb_status != CAM_REQ_CMP) &&
1537 ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0)) {
1538 ccb->ccb_h.status |= CAM_DEV_QFRZN;
1539 xpt_freeze_devq(ccb->ccb_h.path, 1);
1540 }
1541
1542 xpt_done(ccb);
1543
1544 return 0;
1545 }
1546
1547 /**
1548 * @brief Load scatter-gather list entries into an IO
1549 *
1550 * This routine relies on the driver instance's software context pointer and
1551 * the IO object pointer having been already assigned to hooks in the CCB.
1552 * Although the routine does not return success/fail, callers can look at the
1553 * n_sge member to determine if the mapping failed (0 on failure).
1554 *
1555 * @param arg pointer to the CAM ccb for this IO
1556 * @param seg DMA address/length pairs
1557 * @param nseg number of DMA address/length pairs
1558 * @param error any errors while mapping the IO
1559 */
1560 static void
1561 ocs_scsi_dmamap_load(void *arg, bus_dma_segment_t *seg, int nseg, int error)
1562 {
1563 ocs_dmamap_load_arg_t *sglarg = (ocs_dmamap_load_arg_t*) arg;
1564
1565 if (error) {
1566 printf("%s: seg=%p nseg=%d error=%d\n",
1567 __func__, seg, nseg, error);
1568 sglarg->rc = -1;
1569 } else {
1570 uint32_t i = 0;
1571 uint32_t c = 0;
1572
1573 if ((sglarg->sgl_count + nseg) > sglarg->sgl_max) {
1574 printf("%s: sgl_count=%d nseg=%d max=%d\n", __func__,
1575 sglarg->sgl_count, nseg, sglarg->sgl_max);
1576 sglarg->rc = -2;
1577 return;
1578 }
1579
1580 for (i = 0, c = sglarg->sgl_count; i < nseg; i++, c++) {
1581 sglarg->sgl[c].addr = seg[i].ds_addr;
1582 sglarg->sgl[c].len = seg[i].ds_len;
1583 }
1584
1585 sglarg->sgl_count = c;
1586
1587 sglarg->rc = 0;
1588 }
1589 }
1590
1591 /**
1592 * @brief Build a scatter-gather list from a CAM CCB
1593 *
1594 * @param ocs the driver instance's software context
1595 * @param ccb pointer to the CCB
1596 * @param io pointer to the previously allocated IO object
1597 * @param sgl pointer to SGL
1598 * @param sgl_max number of entries in sgl
1599 *
1600 * @return 0 on success, non-zero otherwise
1601 */
1602 static int32_t
1603 ocs_build_scsi_sgl(struct ocs_softc *ocs, union ccb *ccb, ocs_io_t *io,
1604 ocs_scsi_sgl_t *sgl, uint32_t sgl_max)
1605 {
1606 ocs_dmamap_load_arg_t dmaarg;
1607 int32_t err = 0;
1608
1609 if (!ocs || !ccb || !io || !sgl) {
1610 printf("%s: bad param o=%p c=%p i=%p s=%p\n", __func__,
1611 ocs, ccb, io, sgl);
1612 return -1;
1613 }
1614
1615 io->tgt_io.flags &= ~OCS_CAM_IO_F_DMAPPED;
1616
1617 dmaarg.sgl = sgl;
1618 dmaarg.sgl_count = 0;
1619 dmaarg.sgl_max = sgl_max;
1620 dmaarg.rc = 0;
1621
1622 err = bus_dmamap_load_ccb(ocs->buf_dmat, io->tgt_io.dmap, ccb,
1623 ocs_scsi_dmamap_load, &dmaarg, 0);
1624
1625 if (err || dmaarg.rc) {
1626 device_printf(
1627 ocs->dev, "%s: bus_dmamap_load_ccb error (%d %d)\n",
1628 __func__, err, dmaarg.rc);
1629 return -1;
1630 }
1631
1632 io->tgt_io.flags |= OCS_CAM_IO_F_DMAPPED;
1633 return dmaarg.sgl_count;
1634 }
1635
1636 /**
1637 * @ingroup cam_io
1638 * @brief Send a target IO
1639 *
1640 * @param ocs the driver instance's software context
1641 * @param ccb pointer to the CCB
1642 *
1643 * @return 0 on success, non-zero otherwise
1644 */
1645 static int32_t
1646 ocs_target_io(struct ocs_softc *ocs, union ccb *ccb)
1647 {
1648 struct ccb_scsiio *csio = &ccb->csio;
1649 ocs_io_t *io = NULL;
1650 uint32_t cam_dir = ccb->ccb_h.flags & CAM_DIR_MASK;
1651 bool sendstatus = ccb->ccb_h.flags & CAM_SEND_STATUS;
1652 uint32_t xferlen = csio->dxfer_len;
1653 int32_t rc = 0;
1654
1655 io = ocs_scsi_find_io(ocs, csio->tag_id);
1656 if (io == NULL) {
1657 ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
1658 panic("bad tag value");
1659 return 1;
1660 }
1661
1662 /* Received an ABORT TASK for this IO */
1663 if (io->tgt_io.flags & OCS_CAM_IO_F_ABORT_RECV) {
1664 /*device_printf(ocs->dev,
1665 "%s: XPT_CONT_TARGET_IO state=%d tag=%#x xid=%#x flags=%#x\n",
1666 __func__, io->tgt_io.state, io->tag, io->init_task_tag,
1667 io->tgt_io.flags);*/
1668 io->tgt_io.flags |= OCS_CAM_IO_F_ABORT_CAM;
1669
1670 if (ccb->ccb_h.flags & CAM_SEND_STATUS) {
1671 ocs_set_ccb_status(ccb, CAM_REQ_CMP);
1672 ocs_target_io_free(io);
1673 return 1;
1674 }
1675
1676 ocs_set_ccb_status(ccb, CAM_REQ_ABORTED);
1677
1678 return 1;
1679 }
1680
1681 io->tgt_io.app = ccb;
1682
1683 ocs_set_ccb_status(ccb, CAM_REQ_INPROG);
1684 ccb->ccb_h.status |= CAM_SIM_QUEUED;
1685
1686 csio->ccb_h.ccb_ocs_ptr = ocs;
1687 csio->ccb_h.ccb_io_ptr = io;
1688
1689 if ((sendstatus && (xferlen == 0))) {
1690 ocs_scsi_cmd_resp_t resp = { 0 };
1691
1692 ocs_assert(ccb->ccb_h.flags & CAM_SEND_STATUS, -1);
1693
1694 io->tgt_io.state = OCS_CAM_IO_RESP;
1695
1696 resp.scsi_status = csio->scsi_status;
1697
1698 if (ccb->ccb_h.flags & CAM_SEND_SENSE) {
1699 resp.sense_data = (uint8_t *)&csio->sense_data;
1700 resp.sense_data_length = csio->sense_len;
1701 }
1702
1703 resp.residual = io->exp_xfer_len - io->transferred;
1704 rc = ocs_scsi_send_resp(io, 0, &resp, ocs_scsi_target_io_cb, ccb);
1705
1706 } else if (xferlen != 0) {
1707 ocs_scsi_sgl_t *sgl;
1708 int32_t sgl_count = 0;
1709
1710 io->tgt_io.state = OCS_CAM_IO_DATA;
1711
1712 if (sendstatus)
1713 io->tgt_io.sendresp = 1;
1714
1715 sgl = io->sgl;
1716
1717 sgl_count = ocs_build_scsi_sgl(ocs, ccb, io, sgl, io->sgl_allocated);
1718 if (sgl_count > 0) {
1719 if (cam_dir == CAM_DIR_IN) {
1720 rc = ocs_scsi_send_rd_data(io, 0, NULL, sgl,
1721 sgl_count, csio->dxfer_len,
1722 ocs_scsi_target_io_cb, ccb);
1723 } else if (cam_dir == CAM_DIR_OUT) {
1724 rc = ocs_scsi_recv_wr_data(io, 0, NULL, sgl,
1725 sgl_count, csio->dxfer_len,
1726 ocs_scsi_target_io_cb, ccb);
1727 } else {
1728 device_printf(ocs->dev, "%s:"
1729 " unknown CAM direction %#x\n",
1730 __func__, cam_dir);
1731 ocs_set_ccb_status(ccb, CAM_REQ_INVALID);
1732 rc = 1;
1733 }
1734 } else {
1735 device_printf(ocs->dev, "%s: building SGL failed\n",
1736 __func__);
1737 ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
1738 rc = 1;
1739 }
1740 } else {
1741 device_printf(ocs->dev, "%s: Wrong value xfer and sendstatus"
1742 " are 0 \n", __func__);
1743 ocs_set_ccb_status(ccb, CAM_REQ_INVALID);
1744 rc = 1;
1745 }
1746
1747 if (rc) {
1748 ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
1749 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
1750 io->tgt_io.state = OCS_CAM_IO_DATA_DONE;
1751 device_printf(ocs->dev, "%s: CTIO state=%d tag=%#x\n",
1752 __func__, io->tgt_io.state, io->tag);
1753 if ((sendstatus && (xferlen == 0))) {
1754 ocs_target_io_free(io);
1755 }
1756 }
1757
1758 return rc;
1759 }
1760
1761 static int32_t
1762 ocs_target_tmf_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, uint32_t flags,
1763 void *arg)
1764 {
1765
1766 /*device_printf(io->ocs->dev, "%s: tag=%x io=%p s=%#x\n",
1767 __func__, io->tag, io, scsi_status);*/
1768 ocs_scsi_io_complete(io);
1769
1770 return 0;
1771 }
1772
1773 /**
1774 * @ingroup cam_io
1775 * @brief Send an initiator IO
1776 *
1777 * @param ocs the driver instance's software context
1778 * @param ccb pointer to the CCB
1779 *
1780 * @return 0 on success, non-zero otherwise
1781 */
1782 static int32_t
1783 ocs_initiator_io(struct ocs_softc *ocs, union ccb *ccb)
1784 {
1785 int32_t rc;
1786 struct ccb_scsiio *csio = &ccb->csio;
1787 struct ccb_hdr *ccb_h = &csio->ccb_h;
1788 ocs_node_t *node = NULL;
1789 ocs_io_t *io = NULL;
1790 ocs_scsi_sgl_t *sgl;
1791 int32_t flags, sgl_count;
1792 ocs_fcport *fcp;
1793
1794 fcp = FCPORT(ocs, cam_sim_bus(xpt_path_sim((ccb)->ccb_h.path)));
1795
1796 if (fcp->tgt[ccb_h->target_id].state == OCS_TGT_STATE_LOST) {
1797 device_printf(ocs->dev, "%s: device LOST %d\n", __func__,
1798 ccb_h->target_id);
1799 return CAM_REQUEUE_REQ;
1800 }
1801
1802 if (fcp->tgt[ccb_h->target_id].state == OCS_TGT_STATE_NONE) {
1803 device_printf(ocs->dev, "%s: device not ready %d\n", __func__,
1804 ccb_h->target_id);
1805 return CAM_SEL_TIMEOUT;
1806 }
1807
1808 node = ocs_node_get_instance(ocs, fcp->tgt[ccb_h->target_id].node_id);
1809 if (node == NULL) {
1810 device_printf(ocs->dev, "%s: no device %d\n", __func__,
1811 ccb_h->target_id);
1812 return CAM_SEL_TIMEOUT;
1813 }
1814
1815 if (!node->targ) {
1816 device_printf(ocs->dev, "%s: not target device %d\n", __func__,
1817 ccb_h->target_id);
1818 return CAM_SEL_TIMEOUT;
1819 }
1820
1821 io = ocs_scsi_io_alloc(node, OCS_SCSI_IO_ROLE_ORIGINATOR);
1822 if (io == NULL) {
1823 device_printf(ocs->dev, "%s: unable to alloc IO\n", __func__);
1824 return -1;
1825 }
1826
1827 /* eventhough this is INI, use target structure as ocs_build_scsi_sgl
1828 * only references the tgt_io part of an ocs_io_t */
1829 io->tgt_io.app = ccb;
1830
1831 csio->ccb_h.ccb_ocs_ptr = ocs;
1832 csio->ccb_h.ccb_io_ptr = io;
1833 sgl = io->sgl;
1834
1835 sgl_count = ocs_build_scsi_sgl(ocs, ccb, io, sgl, io->sgl_allocated);
1836 if (sgl_count < 0) {
1837 ocs_scsi_io_free(io);
1838 device_printf(ocs->dev, "%s: building SGL failed\n", __func__);
1839 return -1;
1840 }
1841
1842 if (ccb->ccb_h.timeout == CAM_TIME_INFINITY) {
1843 io->timeout = 0;
1844 } else if (ccb->ccb_h.timeout == CAM_TIME_DEFAULT) {
1845 io->timeout = OCS_CAM_IO_TIMEOUT;
1846 } else {
1847 io->timeout = ccb->ccb_h.timeout;
1848 }
1849
1850 switch (csio->tag_action) {
1851 case MSG_HEAD_OF_Q_TAG:
1852 flags = OCS_SCSI_CMD_HEAD_OF_QUEUE;
1853 break;
1854 case MSG_ORDERED_Q_TAG:
1855 flags = OCS_SCSI_CMD_ORDERED;
1856 break;
1857 case MSG_ACA_TASK:
1858 flags = OCS_SCSI_CMD_ACA;
1859 break;
1860 case CAM_TAG_ACTION_NONE:
1861 case MSG_SIMPLE_Q_TAG:
1862 default:
1863 flags = OCS_SCSI_CMD_SIMPLE;
1864 break;
1865 }
1866 flags |= (csio->priority << OCS_SCSI_PRIORITY_SHIFT) &
1867 OCS_SCSI_PRIORITY_MASK;
1868
1869 switch (ccb->ccb_h.flags & CAM_DIR_MASK) {
1870 case CAM_DIR_NONE:
1871 rc = ocs_scsi_send_nodata_io(node, io, ccb_h->target_lun,
1872 ccb->ccb_h.flags & CAM_CDB_POINTER ?
1873 csio->cdb_io.cdb_ptr: csio->cdb_io.cdb_bytes,
1874 csio->cdb_len,
1875 ocs_scsi_initiator_io_cb, ccb, flags);
1876 break;
1877 case CAM_DIR_IN:
1878 rc = ocs_scsi_send_rd_io(node, io, ccb_h->target_lun,
1879 ccb->ccb_h.flags & CAM_CDB_POINTER ?
1880 csio->cdb_io.cdb_ptr: csio->cdb_io.cdb_bytes,
1881 csio->cdb_len,
1882 NULL,
1883 sgl, sgl_count, csio->dxfer_len,
1884 ocs_scsi_initiator_io_cb, ccb, flags);
1885 break;
1886 case CAM_DIR_OUT:
1887 rc = ocs_scsi_send_wr_io(node, io, ccb_h->target_lun,
1888 ccb->ccb_h.flags & CAM_CDB_POINTER ?
1889 csio->cdb_io.cdb_ptr: csio->cdb_io.cdb_bytes,
1890 csio->cdb_len,
1891 NULL,
1892 sgl, sgl_count, csio->dxfer_len,
1893 ocs_scsi_initiator_io_cb, ccb, flags);
1894 break;
1895 default:
1896 panic("%s invalid data direction %08x\n", __func__,
1897 ccb->ccb_h.flags);
1898 break;
1899 }
1900
1901 return rc;
1902 }
1903
1904 static uint32_t
1905 ocs_fcp_change_role(struct ocs_softc *ocs, ocs_fcport *fcp, uint32_t new_role)
1906 {
1907
1908 uint32_t rc = 0, was = 0, i = 0;
1909 ocs_vport_spec_t *vport = fcp->vport;
1910
1911 for (was = 0, i = 0; i < (ocs->num_vports + 1); i++) {
1912 if (FCPORT(ocs, i)->role != KNOB_ROLE_NONE)
1913 was++;
1914 }
1915
1916 // Physical port
1917 if ((was == 0) || (vport == NULL)) {
1918 fcp->role = new_role;
1919 if (vport == NULL) {
1920 ocs->enable_ini = (new_role & KNOB_ROLE_INITIATOR)? 1:0;
1921 ocs->enable_tgt = (new_role & KNOB_ROLE_TARGET)? 1:0;
1922 } else {
1923 vport->enable_ini = (new_role & KNOB_ROLE_INITIATOR)? 1:0;
1924 vport->enable_tgt = (new_role & KNOB_ROLE_TARGET)? 1:0;
1925 }
1926
1927 rc = ocs_xport_control(ocs->xport, OCS_XPORT_PORT_OFFLINE);
1928 if (rc) {
1929 ocs_log_debug(ocs, "port offline failed : %d\n", rc);
1930 }
1931
1932 rc = ocs_xport_control(ocs->xport, OCS_XPORT_PORT_ONLINE);
1933 if (rc) {
1934 ocs_log_debug(ocs, "port online failed : %d\n", rc);
1935 }
1936
1937 return 0;
1938 }
1939
1940 if ((fcp->role != KNOB_ROLE_NONE)){
1941 fcp->role = new_role;
1942 vport->enable_ini = (new_role & KNOB_ROLE_INITIATOR)? 1:0;
1943 vport->enable_tgt = (new_role & KNOB_ROLE_TARGET)? 1:0;
1944 /* New Sport will be created in sport deleted cb */
1945 return ocs_sport_vport_del(ocs, ocs->domain, vport->wwpn, vport->wwnn);
1946 }
1947
1948 fcp->role = new_role;
1949
1950 vport->enable_ini = (new_role & KNOB_ROLE_INITIATOR)? 1:0;
1951 vport->enable_tgt = (new_role & KNOB_ROLE_TARGET)? 1:0;
1952
1953 if (fcp->role != KNOB_ROLE_NONE) {
1954 return ocs_sport_vport_alloc(ocs->domain, vport);
1955 }
1956
1957 return (0);
1958 }
1959
1960 /**
1961 * @ingroup cam_api
1962 * @brief Process CAM actions
1963 *
1964 * The driver supplies this routine to the CAM during intialization and
1965 * is the main entry point for processing CAM Control Blocks (CCB)
1966 *
1967 * @param sim pointer to the SCSI Interface Module
1968 * @param ccb CAM control block
1969 *
1970 * @todo
1971 * - populate path inquiry data via info retrieved from SLI port
1972 */
1973 static void
1974 ocs_action(struct cam_sim *sim, union ccb *ccb)
1975 {
1976 struct ocs_softc *ocs = (struct ocs_softc *)cam_sim_softc(sim);
1977 struct ccb_hdr *ccb_h = &ccb->ccb_h;
1978
1979 int32_t rc, bus;
1980 bus = cam_sim_bus(sim);
1981
1982 switch (ccb_h->func_code) {
1983 case XPT_SCSI_IO:
1984
1985 if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) {
1986 if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) {
1987 ccb->ccb_h.status = CAM_REQ_INVALID;
1988 xpt_done(ccb);
1989 break;
1990 }
1991 }
1992
1993 rc = ocs_initiator_io(ocs, ccb);
1994 if (0 == rc) {
1995 ocs_set_ccb_status(ccb, CAM_REQ_INPROG | CAM_SIM_QUEUED);
1996 break;
1997 } else {
1998 if (rc == CAM_REQUEUE_REQ) {
1999 cam_freeze_devq(ccb->ccb_h.path);
2000 cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 100, 0);
2001 ccb->ccb_h.status = CAM_REQUEUE_REQ;
2002 xpt_done(ccb);
2003 break;
2004 }
2005
2006 ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
2007 if (rc > 0) {
2008 ocs_set_ccb_status(ccb, rc);
2009 } else {
2010 ocs_set_ccb_status(ccb, CAM_SEL_TIMEOUT);
2011 }
2012 }
2013 xpt_done(ccb);
2014 break;
2015 case XPT_PATH_INQ:
2016 {
2017 struct ccb_pathinq *cpi = &ccb->cpi;
2018 struct ccb_pathinq_settings_fc *fc = &cpi->xport_specific.fc;
2019 ocs_fcport *fcp = FCPORT(ocs, bus);
2020
2021 uint64_t wwn = 0;
2022 ocs_xport_stats_t value;
2023
2024 cpi->version_num = 1;
2025
2026 cpi->protocol = PROTO_SCSI;
2027 cpi->protocol_version = SCSI_REV_SPC;
2028
2029 if (ocs->ocs_xport == OCS_XPORT_FC) {
2030 cpi->transport = XPORT_FC;
2031 } else {
2032 cpi->transport = XPORT_UNKNOWN;
2033 }
2034
2035 cpi->transport_version = 0;
2036
2037 /* Set the transport parameters of the SIM */
2038 ocs_xport_status(ocs->xport, OCS_XPORT_LINK_SPEED, &value);
2039 fc->bitrate = value.value * 1000; /* speed in Mbps */
2040
2041 wwn = *((uint64_t *)ocs_scsi_get_property_ptr(ocs, OCS_SCSI_WWPN));
2042 fc->wwpn = be64toh(wwn);
2043
2044 wwn = *((uint64_t *)ocs_scsi_get_property_ptr(ocs, OCS_SCSI_WWNN));
2045 fc->wwnn = be64toh(wwn);
2046
2047 fc->port = fcp->fc_id;
2048
2049 if (ocs->config_tgt) {
2050 cpi->target_sprt =
2051 PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO;
2052 }
2053
2054 cpi->hba_misc = PIM_NOBUSRESET | PIM_UNMAPPED;
2055 cpi->hba_misc |= PIM_EXTLUNS | PIM_NOSCAN;
2056
2057 cpi->hba_inquiry = PI_TAG_ABLE;
2058 cpi->max_target = OCS_MAX_TARGETS;
2059 cpi->initiator_id = ocs->max_remote_nodes + 1;
2060
2061 if (!ocs->enable_ini) {
2062 cpi->hba_misc |= PIM_NOINITIATOR;
2063 }
2064
2065 cpi->max_lun = OCS_MAX_LUN;
2066 cpi->bus_id = cam_sim_bus(sim);
2067
2068 /* Need to supply a base transfer speed prior to linking up
2069 * Worst case, this would be FC 1Gbps */
2070 cpi->base_transfer_speed = 1 * 1000 * 1000;
2071
2072 /* Calculate the max IO supported
2073 * Worst case would be an OS page per SGL entry */
2074
2075 cpi->maxio = PAGE_SIZE *
2076 (ocs_scsi_get_property(ocs, OCS_SCSI_MAX_SGL) - 1);
2077
2078 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
2079 strncpy(cpi->hba_vid, "Emulex", HBA_IDLEN);
2080 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
2081 cpi->unit_number = cam_sim_unit(sim);
2082
2083 cpi->ccb_h.status = CAM_REQ_CMP;
2084 xpt_done(ccb);
2085 break;
2086 }
2087 case XPT_GET_TRAN_SETTINGS:
2088 {
2089 struct ccb_trans_settings *cts = &ccb->cts;
2090 struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi;
2091 struct ccb_trans_settings_fc *fc = &cts->xport_specific.fc;
2092 ocs_xport_stats_t value;
2093 ocs_fcport *fcp = FCPORT(ocs, bus);
2094 ocs_fc_target_t *tgt = NULL;
2095
2096 if (ocs->ocs_xport != OCS_XPORT_FC) {
2097 ocs_set_ccb_status(ccb, CAM_REQ_INVALID);
2098 xpt_done(ccb);
2099 break;
2100 }
2101
2102 if (cts->ccb_h.target_id > OCS_MAX_TARGETS) {
2103 ocs_set_ccb_status(ccb, CAM_DEV_NOT_THERE);
2104 xpt_done(ccb);
2105 break;
2106 }
2107
2108 tgt = &fcp->tgt[cts->ccb_h.target_id];
2109 if (tgt->state == OCS_TGT_STATE_NONE) {
2110 ocs_set_ccb_status(ccb, CAM_DEV_NOT_THERE);
2111 xpt_done(ccb);
2112 break;
2113 }
2114
2115 cts->protocol = PROTO_SCSI;
2116 cts->protocol_version = SCSI_REV_SPC2;
2117 cts->transport = XPORT_FC;
2118 cts->transport_version = 2;
2119
2120 scsi->valid = CTS_SCSI_VALID_TQ;
2121 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
2122
2123 /* speed in Mbps */
2124 ocs_xport_status(ocs->xport, OCS_XPORT_LINK_SPEED, &value);
2125 fc->bitrate = value.value * 100;
2126
2127 fc->wwpn = tgt->wwpn;
2128
2129 fc->wwnn = tgt->wwnn;
2130
2131 fc->port = tgt->port_id;
2132
2133 fc->valid = CTS_FC_VALID_SPEED |
2134 CTS_FC_VALID_WWPN |
2135 CTS_FC_VALID_WWNN |
2136 CTS_FC_VALID_PORT;
2137
2138 ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2139 xpt_done(ccb);
2140 break;
2141 }
2142 case XPT_SET_TRAN_SETTINGS:
2143 ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2144 xpt_done(ccb);
2145 break;
2146
2147 case XPT_CALC_GEOMETRY:
2148 cam_calc_geometry(&ccb->ccg, TRUE);
2149 xpt_done(ccb);
2150 break;
2151
2152 case XPT_GET_SIM_KNOB:
2153 {
2154 struct ccb_sim_knob *knob = &ccb->knob;
2155 uint64_t wwn = 0;
2156 ocs_fcport *fcp = FCPORT(ocs, bus);
2157
2158 if (ocs->ocs_xport != OCS_XPORT_FC) {
2159 ocs_set_ccb_status(ccb, CAM_REQ_INVALID);
2160 xpt_done(ccb);
2161 break;
2162 }
2163
2164 if (bus == 0) {
2165 wwn = *((uint64_t *)ocs_scsi_get_property_ptr(ocs,
2166 OCS_SCSI_WWNN));
2167 knob->xport_specific.fc.wwnn = be64toh(wwn);
2168
2169 wwn = *((uint64_t *)ocs_scsi_get_property_ptr(ocs,
2170 OCS_SCSI_WWPN));
2171 knob->xport_specific.fc.wwpn = be64toh(wwn);
2172 } else {
2173 knob->xport_specific.fc.wwnn = fcp->vport->wwnn;
2174 knob->xport_specific.fc.wwpn = fcp->vport->wwpn;
2175 }
2176
2177 knob->xport_specific.fc.role = fcp->role;
2178 knob->xport_specific.fc.valid = KNOB_VALID_ADDRESS |
2179 KNOB_VALID_ROLE;
2180
2181 ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2182 xpt_done(ccb);
2183 break;
2184 }
2185 case XPT_SET_SIM_KNOB:
2186 {
2187 struct ccb_sim_knob *knob = &ccb->knob;
2188 bool role_changed = FALSE;
2189 ocs_fcport *fcp = FCPORT(ocs, bus);
2190
2191 if (ocs->ocs_xport != OCS_XPORT_FC) {
2192 ocs_set_ccb_status(ccb, CAM_REQ_INVALID);
2193 xpt_done(ccb);
2194 break;
2195 }
2196
2197 if (knob->xport_specific.fc.valid & KNOB_VALID_ADDRESS) {
2198 device_printf(ocs->dev,
2199 "%s: XPT_SET_SIM_KNOB wwnn=%llx wwpn=%llx\n",
2200 __func__,
2201 (unsigned long long)knob->xport_specific.fc.wwnn,
2202 (unsigned long long)knob->xport_specific.fc.wwpn);
2203 }
2204
2205 if (knob->xport_specific.fc.valid & KNOB_VALID_ROLE) {
2206 switch (knob->xport_specific.fc.role) {
2207 case KNOB_ROLE_NONE:
2208 if (fcp->role != KNOB_ROLE_NONE) {
2209 role_changed = TRUE;
2210 }
2211 break;
2212 case KNOB_ROLE_TARGET:
2213 if (fcp->role != KNOB_ROLE_TARGET) {
2214 role_changed = TRUE;
2215 }
2216 break;
2217 case KNOB_ROLE_INITIATOR:
2218 if (fcp->role != KNOB_ROLE_INITIATOR) {
2219 role_changed = TRUE;
2220 }
2221 break;
2222 case KNOB_ROLE_BOTH:
2223 if (fcp->role != KNOB_ROLE_BOTH) {
2224 role_changed = TRUE;
2225 }
2226 break;
2227 default:
2228 device_printf(ocs->dev,
2229 "%s: XPT_SET_SIM_KNOB unsupported role: %d\n",
2230 __func__, knob->xport_specific.fc.role);
2231 }
2232
2233 if (role_changed) {
2234 device_printf(ocs->dev,
2235 "BUS:%d XPT_SET_SIM_KNOB old_role: %d new_role: %d\n",
2236 bus, fcp->role, knob->xport_specific.fc.role);
2237
2238 ocs_fcp_change_role(ocs, fcp, knob->xport_specific.fc.role);
2239 }
2240 }
2241
2242
2243
2244 ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2245 xpt_done(ccb);
2246 break;
2247 }
2248 case XPT_ABORT:
2249 {
2250 union ccb *accb = ccb->cab.abort_ccb;
2251
2252 switch (accb->ccb_h.func_code) {
2253 case XPT_ACCEPT_TARGET_IO:
2254 ocs_abort_atio(ocs, ccb);
2255 break;
2256 case XPT_IMMEDIATE_NOTIFY:
2257 ocs_abort_inot(ocs, ccb);
2258 break;
2259 case XPT_SCSI_IO:
2260 rc = ocs_abort_initiator_io(ocs, accb);
2261 if (rc) {
2262 ccb->ccb_h.status = CAM_UA_ABORT;
2263 } else {
2264 ccb->ccb_h.status = CAM_REQ_CMP;
2265 }
2266
2267 break;
2268 default:
2269 printf("abort of unknown func %#x\n",
2270 accb->ccb_h.func_code);
2271 ccb->ccb_h.status = CAM_REQ_INVALID;
2272 break;
2273 }
2274 break;
2275 }
2276 case XPT_RESET_BUS:
2277 if (ocs_xport_control(ocs->xport, OCS_XPORT_PORT_OFFLINE) == 0) {
2278 rc = ocs_xport_control(ocs->xport, OCS_XPORT_PORT_ONLINE);
2279 if (rc) {
2280 ocs_log_debug(ocs, "Failed to bring port online"
2281 " : %d\n", rc);
2282 }
2283 ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2284 } else {
2285 ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
2286 }
2287 xpt_done(ccb);
2288 break;
2289 case XPT_RESET_DEV:
2290 {
2291 ocs_node_t *node = NULL;
2292 ocs_io_t *io = NULL;
2293 int32_t rc = 0;
2294 ocs_fcport *fcp = FCPORT(ocs, bus);
2295
2296 node = ocs_node_get_instance(ocs, fcp->tgt[ccb_h->target_id].node_id);
2297 if (node == NULL) {
2298 device_printf(ocs->dev, "%s: no device %d\n",
2299 __func__, ccb_h->target_id);
2300 ocs_set_ccb_status(ccb, CAM_DEV_NOT_THERE);
2301 xpt_done(ccb);
2302 break;
2303 }
2304
2305 io = ocs_scsi_io_alloc(node, OCS_SCSI_IO_ROLE_ORIGINATOR);
2306 if (io == NULL) {
2307 device_printf(ocs->dev, "%s: unable to alloc IO\n",
2308 __func__);
2309 ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
2310 xpt_done(ccb);
2311 break;
2312 }
2313
2314 rc = ocs_scsi_send_tmf(node, io, NULL, ccb_h->target_lun,
2315 OCS_SCSI_TMF_LOGICAL_UNIT_RESET,
2316 NULL, 0, 0, /* sgl, sgl_count, length */
2317 ocs_initiator_tmf_cb, NULL/*arg*/);
2318
2319 if (rc) {
2320 ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
2321 } else {
2322 ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2323 }
2324
2325 if (node->fcp2device) {
2326 ocs_reset_crn(node, ccb_h->target_lun);
2327 }
2328
2329 xpt_done(ccb);
2330 break;
2331 }
2332 case XPT_EN_LUN: /* target support */
2333 {
2334 ocs_tgt_resource_t *trsrc = NULL;
2335 uint32_t status = 0;
2336 ocs_fcport *fcp = FCPORT(ocs, bus);
2337
2338 device_printf(ocs->dev, "XPT_EN_LUN %sable %d:%d\n",
2339 ccb->cel.enable ? "en" : "dis",
2340 ccb->ccb_h.target_id,
2341 (unsigned int)ccb->ccb_h.target_lun);
2342
2343 trsrc = ocs_tgt_resource_get(fcp, &ccb->ccb_h, &status);
2344 if (trsrc) {
2345 trsrc->enabled = ccb->cel.enable;
2346
2347 /* Abort all ATIO/INOT on LUN disable */
2348 if (trsrc->enabled == FALSE) {
2349 ocs_tgt_resource_abort(ocs, trsrc);
2350 } else {
2351 STAILQ_INIT(&trsrc->atio);
2352 STAILQ_INIT(&trsrc->inot);
2353 }
2354 status = CAM_REQ_CMP;
2355 }
2356
2357 ocs_set_ccb_status(ccb, status);
2358 xpt_done(ccb);
2359 break;
2360 }
2361 /*
2362 * The flow of target IOs in CAM is:
2363 * - CAM supplies a number of CCBs to the driver used for received
2364 * commands.
2365 * - when the driver receives a command, it copies the relevant
2366 * information to the CCB and returns it to the CAM using xpt_done()
2367 * - after the target server processes the request, it creates
2368 * a new CCB containing information on how to continue the IO and
2369 * passes that to the driver
2370 * - the driver processes the "continue IO" (a.k.a CTIO) CCB
2371 * - once the IO completes, the driver returns the CTIO to the CAM
2372 * using xpt_done()
2373 */
2374 case XPT_ACCEPT_TARGET_IO: /* used to inform upper layer of
2375 received CDB (a.k.a. ATIO) */
2376 case XPT_IMMEDIATE_NOTIFY: /* used to inform upper layer of other
2377 event (a.k.a. INOT) */
2378 {
2379 ocs_tgt_resource_t *trsrc = NULL;
2380 uint32_t status = 0;
2381 ocs_fcport *fcp = FCPORT(ocs, bus);
2382
2383 /*printf("XPT_%s %p\n", ccb_h->func_code == XPT_ACCEPT_TARGET_IO ?
2384 "ACCEPT_TARGET_IO" : "IMMEDIATE_NOTIFY", ccb);*/
2385 trsrc = ocs_tgt_resource_get(fcp, &ccb->ccb_h, &status);
2386 if (trsrc == NULL) {
2387 ocs_set_ccb_status(ccb, CAM_DEV_NOT_THERE);
2388 xpt_done(ccb);
2389 break;
2390 }
2391
2392 if (XPT_ACCEPT_TARGET_IO == ccb->ccb_h.func_code) {
2393 struct ccb_accept_tio *atio = NULL;
2394
2395 atio = (struct ccb_accept_tio *)ccb;
2396 atio->init_id = 0x0badbeef;
2397 atio->tag_id = 0xdeadc0de;
2398
2399 STAILQ_INSERT_TAIL(&trsrc->atio, &ccb->ccb_h,
2400 sim_links.stqe);
2401 } else {
2402 STAILQ_INSERT_TAIL(&trsrc->inot, &ccb->ccb_h,
2403 sim_links.stqe);
2404 }
2405 ccb->ccb_h.ccb_io_ptr = NULL;
2406 ccb->ccb_h.ccb_ocs_ptr = ocs;
2407 ocs_set_ccb_status(ccb, CAM_REQ_INPROG);
2408 /*
2409 * These actions give resources to the target driver.
2410 * If we didn't return here, this function would call
2411 * xpt_done(), signaling to the upper layers that an
2412 * IO or other event had arrived.
2413 */
2414 break;
2415 }
2416 case XPT_NOTIFY_ACKNOWLEDGE:
2417 {
2418 ocs_io_t *io = NULL;
2419 ocs_io_t *abortio = NULL;
2420
2421 /* Get the IO reference for this tag */
2422 io = ocs_scsi_find_io(ocs, ccb->cna2.tag_id);
2423 if (io == NULL) {
2424 device_printf(ocs->dev,
2425 "%s: XPT_NOTIFY_ACKNOWLEDGE no IO with tag %#x\n",
2426 __func__, ccb->cna2.tag_id);
2427 ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
2428 xpt_done(ccb);
2429 break;
2430 }
2431
2432 abortio = io->tgt_io.app;
2433 if (abortio) {
2434 abortio->tgt_io.flags &= ~OCS_CAM_IO_F_ABORT_NOTIFY;
2435 device_printf(ocs->dev,
2436 "%s: XPT_NOTIFY_ACK state=%d tag=%#x xid=%#x"
2437 " flags=%#x\n", __func__, abortio->tgt_io.state,
2438 abortio->tag, abortio->init_task_tag,
2439 abortio->tgt_io.flags);
2440 /* TMF response was sent in abort callback */
2441 } else {
2442 ocs_scsi_send_tmf_resp(io,
2443 OCS_SCSI_TMF_FUNCTION_COMPLETE,
2444 NULL, ocs_target_tmf_cb, NULL);
2445 }
2446
2447 ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2448 xpt_done(ccb);
2449 break;
2450 }
2451 case XPT_CONT_TARGET_IO: /* continue target IO, sending data/response (a.k.a. CTIO) */
2452 if (ocs_target_io(ocs, ccb)) {
2453 device_printf(ocs->dev,
2454 "XPT_CONT_TARGET_IO failed flags=%x tag=%#x\n",
2455 ccb->ccb_h.flags, ccb->csio.tag_id);
2456 xpt_done(ccb);
2457 }
2458 break;
2459 default:
2460 device_printf(ocs->dev, "unhandled func_code = %#x\n",
2461 ccb_h->func_code);
2462 ccb_h->status = CAM_REQ_INVALID;
2463 xpt_done(ccb);
2464 break;
2465 }
2466 }
2467
2468 /**
2469 * @ingroup cam_api
2470 * @brief Process events
2471 *
2472 * @param sim pointer to the SCSI Interface Module
2473 *
2474 */
2475 static void
2476 ocs_poll(struct cam_sim *sim)
2477 {
2478 printf("%s\n", __func__);
2479 }
2480
2481 static int32_t
2482 ocs_initiator_tmf_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status,
2483 ocs_scsi_cmd_resp_t *rsp, uint32_t flags, void *arg)
2484 {
2485 int32_t rc = 0;
2486
2487 switch (scsi_status) {
2488 case OCS_SCSI_STATUS_GOOD:
2489 case OCS_SCSI_STATUS_NO_IO:
2490 break;
2491 case OCS_SCSI_STATUS_CHECK_RESPONSE:
2492 if (rsp->response_data_length == 0) {
2493 ocs_log_test(io->ocs, "check response without data?!?\n");
2494 rc = -1;
2495 break;
2496 }
2497
2498 if (rsp->response_data[3] != 0) {
2499 ocs_log_test(io->ocs, "TMF status %08x\n",
2500 be32toh(*((uint32_t *)rsp->response_data)));
2501 rc = -1;
2502 break;
2503 }
2504 break;
2505 default:
2506 ocs_log_test(io->ocs, "status=%#x\n", scsi_status);
2507 rc = -1;
2508 }
2509
2510 ocs_scsi_io_free(io);
2511
2512 return rc;
2513 }
2514
2515 /**
2516 * @brief lookup target resource structure
2517 *
2518 * Arbitrarily support
2519 * - wildcard target ID + LU
2520 * - 0 target ID + non-wildcard LU
2521 *
2522 * @param ocs the driver instance's software context
2523 * @param ccb_h pointer to the CCB header
2524 * @param status returned status value
2525 *
2526 * @return pointer to the target resource, NULL if none available (e.g. if LU
2527 * is not enabled)
2528 */
2529 static ocs_tgt_resource_t *ocs_tgt_resource_get(ocs_fcport *fcp,
2530 struct ccb_hdr *ccb_h, uint32_t *status)
2531 {
2532 target_id_t tid = ccb_h->target_id;
2533 lun_id_t lun = ccb_h->target_lun;
2534
2535 if (CAM_TARGET_WILDCARD == tid) {
2536 if (CAM_LUN_WILDCARD != lun) {
2537 *status = CAM_LUN_INVALID;
2538 return NULL;
2539 }
2540 return &fcp->targ_rsrc_wildcard;
2541 } else {
2542 if (lun < OCS_MAX_LUN) {
2543 return &fcp->targ_rsrc[lun];
2544 } else {
2545 *status = CAM_LUN_INVALID;
2546 return NULL;
2547 }
2548 }
2549
2550 }
2551
2552 static int32_t
2553 ocs_tgt_resource_abort(struct ocs_softc *ocs, ocs_tgt_resource_t *trsrc)
2554 {
2555 union ccb *ccb = NULL;
2556
2557 do {
2558 ccb = (union ccb *)STAILQ_FIRST(&trsrc->atio);
2559 if (ccb) {
2560 STAILQ_REMOVE_HEAD(&trsrc->atio, sim_links.stqe);
2561 ccb->ccb_h.status = CAM_REQ_ABORTED;
2562 xpt_done(ccb);
2563 }
2564 } while (ccb);
2565
2566 do {
2567 ccb = (union ccb *)STAILQ_FIRST(&trsrc->inot);
2568 if (ccb) {
2569 STAILQ_REMOVE_HEAD(&trsrc->inot, sim_links.stqe);
2570 ccb->ccb_h.status = CAM_REQ_ABORTED;
2571 xpt_done(ccb);
2572 }
2573 } while (ccb);
2574
2575 return 0;
2576 }
2577
2578 static void
2579 ocs_abort_atio(struct ocs_softc *ocs, union ccb *ccb)
2580 {
2581
2582 ocs_io_t *aio = NULL;
2583 ocs_tgt_resource_t *trsrc = NULL;
2584 uint32_t status = CAM_REQ_INVALID;
2585 struct ccb_hdr *cur = NULL;
2586 union ccb *accb = ccb->cab.abort_ccb;
2587
2588 int bus = cam_sim_bus(xpt_path_sim((ccb)->ccb_h.path));
2589 ocs_fcport *fcp = FCPORT(ocs, bus);
2590
2591 trsrc = ocs_tgt_resource_get(fcp, &accb->ccb_h, &status);
2592 if (trsrc != NULL) {
2593 STAILQ_FOREACH(cur, &trsrc->atio, sim_links.stqe) {
2594 if (cur != &accb->ccb_h)
2595 continue;
2596
2597 STAILQ_REMOVE(&trsrc->atio, cur, ccb_hdr,
2598 sim_links.stqe);
2599 accb->ccb_h.status = CAM_REQ_ABORTED;
2600 xpt_done(accb);
2601 ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2602 return;
2603 }
2604 }
2605
2606 /* if the ATIO has a valid IO pointer, CAM is telling
2607 * the driver that the ATIO (which represents the entire
2608 * exchange) has been aborted. */
2609
2610 aio = accb->ccb_h.ccb_io_ptr;
2611 if (aio == NULL) {
2612 ccb->ccb_h.status = CAM_UA_ABORT;
2613 return;
2614 }
2615
2616 device_printf(ocs->dev,
2617 "%s: XPT_ABORT ATIO state=%d tag=%#x"
2618 " xid=%#x flags=%#x\n", __func__,
2619 aio->tgt_io.state, aio->tag,
2620 aio->init_task_tag, aio->tgt_io.flags);
2621 /* Expectations are:
2622 * - abort task was received
2623 * - already aborted IO in the DEVICE
2624 * - already received NOTIFY ACKNOWLEDGE */
2625
2626 if ((aio->tgt_io.flags & OCS_CAM_IO_F_ABORT_RECV) == 0) {
2627 device_printf(ocs->dev, "%s: abort not received or io completed \n", __func__);
2628 ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2629 return;
2630 }
2631
2632 aio->tgt_io.flags |= OCS_CAM_IO_F_ABORT_CAM;
2633 ocs_target_io_free(aio);
2634 ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2635
2636 return;
2637 }
2638
2639 static void
2640 ocs_abort_inot(struct ocs_softc *ocs, union ccb *ccb)
2641 {
2642 ocs_tgt_resource_t *trsrc = NULL;
2643 uint32_t status = CAM_REQ_INVALID;
2644 struct ccb_hdr *cur = NULL;
2645 union ccb *accb = ccb->cab.abort_ccb;
2646
2647 int bus = cam_sim_bus(xpt_path_sim((ccb)->ccb_h.path));
2648 ocs_fcport *fcp = FCPORT(ocs, bus);
2649
2650 trsrc = ocs_tgt_resource_get(fcp, &accb->ccb_h, &status);
2651 if (trsrc) {
2652 STAILQ_FOREACH(cur, &trsrc->inot, sim_links.stqe) {
2653 if (cur != &accb->ccb_h)
2654 continue;
2655
2656 STAILQ_REMOVE(&trsrc->inot, cur, ccb_hdr,
2657 sim_links.stqe);
2658 accb->ccb_h.status = CAM_REQ_ABORTED;
2659 xpt_done(accb);
2660 ocs_set_ccb_status(ccb, CAM_REQ_CMP);
2661 return;
2662 }
2663 }
2664
2665 ocs_set_ccb_status(ccb, CAM_UA_ABORT);
2666 return;
2667 }
2668
2669 static uint32_t
2670 ocs_abort_initiator_io(struct ocs_softc *ocs, union ccb *accb)
2671 {
2672
2673 ocs_node_t *node = NULL;
2674 ocs_io_t *io = NULL;
2675 int32_t rc = 0;
2676 struct ccb_scsiio *csio = &accb->csio;
2677
2678 ocs_fcport *fcp = FCPORT(ocs, cam_sim_bus(xpt_path_sim((accb)->ccb_h.path)));
2679 node = ocs_node_get_instance(ocs, fcp->tgt[accb->ccb_h.target_id].node_id);
2680 if (node == NULL) {
2681 device_printf(ocs->dev, "%s: no device %d\n",
2682 __func__, accb->ccb_h.target_id);
2683 ocs_set_ccb_status(accb, CAM_DEV_NOT_THERE);
2684 xpt_done(accb);
2685 return (-1);
2686 }
2687
2688 io = ocs_scsi_io_alloc(node, OCS_SCSI_IO_ROLE_ORIGINATOR);
2689 if (io == NULL) {
2690 device_printf(ocs->dev,
2691 "%s: unable to alloc IO\n", __func__);
2692 ocs_set_ccb_status(accb, CAM_REQ_CMP_ERR);
2693 xpt_done(accb);
2694 return (-1);
2695 }
2696
2697 rc = ocs_scsi_send_tmf(node, io,
2698 (ocs_io_t *)csio->ccb_h.ccb_io_ptr,
2699 accb->ccb_h.target_lun,
2700 OCS_SCSI_TMF_ABORT_TASK,
2701 NULL, 0, 0,
2702 ocs_initiator_tmf_cb, NULL/*arg*/);
2703
2704 return rc;
2705 }
2706
2707 void
2708 ocs_scsi_ini_ddump(ocs_textbuf_t *textbuf, ocs_scsi_ddump_type_e type, void *obj)
2709 {
2710 switch(type) {
2711 case OCS_SCSI_DDUMP_DEVICE: {
2712 //ocs_t *ocs = obj;
2713 break;
2714 }
2715 case OCS_SCSI_DDUMP_DOMAIN: {
2716 //ocs_domain_t *domain = obj;
2717 break;
2718 }
2719 case OCS_SCSI_DDUMP_SPORT: {
2720 //ocs_sport_t *sport = obj;
2721 break;
2722 }
2723 case OCS_SCSI_DDUMP_NODE: {
2724 //ocs_node_t *node = obj;
2725 break;
2726 }
2727 case OCS_SCSI_DDUMP_IO: {
2728 //ocs_io_t *io = obj;
2729 break;
2730 }
2731 default: {
2732 break;
2733 }
2734 }
2735 }
2736
2737 void
2738 ocs_scsi_tgt_ddump(ocs_textbuf_t *textbuf, ocs_scsi_ddump_type_e type, void *obj)
2739 {
2740 switch(type) {
2741 case OCS_SCSI_DDUMP_DEVICE: {
2742 //ocs_t *ocs = obj;
2743 break;
2744 }
2745 case OCS_SCSI_DDUMP_DOMAIN: {
2746 //ocs_domain_t *domain = obj;
2747 break;
2748 }
2749 case OCS_SCSI_DDUMP_SPORT: {
2750 //ocs_sport_t *sport = obj;
2751 break;
2752 }
2753 case OCS_SCSI_DDUMP_NODE: {
2754 //ocs_node_t *node = obj;
2755 break;
2756 }
2757 case OCS_SCSI_DDUMP_IO: {
2758 ocs_io_t *io = obj;
2759 char *state_str = NULL;
2760
2761 switch (io->tgt_io.state) {
2762 case OCS_CAM_IO_FREE:
2763 state_str = "FREE";
2764 break;
2765 case OCS_CAM_IO_COMMAND:
2766 state_str = "COMMAND";
2767 break;
2768 case OCS_CAM_IO_DATA:
2769 state_str = "DATA";
2770 break;
2771 case OCS_CAM_IO_DATA_DONE:
2772 state_str = "DATA_DONE";
2773 break;
2774 case OCS_CAM_IO_RESP:
2775 state_str = "RESP";
2776 break;
2777 default:
2778 state_str = "xxx BAD xxx";
2779 }
2780 ocs_ddump_value(textbuf, "cam_st", "%s", state_str);
2781 if (io->tgt_io.app) {
2782 ocs_ddump_value(textbuf, "cam_flags", "%#x",
2783 ((union ccb *)(io->tgt_io.app))->ccb_h.flags);
2784 ocs_ddump_value(textbuf, "cam_status", "%#x",
2785 ((union ccb *)(io->tgt_io.app))->ccb_h.status);
2786 }
2787
2788 break;
2789 }
2790 default: {
2791 break;
2792 }
2793 }
2794 }
2795
2796 int32_t ocs_scsi_get_block_vaddr(ocs_io_t *io, uint64_t blocknumber,
2797 ocs_scsi_vaddr_len_t addrlen[],
2798 uint32_t max_addrlen, void **dif_vaddr)
2799 {
2800 return -1;
2801 }
2802
2803 uint32_t
2804 ocs_get_crn(ocs_node_t *node, uint8_t *crn, uint64_t lun)
2805 {
2806 uint32_t idx;
2807 struct ocs_lun_crn *lcrn = NULL;
2808 idx = lun % OCS_MAX_LUN;
2809
2810 lcrn = node->ini_node.lun_crn[idx];
2811
2812 if (lcrn == NULL) {
2813 lcrn = ocs_malloc(node->ocs, sizeof(struct ocs_lun_crn),
2814 M_ZERO|M_NOWAIT);
2815 if (lcrn == NULL) {
2816 return (1);
2817 }
2818
2819 lcrn->lun = lun;
2820 node->ini_node.lun_crn[idx] = lcrn;
2821 }
2822
2823 if (lcrn->lun != lun) {
2824 return (1);
2825 }
2826
2827 if (lcrn->crnseed == 0)
2828 lcrn->crnseed = 1;
2829
2830 *crn = lcrn->crnseed++;
2831 return (0);
2832 }
2833
2834 void
2835 ocs_del_crn(ocs_node_t *node)
2836 {
2837 uint32_t i;
2838 struct ocs_lun_crn *lcrn = NULL;
2839
2840 for(i = 0; i < OCS_MAX_LUN; i++) {
2841 lcrn = node->ini_node.lun_crn[i];
2842 if (lcrn) {
2843 ocs_free(node->ocs, lcrn, sizeof(*lcrn));
2844 }
2845 }
2846
2847 return;
2848 }
2849
2850 void
2851 ocs_reset_crn(ocs_node_t *node, uint64_t lun)
2852 {
2853 uint32_t idx;
2854 struct ocs_lun_crn *lcrn = NULL;
2855 idx = lun % OCS_MAX_LUN;
2856
2857 lcrn = node->ini_node.lun_crn[idx];
2858 if (lcrn)
2859 lcrn->crnseed = 0;
2860
2861 return;
2862 }
Cache object: 3e6f0bd6a14c10a14cd0c81ad96229d1
|