1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /** 35 * \file 36 * SCSI to bdev translation layer 37 */ 38 39 #ifndef SPDK_SCSI_H 40 #define SPDK_SCSI_H 41 42 #include "spdk/stdinc.h" 43 44 #include "spdk/bdev.h" 45 #include "spdk/queue.h" 46 47 #ifdef __cplusplus 48 extern "C" { 49 #endif 50 51 /* Defines for SPDK tracing framework */ 52 #define OWNER_SCSI_DEV 0x10 53 #define OBJECT_SCSI_TASK 0x10 54 #define TRACE_GROUP_SCSI 0x2 55 #define TRACE_SCSI_TASK_DONE SPDK_TPOINT_ID(TRACE_GROUP_SCSI, 0x0) 56 #define TRACE_SCSI_TASK_START SPDK_TPOINT_ID(TRACE_GROUP_SCSI, 0x1) 57 58 #define SPDK_SCSI_MAX_DEVS 1024 59 #define SPDK_SCSI_DEV_MAX_PORTS 4 60 #define SPDK_SCSI_DEV_MAX_NAME 255 61 62 #define SPDK_SCSI_PORT_MAX_NAME_LENGTH 255 63 #define SPDK_SCSI_MAX_TRANSPORT_ID_LENGTH 255 64 65 enum spdk_scsi_data_dir { 66 SPDK_SCSI_DIR_NONE = 0, 67 SPDK_SCSI_DIR_TO_DEV = 1, 68 SPDK_SCSI_DIR_FROM_DEV = 2, 69 }; 70 71 enum spdk_scsi_task_func { 72 SPDK_SCSI_TASK_FUNC_ABORT_TASK = 0, 73 SPDK_SCSI_TASK_FUNC_ABORT_TASK_SET, 74 SPDK_SCSI_TASK_FUNC_CLEAR_TASK_SET, 75 SPDK_SCSI_TASK_FUNC_LUN_RESET, 76 }; 77 78 /* 79 * SAM does not define the value for these service responses. Each transport 80 * (i.e. SAS, FC, iSCSI) will map these value to transport-specific codes, 81 * and may add their own. 82 */ 83 enum spdk_scsi_task_mgmt_resp { 84 SPDK_SCSI_TASK_MGMT_RESP_COMPLETE, 85 SPDK_SCSI_TASK_MGMT_RESP_SUCCESS, 86 SPDK_SCSI_TASK_MGMT_RESP_REJECT, 87 SPDK_SCSI_TASK_MGMT_RESP_INVALID_LUN, 88 SPDK_SCSI_TASK_MGMT_RESP_TARGET_FAILURE, 89 SPDK_SCSI_TASK_MGMT_RESP_REJECT_FUNC_NOT_SUPPORTED 90 }; 91 92 struct spdk_scsi_task; 93 typedef void (*spdk_scsi_task_cpl)(struct spdk_scsi_task *task); 94 typedef void (*spdk_scsi_task_free)(struct spdk_scsi_task *task); 95 96 struct spdk_scsi_task { 97 uint8_t status; 98 uint8_t function; /* task mgmt function */ 99 uint8_t response; /* task mgmt response */ 100 101 struct spdk_scsi_lun *lun; 102 struct spdk_scsi_port *target_port; 103 struct spdk_scsi_port *initiator_port; 104 105 spdk_scsi_task_cpl cpl_fn; 106 spdk_scsi_task_free free_fn; 107 108 uint32_t ref; 109 uint32_t transfer_len; 110 uint32_t dxfer_dir; 111 uint32_t length; 112 113 /** 114 * Amount of data actually transferred. Can be less than requested 115 * transfer_len - i.e. SCSI INQUIRY. 116 */ 117 uint32_t data_transferred; 118 119 uint64_t offset; 120 121 uint8_t *cdb; 122 123 /** 124 * \internal 125 * Size of internal buffer or zero when iov.iov_base is not internally managed. 126 */ 127 uint32_t alloc_len; 128 /** 129 * \internal 130 * iov is internal buffer. Use iovs to access elements of IO. 131 */ 132 struct iovec iov; 133 struct iovec *iovs; 134 uint16_t iovcnt; 135 136 uint8_t sense_data[32]; 137 size_t sense_data_len; 138 139 void *bdev_io; 140 141 TAILQ_ENTRY(spdk_scsi_task) scsi_link; 142 143 uint32_t abort_id; 144 struct spdk_bdev_io_wait_entry bdev_io_wait; 145 }; 146 147 struct spdk_scsi_port; 148 struct spdk_scsi_dev; 149 struct spdk_scsi_lun; 150 struct spdk_scsi_lun_desc; 151 152 typedef void (*spdk_scsi_lun_remove_cb_t)(struct spdk_scsi_lun *, void *); 153 typedef void (*spdk_scsi_dev_destruct_cb_t)(void *cb_arg, int rc); 154 155 /** 156 * Initialize SCSI layer. 157 * 158 * \return 0 on success, -1 on failure. 159 */ 160 int spdk_scsi_init(void); 161 162 /** 163 * Stop and clean the SCSI layer. 164 */ 165 void spdk_scsi_fini(void); 166 167 /** 168 * Get the LUN id of the given logical unit. 169 * 170 * \param lun Logical unit. 171 * 172 * \return LUN id of the logical unit. 173 */ 174 int spdk_scsi_lun_get_id(const struct spdk_scsi_lun *lun); 175 176 /** 177 * Get the name of the bdev associated with the given logical unit. 178 * 179 * \param lun Logical unit. 180 * 181 * \return the name of the bdev associated with the logical unit. 182 */ 183 const char *spdk_scsi_lun_get_bdev_name(const struct spdk_scsi_lun *lun); 184 185 /** 186 * Get the SCSI device associated with the given logical unit. 187 * 188 * \param lun Logical unit. 189 * 190 * \return the SCSI device associated with the logical unit. 191 */ 192 const struct spdk_scsi_dev *spdk_scsi_lun_get_dev(const struct spdk_scsi_lun *lun); 193 194 /** 195 * Check if the logical unit is hot removing. 196 * 197 * \param lun Logical unit 198 * 199 * \return true if removing, false otherwise. 200 */ 201 bool spdk_scsi_lun_is_removing(const struct spdk_scsi_lun *lun); 202 203 /** 204 * Get the name of the given SCSI device. 205 * 206 * \param dev SCSI device. 207 * 208 * \return the name of the SCSI device on success, or NULL on failure. 209 */ 210 const char *spdk_scsi_dev_get_name(const struct spdk_scsi_dev *dev); 211 212 /** 213 * Get the id of the given SCSI device. 214 * 215 * \param dev SCSI device. 216 * 217 * \return the id of the SCSI device. 218 */ 219 int spdk_scsi_dev_get_id(const struct spdk_scsi_dev *dev); 220 221 /** 222 * Get the logical unit of the given SCSI device whose id is lun_id. 223 * 224 * \param dev SCSI device. 225 * \param lun_id Id of the logical unit. 226 * 227 * \return the logical unit on success, or NULL on failure. 228 */ 229 struct spdk_scsi_lun *spdk_scsi_dev_get_lun(struct spdk_scsi_dev *dev, int lun_id); 230 231 /** 232 * Get the first logical unit of the given SCSI device. 233 * 234 * \param dev SCSI device. 235 * 236 * \return the first logical unit on success, or NULL if there is no logical unit. 237 */ 238 struct spdk_scsi_lun *spdk_scsi_dev_get_first_lun(struct spdk_scsi_dev *dev); 239 240 /** 241 * Get the next logical unit of a SCSI device. 242 * 243 * \param lun Previous logical unit. 244 * 245 * \return the next logical unit of a SCSI device, or NULL if the prev_lun was the last. 246 */ 247 struct spdk_scsi_lun *spdk_scsi_dev_get_next_lun(struct spdk_scsi_lun *prev_lun); 248 249 /** 250 * Check whether the SCSI device has any pending task. 251 * 252 * \param dev SCSI device. 253 * \param initiator_port Check tasks only from the initiator if specified, or 254 * all all tasks otherwise. 255 * 256 * \return true if the SCSI device has any pending task, or false otherwise. 257 */ 258 bool spdk_scsi_dev_has_pending_tasks(const struct spdk_scsi_dev *dev, 259 const struct spdk_scsi_port *initiator_port); 260 261 /** 262 * Destruct the SCSI decice. 263 * 264 * \param dev SCSI device. 265 * \param cb_fn Callback function. 266 * \param cb_arg Argument to callback function. 267 */ 268 void spdk_scsi_dev_destruct(struct spdk_scsi_dev *dev, 269 spdk_scsi_dev_destruct_cb_t cb_fn, void *cb_arg); 270 271 /** 272 * Execute the SCSI management task. 273 * 274 * The task can be constructed by the function spdk_scsi_task_construct(). 275 * Code of task management function to be executed is set before calling this API. 276 * 277 * \param dev SCSI device. 278 * \param task SCSI task to be executed. 279 */ 280 void spdk_scsi_dev_queue_mgmt_task(struct spdk_scsi_dev *dev, struct spdk_scsi_task *task); 281 282 /** 283 * Execute the SCSI task. 284 * 285 * The task can be constructed by the function spdk_scsi_task_construct(). 286 * 287 * \param dev SCSI device. 288 * \param task Task to be executed. 289 */ 290 void spdk_scsi_dev_queue_task(struct spdk_scsi_dev *dev, struct spdk_scsi_task *task); 291 292 /** 293 * Add a new port to the given SCSI device. 294 * 295 * \param dev SCSI device. 296 * \param id Port id. 297 * \param name Port name. 298 * 299 * \return 0 on success, -1 on failure. 300 */ 301 int spdk_scsi_dev_add_port(struct spdk_scsi_dev *dev, uint64_t id, const char *name); 302 303 /** 304 * Delete a specified port of the given SCSI device. 305 * 306 * \param dev SCSI device. 307 * \param id Port id. 308 * 309 * \return 0 on success, -1 on failure. 310 */ 311 int spdk_scsi_dev_delete_port(struct spdk_scsi_dev *dev, uint64_t id); 312 313 /** 314 * Get the port of the given SCSI device whose port ID is id. 315 * 316 * \param dev SCSI device. 317 * \param id Port id. 318 * 319 * \return the port of the SCSI device on success, or NULL on failure. 320 */ 321 struct spdk_scsi_port *spdk_scsi_dev_find_port_by_id(struct spdk_scsi_dev *dev, uint64_t id); 322 323 /** 324 * Allocate I/O channels for all LUNs of the given SCSI device. 325 * 326 * \param dev SCSI device. 327 * 328 * \return 0 on success, -1 on failure. 329 */ 330 int spdk_scsi_dev_allocate_io_channels(struct spdk_scsi_dev *dev); 331 332 /** 333 * Free I/O channels from all LUNs of the given SCSI device. 334 */ 335 void spdk_scsi_dev_free_io_channels(struct spdk_scsi_dev *dev); 336 337 /** 338 * Construct a SCSI device object using the given parameters. 339 * 340 * \param name Name for the SCSI device. 341 * \param bdev_name_list List of bdev names to attach to the LUNs for this SCSI 342 * device. 343 * \param lun_id_list List of LUN IDs for the LUN in this SCSI device. Caller is 344 * responsible for managing the memory containing this list. lun_id_list[x] is 345 * the LUN ID for lun_list[x]. 346 * \param num_luns Number of entries in lun_list and lun_id_list. 347 * \param protocol_id SCSI SPC protocol identifier to report in INQUIRY data 348 * \param hotremove_cb Callback to lun hotremoval. Will be called once hotremove 349 * is first triggered. 350 * \param hotremove_ctx Additional argument to hotremove_cb. 351 * 352 * \return the constructed spdk_scsi_dev object. 353 */ 354 struct spdk_scsi_dev *spdk_scsi_dev_construct(const char *name, 355 const char *bdev_name_list[], 356 int *lun_id_list, 357 int num_luns, 358 uint8_t protocol_id, 359 void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), 360 void *hotremove_ctx); 361 362 /** 363 * Construct a SCSI device object using the more given parameters. 364 * 365 * \param name Name for the SCSI device. 366 * \param bdev_name_list List of bdev names to attach to the LUNs for this SCSI 367 * device. 368 * \param lun_id_list List of LUN IDs for the LUN in this SCSI device. Caller is 369 * responsible for managing the memory containing this list. lun_id_list[x] is 370 * the LUN ID for lun_list[x]. 371 * \param num_luns Number of entries in lun_list and lun_id_list. 372 * \param protocol_id SCSI SPC protocol identifier to report in INQUIRY data 373 * \param resize_cb Callback of lun resize. 374 * \param resize_ctx Additional argument to resize_cb. 375 * \param hotremove_cb Callback to lun hotremoval. Will be called once hotremove 376 * is first triggered. 377 * \param hotremove_ctx Additional argument to hotremove_cb. 378 * 379 * \return the constructed spdk_scsi_dev object. 380 */ 381 struct spdk_scsi_dev *spdk_scsi_dev_construct_ext(const char *name, 382 const char *bdev_name_list[], 383 int *lun_id_list, 384 int num_luns, 385 uint8_t protocol_id, 386 void (*resize_cb)(const struct spdk_scsi_lun *, void *), 387 void *resize_ctx, 388 void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), 389 void *hotremove_ctx); 390 391 /** 392 * Delete a logical unit of the given SCSI device. 393 * 394 * \param dev SCSI device. 395 * \param lun Logical unit to delete. 396 */ 397 void spdk_scsi_dev_delete_lun(struct spdk_scsi_dev *dev, struct spdk_scsi_lun *lun); 398 399 /** 400 * Add a new logical unit to the given SCSI device. 401 * 402 * \param dev SCSI device. 403 * \param bdev_name Name of the bdev attached to the logical unit. 404 * \param lun_id LUN id for the new logical unit. 405 * \param hotremove_cb Callback to lun hotremoval. Will be called once hotremove 406 * is first triggered. 407 * \param hotremove_ctx Additional argument to hotremove_cb. 408 */ 409 int spdk_scsi_dev_add_lun(struct spdk_scsi_dev *dev, const char *bdev_name, int lun_id, 410 void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), 411 void *hotremove_ctx); 412 413 /** 414 * Add a new logical unit to the given SCSI device with more callbacks. 415 * 416 * \param dev SCSI device. 417 * \param bdev_name Name of the bdev attached to the logical unit. 418 * \param lun_id LUN id for the new logical unit. 419 * \param resize_cb Callback of lun resize. 420 * \param resize_ctx Additional argument to resize_cb. 421 * \param hotremove_cb Callback to lun hotremoval. Will be called once hotremove 422 * is first triggered. 423 * \param hotremove_ctx Additional argument to hotremove_cb. 424 */ 425 int spdk_scsi_dev_add_lun_ext(struct spdk_scsi_dev *dev, const char *bdev_name, int lun_id, 426 void (*resize_cb)(const struct spdk_scsi_lun *, void *), 427 void *resize_ctx, 428 void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), 429 void *hotremove_ctx); 430 431 /** 432 * Create a new SCSI port. 433 * 434 * \param id Port id. 435 * \param index Port index. 436 * \param name Port Name. 437 * 438 * \return a pointer to the created SCSI port on success, or NULL on failure. 439 */ 440 struct spdk_scsi_port *spdk_scsi_port_create(uint64_t id, uint16_t index, const char *name); 441 442 /** 443 * Free the SCSI port. 444 * 445 * \param pport SCSI port to free. 446 */ 447 void spdk_scsi_port_free(struct spdk_scsi_port **pport); 448 449 /** 450 * Get the name of the SCSI port. 451 * 452 * \param port SCSI port to query. 453 * 454 * \return the name of the SCSI port. 455 */ 456 const char *spdk_scsi_port_get_name(const struct spdk_scsi_port *port); 457 458 /** 459 * Construct a new SCSI task. 460 * 461 * \param task SCSI task to consturct. 462 * \param cpl_fn Called when the task is completed. 463 * \param free_fn Called when the task is freed 464 */ 465 void spdk_scsi_task_construct(struct spdk_scsi_task *task, 466 spdk_scsi_task_cpl cpl_fn, 467 spdk_scsi_task_free free_fn); 468 469 /** 470 * Put the SCSI task. 471 * 472 * \param task SCSI task to put. 473 */ 474 void spdk_scsi_task_put(struct spdk_scsi_task *task); 475 476 /** 477 * Set internal buffer to given one. Caller is owner of that buffer. 478 * 479 * \param task SCSI task. 480 * \param data Pointer to buffer. 481 * \param len Buffer length. 482 */ 483 void spdk_scsi_task_set_data(struct spdk_scsi_task *task, void *data, uint32_t len); 484 485 /** 486 * Single buffer -> vector of buffers. 487 * 488 * \param task SCSI task. 489 * \param src A pointer to the data buffer read from. 490 * \param len Length of the data buffer read from. 491 * 492 * \return the total length of the vector of buffers written into on success, or 493 * -1 on failure. 494 */ 495 int spdk_scsi_task_scatter_data(struct spdk_scsi_task *task, const void *src, size_t len); 496 497 /** 498 * Vector of buffers -> single buffer. 499 * 500 * \param task SCSI task, 501 * \param len Length of the buffer allocated and written into. 502 * 503 * \return a pointer to the buffer allocated and written into. 504 */ 505 void *spdk_scsi_task_gather_data(struct spdk_scsi_task *task, int *len); 506 507 /** 508 * Build sense data for the SCSI task. 509 * 510 * \param task SCSI task. 511 * \param sk Sense key. 512 * \param asc Additional sense code. 513 * \param ascq Additional sense code qualifier. 514 */ 515 void spdk_scsi_task_build_sense_data(struct spdk_scsi_task *task, int sk, int asc, 516 int ascq); 517 518 /** 519 * Set SCSI status code to the SCSI task. When the status code is CHECK CONDITION, 520 * sense data is build too. 521 * 522 * \param task SCSI task. 523 * \param sc Sense code 524 * \param sk Sense key. 525 * \param asc Additional sense code. 526 * \param ascq Additional sense code qualifier. 527 */ 528 void spdk_scsi_task_set_status(struct spdk_scsi_task *task, int sc, int sk, int asc, 529 int ascq); 530 531 /** 532 * Copy SCSI status. 533 * 534 * \param dst SCSI task whose status is written to. 535 * \param src SCSI task whose status is read from. 536 */ 537 void spdk_scsi_task_copy_status(struct spdk_scsi_task *dst, struct spdk_scsi_task *src); 538 539 /** 540 * Process the SCSI task when no LUN is attached. 541 * 542 * \param task SCSI task. 543 */ 544 void spdk_scsi_task_process_null_lun(struct spdk_scsi_task *task); 545 546 /** 547 * Process the aborted SCSI task. 548 * 549 * \param task SCSI task. 550 */ 551 void spdk_scsi_task_process_abort(struct spdk_scsi_task *task); 552 553 /** 554 * Open a logical unit for I/O operations. 555 * 556 * The registered callback function must get all tasks from the upper layer 557 * (e.g. iSCSI) to the LUN done, free the IO channel of the LUN if allocated, 558 * and then close the LUN. 559 * 560 * \param lun Logical unit to open. 561 * \param hotremove_cb Callback function for hot removal of the logical unit. 562 * \param hotremove_ctx Param for hot removal callback function. 563 * \param desc Output parameter for the descriptor when operation is successful. 564 * \return 0 if operation is successful, suitable errno value otherwise 565 */ 566 int spdk_scsi_lun_open(struct spdk_scsi_lun *lun, spdk_scsi_lun_remove_cb_t hotremove_cb, 567 void *hotremove_ctx, struct spdk_scsi_lun_desc **desc); 568 569 /** 570 * Close an opened logical unit. 571 * 572 * \param desc Descriptor of the logical unit. 573 */ 574 void spdk_scsi_lun_close(struct spdk_scsi_lun_desc *desc); 575 576 /** 577 * Allocate I/O channel for the LUN 578 * 579 * \param desc Descriptor of the logical unit. 580 * 581 * \return 0 on success, -1 on failure. 582 */ 583 int spdk_scsi_lun_allocate_io_channel(struct spdk_scsi_lun_desc *desc); 584 585 /** 586 * Free I/O channel from the logical unit 587 * 588 * \param desc Descriptor of the logical unit. 589 */ 590 void spdk_scsi_lun_free_io_channel(struct spdk_scsi_lun_desc *desc); 591 592 /** 593 * Get DIF context for SCSI LUN and SCSI command. 594 * 595 * \param lun Logical unit. 596 * \param task SCSI task which has the payload. 597 * \param dif_ctx Output parameter which will contain initialized DIF context. 598 * 599 * \return true on success or false otherwise. 600 */ 601 bool spdk_scsi_lun_get_dif_ctx(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task, 602 struct spdk_dif_ctx *dif_ctx); 603 604 /** 605 * Set iSCSI Initiator port TransportID 606 * 607 * \param port SCSI initiator port. 608 * \param iscsi_name Initiator name. 609 * \param isid Session ID. 610 */ 611 void spdk_scsi_port_set_iscsi_transport_id(struct spdk_scsi_port *port, 612 char *iscsi_name, uint64_t isid); 613 614 /** 615 * Convert LUN ID from integer to LUN format 616 * 617 * \param lun_id Integer LUN ID 618 * 619 * \return LUN format of LUN ID 620 */ 621 uint64_t spdk_scsi_lun_id_int_to_fmt(int lun_id); 622 623 /** 624 * Convert LUN ID from LUN format to integer 625 * 626 * \param fmt_lun LUN format of LUN ID 627 * 628 * \return integer LUN ID 629 */ 630 int spdk_scsi_lun_id_fmt_to_int(uint64_t fmt_lun); 631 #ifdef __cplusplus 632 } 633 #endif 634 635 #endif /* SPDK_SCSI_H */ 636