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