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