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