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