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 * 237 * \return true if the SCSI device has any pending task, or false otherwise. 238 */ 239 bool spdk_scsi_dev_has_pending_tasks(const struct spdk_scsi_dev *dev); 240 241 /** 242 * Destruct the SCSI decice. 243 * 244 * \param dev SCSI device. 245 * \param cb_fn Callback function. 246 * \param cb_arg Argument to callback function. 247 */ 248 void spdk_scsi_dev_destruct(struct spdk_scsi_dev *dev, 249 spdk_scsi_dev_destruct_cb_t cb_fn, void *cb_arg); 250 251 /** 252 * Execute the SCSI management task. 253 * 254 * The task can be constructed by the function spdk_scsi_task_construct(). 255 * Code of task management function to be executed is set before calling this API. 256 * 257 * \param dev SCSI device. 258 * \param task SCSI task to be executed. 259 */ 260 void spdk_scsi_dev_queue_mgmt_task(struct spdk_scsi_dev *dev, struct spdk_scsi_task *task); 261 262 /** 263 * Execute the SCSI task. 264 * 265 * The task can be constructed by the function spdk_scsi_task_construct(). 266 * 267 * \param dev SCSI device. 268 * \param task Task to be executed. 269 */ 270 void spdk_scsi_dev_queue_task(struct spdk_scsi_dev *dev, struct spdk_scsi_task *task); 271 272 /** 273 * Add a new port to the given SCSI device. 274 * 275 * \param dev SCSI device. 276 * \param id Port id. 277 * \param name Port name. 278 * 279 * \return 0 on success, -1 on failure. 280 */ 281 int spdk_scsi_dev_add_port(struct spdk_scsi_dev *dev, uint64_t id, const char *name); 282 283 /** 284 * Delete a specified port of the given SCSI device. 285 * 286 * \param dev SCSI device. 287 * \param id Port id. 288 * 289 * \return 0 on success, -1 on failure. 290 */ 291 int spdk_scsi_dev_delete_port(struct spdk_scsi_dev *dev, uint64_t id); 292 293 /** 294 * Get the port of the given SCSI device whose port ID is id. 295 * 296 * \param dev SCSI device. 297 * \param id Port id. 298 * 299 * \return the port of the SCSI device on success, or NULL on failure. 300 */ 301 struct spdk_scsi_port *spdk_scsi_dev_find_port_by_id(struct spdk_scsi_dev *dev, uint64_t id); 302 303 /** 304 * Allocate I/O channels for all LUNs of the given SCSI device. 305 * 306 * \param dev SCSI device. 307 * 308 * \return 0 on success, -1 on failure. 309 */ 310 int spdk_scsi_dev_allocate_io_channels(struct spdk_scsi_dev *dev); 311 312 /** 313 * Free I/O channels from all LUNs of the given SCSI device. 314 */ 315 void spdk_scsi_dev_free_io_channels(struct spdk_scsi_dev *dev); 316 317 /** 318 * Construct a SCSI device object using the given parameters. 319 * 320 * \param name Name for the SCSI device. 321 * \param bdev_name_list List of bdev names to attach to the LUNs for this SCSI 322 * device. 323 * \param lun_id_list List of LUN IDs for the LUN in this SCSI device. Caller is 324 * responsible for managing the memory containing this list. lun_id_list[x] is 325 * the LUN ID for lun_list[x]. 326 * \param num_luns Number of entries in lun_list and lun_id_list. 327 * \param protocol_id SCSI SPC protocol identifier to report in INQUIRY data 328 * \param hotremove_cb Callback to lun hotremoval. Will be called once hotremove 329 * is first triggered. 330 * \param hotremove_ctx Additional argument to hotremove_cb. 331 * 332 * \return the constructed spdk_scsi_dev object. 333 */ 334 struct spdk_scsi_dev *spdk_scsi_dev_construct(const char *name, 335 const char *bdev_name_list[], 336 int *lun_id_list, 337 int num_luns, 338 uint8_t protocol_id, 339 void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), 340 void *hotremove_ctx); 341 342 /** 343 * Delete a logical unit of the given SCSI device. 344 * 345 * \param dev SCSI device. 346 * \param lun Logical unit to delete. 347 */ 348 void spdk_scsi_dev_delete_lun(struct spdk_scsi_dev *dev, struct spdk_scsi_lun *lun); 349 350 /** 351 * Add a new logical unit to the given SCSI device. 352 * 353 * \param dev SCSI device. 354 * \param bdev_name Name of the bdev attached to the logical unit. 355 * \param lun_id LUN id for the new logical unit. 356 * \param hotremove_cb Callback to lun hotremoval. Will be called once hotremove 357 * is first triggered. 358 * \param hotremove_ctx Additional argument to hotremove_cb. 359 */ 360 int spdk_scsi_dev_add_lun(struct spdk_scsi_dev *dev, const char *bdev_name, int lun_id, 361 void (*hotremove_cb)(const struct spdk_scsi_lun *, void *), 362 void *hotremove_ctx); 363 364 /** 365 * Create a new SCSI port. 366 * 367 * \param id Port id. 368 * \param index Port index. 369 * \param name Port Name. 370 * 371 * \return a pointer to the created SCSI port on success, or NULL on failure. 372 */ 373 struct spdk_scsi_port *spdk_scsi_port_create(uint64_t id, uint16_t index, const char *name); 374 375 /** 376 * Free the SCSI port. 377 * 378 * \param pport SCSI port to free. 379 */ 380 void spdk_scsi_port_free(struct spdk_scsi_port **pport); 381 382 /** 383 * Get the name of the SCSI port. 384 * 385 * \param port SCSI port to query. 386 * 387 * \return the name of the SCSI port. 388 */ 389 const char *spdk_scsi_port_get_name(const struct spdk_scsi_port *port); 390 391 /** 392 * Construct a new SCSI task. 393 * 394 * \param task SCSI task to consturct. 395 * \param cpl_fn Called when the task is completed. 396 * \param free_fn Called when the task is freed 397 */ 398 void spdk_scsi_task_construct(struct spdk_scsi_task *task, 399 spdk_scsi_task_cpl cpl_fn, 400 spdk_scsi_task_free free_fn); 401 402 /** 403 * Put the SCSI task. 404 * 405 * \param task SCSI task to put. 406 */ 407 void spdk_scsi_task_put(struct spdk_scsi_task *task); 408 409 /** 410 * Set internal buffer to given one. Caller is owner of that buffer. 411 * 412 * \param task SCSI task. 413 * \param data Pointer to buffer. 414 * \param len Buffer length. 415 */ 416 void spdk_scsi_task_set_data(struct spdk_scsi_task *task, void *data, uint32_t len); 417 418 /** 419 * Single buffer -> vector of buffers. 420 * 421 * \param task SCSI task. 422 * \param src A pointer to the data buffer read from. 423 * \param len Length of the data buffer read from. 424 * 425 * \return the total length of the vector of buffers written into on success, or 426 * -1 on failure. 427 */ 428 int spdk_scsi_task_scatter_data(struct spdk_scsi_task *task, const void *src, size_t len); 429 430 /** 431 * Vector of buffers -> single buffer. 432 * 433 * \param task SCSI task, 434 * \param len Length of the buffer allocated and written into. 435 * 436 * \return a pointer to the buffer allocated and written into. 437 */ 438 void *spdk_scsi_task_gather_data(struct spdk_scsi_task *task, int *len); 439 440 /** 441 * Build sense data for the SCSI task. 442 * 443 * \param task SCSI task. 444 * \param sk Sense key. 445 * \param asc Additional sense code. 446 * \param ascq Additional sense code qualifier. 447 */ 448 void spdk_scsi_task_build_sense_data(struct spdk_scsi_task *task, int sk, int asc, 449 int ascq); 450 451 /** 452 * Set SCSI status code to the SCSI task. When the status code is CHECK CONDITION, 453 * sense data is build too. 454 * 455 * \param task SCSI task. 456 * \param sc Sense code 457 * \param sk Sense key. 458 * \param asc Additional sense code. 459 * \param ascq Additional sense code qualifier. 460 */ 461 void spdk_scsi_task_set_status(struct spdk_scsi_task *task, int sc, int sk, int asc, 462 int ascq); 463 464 /** 465 * Copy SCSI status. 466 * 467 * \param dst SCSI task whose status is written to. 468 * \param src SCSI task whose status is read from. 469 */ 470 void spdk_scsi_task_copy_status(struct spdk_scsi_task *dst, struct spdk_scsi_task *src); 471 472 /** 473 * Process the SCSI task when no LUN is attached. 474 * 475 * \param task SCSI task. 476 */ 477 void spdk_scsi_task_process_null_lun(struct spdk_scsi_task *task); 478 479 /** 480 * Process the aborted SCSI task. 481 * 482 * \param task SCSI task. 483 */ 484 void spdk_scsi_task_process_abort(struct spdk_scsi_task *task); 485 486 /** 487 * Open a logical unit for I/O operations. 488 * 489 * The registered callback function must get all tasks from the upper layer 490 * (e.g. iSCSI) to the LUN done, free the IO channel of the LUN if allocated, 491 * and then close the LUN. 492 * 493 * \param lun Logical unit to open. 494 * \param hotremove_cb Callback function for hot removal of the logical unit. 495 * \param hotremove_ctx Param for hot removal callback function. 496 * \param desc Output parameter for the descriptor when operation is successful. 497 * \return 0 if operation is successful, suitable errno value otherwise 498 */ 499 int spdk_scsi_lun_open(struct spdk_scsi_lun *lun, spdk_scsi_lun_remove_cb_t hotremove_cb, 500 void *hotremove_ctx, struct spdk_scsi_lun_desc **desc); 501 502 /** 503 * Close an opened logical unit. 504 * 505 * \param desc Descriptor of the logical unit. 506 */ 507 void spdk_scsi_lun_close(struct spdk_scsi_lun_desc *desc); 508 509 /** 510 * Allocate I/O channel for the LUN 511 * 512 * \param desc Descriptor of the logical unit. 513 * 514 * \return 0 on success, -1 on failure. 515 */ 516 int spdk_scsi_lun_allocate_io_channel(struct spdk_scsi_lun_desc *desc); 517 518 /** 519 * Free I/O channel from the logical unit 520 * 521 * \param desc Descriptor of the logical unit. 522 */ 523 void spdk_scsi_lun_free_io_channel(struct spdk_scsi_lun_desc *desc); 524 525 /** 526 * Get DIF context for SCSI LUN and SCSI command. 527 * 528 * \param lun Logical unit. 529 * \param cdb SCSI CDB. 530 * \param offset Offset in the payload. 531 * \param dif_ctx Output parameter which will contain initialized DIF context. 532 * 533 * \return true on success or false otherwise. 534 */ 535 bool spdk_scsi_lun_get_dif_ctx(struct spdk_scsi_lun *lun, uint8_t *cdb, uint32_t offset, 536 struct spdk_dif_ctx *dif_ctx); 537 538 /** 539 * Set iSCSI Initiator port TransportID 540 * 541 * \param port SCSI initiator port. 542 * \param iscsi_name Initiator name. 543 * \param isid Session ID. 544 */ 545 void spdk_scsi_port_set_iscsi_transport_id(struct spdk_scsi_port *port, 546 char *iscsi_name, uint64_t isid); 547 548 /** 549 * Convert LUN ID from integer to LUN format 550 * 551 * \param lun_id Integer LUN ID 552 * 553 * \return LUN format of LUN ID 554 */ 555 uint64_t spdk_scsi_lun_id_int_to_fmt(int lun_id); 556 557 /** 558 * Convert LUN ID from LUN format to integer 559 * 560 * \param fmt_lun LUN format of LUN ID 561 * 562 * \return integer LUN ID 563 */ 564 int spdk_scsi_lun_id_fmt_to_int(uint64_t fmt_lun); 565 #ifdef __cplusplus 566 } 567 #endif 568 569 #endif /* SPDK_SCSI_H */ 570