linux/include/scsi/osd_initiator.h
<<
>>
Prefs
   1/*
   2 * osd_initiator.h - OSD initiator API definition
   3 *
   4 * Copyright (C) 2008 Panasas Inc.  All rights reserved.
   5 *
   6 * Authors:
   7 *   Boaz Harrosh <bharrosh@panasas.com>
   8 *   Benny Halevy <bhalevy@panasas.com>
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License version 2
  12 *
  13 */
  14#ifndef __OSD_INITIATOR_H__
  15#define __OSD_INITIATOR_H__
  16
  17#include "osd_protocol.h"
  18#include "osd_types.h"
  19
  20#include <linux/blkdev.h>
  21
  22/* Note: "NI" in comments below means "Not Implemented yet" */
  23
  24/* Configure of code:
  25 * #undef if you *don't* want OSD v1 support in runtime.
  26 * If #defined the initiator will dynamically configure to encode OSD v1
  27 * CDB's if the target is detected to be OSD v1 only.
  28 * OSD v2 only commands, options, and attributes will be ignored if target
  29 * is v1 only.
  30 * If #defined will result in bigger/slower code (OK Slower maybe not)
  31 * Q: Should this be CONFIG_SCSI_OSD_VER1_SUPPORT and set from Kconfig?
  32 */
  33#define OSD_VER1_SUPPORT y
  34
  35enum osd_std_version {
  36        OSD_VER_NONE = 0,
  37        OSD_VER1 = 1,
  38        OSD_VER2 = 2,
  39};
  40
  41/*
  42 * Object-based Storage Device.
  43 * This object represents an OSD device.
  44 * It is not a full linux device in any way. It is only
  45 * a place to hang resources associated with a Linux
  46 * request Q and some default properties.
  47 */
  48struct osd_dev {
  49        struct scsi_device *scsi_device;
  50        unsigned def_timeout;
  51
  52#ifdef OSD_VER1_SUPPORT
  53        enum osd_std_version version;
  54#endif
  55};
  56
  57/* Retrieve/return osd_dev(s) for use by Kernel clients */
  58struct osd_dev *osduld_path_lookup(const char *dev_name); /*Use IS_ERR/ERR_PTR*/
  59void osduld_put_device(struct osd_dev *od);
  60
  61/* Add/remove test ioctls from external modules */
  62typedef int (do_test_fn)(struct osd_dev *od, unsigned cmd, unsigned long arg);
  63int osduld_register_test(unsigned ioctl, do_test_fn *do_test);
  64void osduld_unregister_test(unsigned ioctl);
  65
  66/* These are called by uld at probe time */
  67void osd_dev_init(struct osd_dev *od, struct scsi_device *scsi_device);
  68void osd_dev_fini(struct osd_dev *od);
  69
  70/* some hi level device operations */
  71int osd_auto_detect_ver(struct osd_dev *od, void *caps);    /* GFP_KERNEL */
  72
  73/* we might want to use function vector in the future */
  74static inline void osd_dev_set_ver(struct osd_dev *od, enum osd_std_version v)
  75{
  76#ifdef OSD_VER1_SUPPORT
  77        od->version = v;
  78#endif
  79}
  80
  81struct osd_request;
  82typedef void (osd_req_done_fn)(struct osd_request *or, void *private);
  83
  84struct osd_request {
  85        struct osd_cdb cdb;
  86        struct osd_data_out_integrity_info out_data_integ;
  87        struct osd_data_in_integrity_info in_data_integ;
  88
  89        struct osd_dev *osd_dev;
  90        struct request *request;
  91
  92        struct _osd_req_data_segment {
  93                void *buff;
  94                unsigned alloc_size; /* 0 here means: don't call kfree */
  95                unsigned total_bytes;
  96        } set_attr, enc_get_attr, get_attr;
  97
  98        struct _osd_io_info {
  99                struct bio *bio;
 100                u64 total_bytes;
 101                struct request *req;
 102                struct _osd_req_data_segment *last_seg;
 103                u8 *pad_buff;
 104        } out, in;
 105
 106        gfp_t alloc_flags;
 107        unsigned timeout;
 108        unsigned retries;
 109        u8 sense[OSD_MAX_SENSE_LEN];
 110        enum osd_attributes_mode attributes_mode;
 111
 112        osd_req_done_fn *async_done;
 113        void *async_private;
 114        int async_error;
 115};
 116
 117/* OSD Version control */
 118static inline bool osd_req_is_ver1(struct osd_request *or)
 119{
 120#ifdef OSD_VER1_SUPPORT
 121        return or->osd_dev->version == OSD_VER1;
 122#else
 123        return false;
 124#endif
 125}
 126
 127/*
 128 * How to use the osd library:
 129 *
 130 * osd_start_request
 131 *      Allocates a request.
 132 *
 133 * osd_req_*
 134 *      Call one of, to encode the desired operation.
 135 *
 136 * osd_add_{get,set}_attr
 137 *      Optionally add attributes to the CDB, list or page mode.
 138 *
 139 * osd_finalize_request
 140 *      Computes final data out/in offsets and signs the request,
 141 *      making it ready for execution.
 142 *
 143 * osd_execute_request
 144 *      May be called to execute it through the block layer. Other wise submit
 145 *      the associated block request in some other way.
 146 *
 147 * After execution:
 148 * osd_req_decode_sense
 149 *      Decodes sense information to verify execution results.
 150 *
 151 * osd_req_decode_get_attr
 152 *      Retrieve osd_add_get_attr_list() values if used.
 153 *
 154 * osd_end_request
 155 *      Must be called to deallocate the request.
 156 */
 157
 158/**
 159 * osd_start_request - Allocate and initialize an osd_request
 160 *
 161 * @osd_dev:    OSD device that holds the scsi-device and default values
 162 *              that the request is associated with.
 163 * @gfp:        The allocation flags to use for request allocation, and all
 164 *              subsequent allocations. This will be stored at
 165 *              osd_request->alloc_flags, can be changed by user later
 166 *
 167 * Allocate osd_request and initialize all members to the
 168 * default/initial state.
 169 */
 170struct osd_request *osd_start_request(struct osd_dev *od, gfp_t gfp);
 171
 172enum osd_req_options {
 173        OSD_REQ_FUA = 0x08,     /* Force Unit Access */
 174        OSD_REQ_DPO = 0x10,     /* Disable Page Out */
 175
 176        OSD_REQ_BYPASS_TIMESTAMPS = 0x80,
 177};
 178
 179/**
 180 * osd_finalize_request - Sign request and prepare request for execution
 181 *
 182 * @or:         osd_request to prepare
 183 * @options:    combination of osd_req_options bit flags or 0.
 184 * @cap:        A Pointer to an OSD_CAP_LEN bytes buffer that is received from
 185 *              The security manager as capabilities for this cdb.
 186 * @cap_key:    The cryptographic key used to sign the cdb/data. Can be null
 187 *              if NOSEC is used.
 188 *
 189 * The actual request and bios are only allocated here, so are the get_attr
 190 * buffers that will receive the returned attributes. Copy's @cap to cdb.
 191 * Sign the cdb/data with @cap_key.
 192 */
 193int osd_finalize_request(struct osd_request *or,
 194        u8 options, const void *cap, const u8 *cap_key);
 195
 196/**
 197 * osd_execute_request - Execute the request synchronously through block-layer
 198 *
 199 * @or:         osd_request to Executed
 200 *
 201 * Calls blk_execute_rq to q the command and waits for completion.
 202 */
 203int osd_execute_request(struct osd_request *or);
 204
 205/**
 206 * osd_execute_request_async - Execute the request without waitting.
 207 *
 208 * @or:                      - osd_request to Executed
 209 * @done: (Optional)         - Called at end of execution
 210 * @private:                 - Will be passed to @done function
 211 *
 212 * Calls blk_execute_rq_nowait to queue the command. When execution is done
 213 * optionally calls @done with @private as parameter. @or->async_error will
 214 * have the return code
 215 */
 216int osd_execute_request_async(struct osd_request *or,
 217        osd_req_done_fn *done, void *private);
 218
 219/**
 220 * osd_req_decode_sense_full - Decode sense information after execution.
 221 *
 222 * @or:           - osd_request to examine
 223 * @osi           - Recievs a more detailed error report information (optional).
 224 * @silent        - Do not print to dmsg (Even if enabled)
 225 * @bad_obj_list  - Some commands act on multiple objects. Failed objects will
 226 *                  be recieved here (optional)
 227 * @max_obj       - Size of @bad_obj_list.
 228 * @bad_attr_list - List of failing attributes (optional)
 229 * @max_attr      - Size of @bad_attr_list.
 230 *
 231 * After execution, sense + return code can be analyzed using this function. The
 232 * return code is the final disposition on the error. So it is possible that a
 233 * CHECK_CONDITION was returned from target but this will return NO_ERROR, for
 234 * example on recovered errors. All parameters are optional if caller does
 235 * not need any returned information.
 236 * Note: This function will also dump the error to dmsg according to settings
 237 * of the SCSI_OSD_DPRINT_SENSE Kconfig value. Set @silent if you know the
 238 * command would routinely fail, to not spam the dmsg file.
 239 */
 240struct osd_sense_info {
 241        int key;                /* one of enum scsi_sense_keys */
 242        int additional_code ;   /* enum osd_additional_sense_codes */
 243        union { /* Sense specific information */
 244                u16 sense_info;
 245                u16 cdb_field_offset;   /* scsi_invalid_field_in_cdb */
 246        };
 247        union { /* Command specific information */
 248                u64 command_info;
 249        };
 250
 251        u32 not_initiated_command_functions; /* osd_command_functions_bits */
 252        u32 completed_command_functions; /* osd_command_functions_bits */
 253        struct osd_obj_id obj;
 254        struct osd_attr attr;
 255};
 256
 257int osd_req_decode_sense_full(struct osd_request *or,
 258        struct osd_sense_info *osi, bool silent,
 259        struct osd_obj_id *bad_obj_list, int max_obj,
 260        struct osd_attr *bad_attr_list, int max_attr);
 261
 262static inline int osd_req_decode_sense(struct osd_request *or,
 263        struct osd_sense_info *osi)
 264{
 265        return osd_req_decode_sense_full(or, osi, false, NULL, 0, NULL, 0);
 266}
 267
 268/**
 269 * osd_end_request - return osd_request to free store
 270 *
 271 * @or:         osd_request to free
 272 *
 273 * Deallocate all osd_request resources (struct req's, BIOs, buffers, etc.)
 274 */
 275void osd_end_request(struct osd_request *or);
 276
 277/*
 278 * CDB Encoding
 279 *
 280 * Note: call only one of the following methods.
 281 */
 282
 283/*
 284 * Device commands
 285 */
 286void osd_req_set_master_seed_xchg(struct osd_request *or, ...);/* NI */
 287void osd_req_set_master_key(struct osd_request *or, ...);/* NI */
 288
 289void osd_req_format(struct osd_request *or, u64 tot_capacity);
 290
 291/* list all partitions
 292 * @list header must be initialized to zero on first run.
 293 *
 294 * Call osd_is_obj_list_done() to find if we got the complete list.
 295 */
 296int osd_req_list_dev_partitions(struct osd_request *or,
 297        osd_id initial_id, struct osd_obj_id_list *list, unsigned nelem);
 298
 299void osd_req_flush_obsd(struct osd_request *or,
 300        enum osd_options_flush_scope_values);
 301
 302void osd_req_perform_scsi_command(struct osd_request *or,
 303        const u8 *cdb, ...);/* NI */
 304void osd_req_task_management(struct osd_request *or, ...);/* NI */
 305
 306/*
 307 * Partition commands
 308 */
 309void osd_req_create_partition(struct osd_request *or, osd_id partition);
 310void osd_req_remove_partition(struct osd_request *or, osd_id partition);
 311
 312void osd_req_set_partition_key(struct osd_request *or,
 313        osd_id partition, u8 new_key_id[OSD_CRYPTO_KEYID_SIZE],
 314        u8 seed[OSD_CRYPTO_SEED_SIZE]);/* NI */
 315
 316/* list all collections in the partition
 317 * @list header must be init to zero on first run.
 318 *
 319 * Call osd_is_obj_list_done() to find if we got the complete list.
 320 */
 321int osd_req_list_partition_collections(struct osd_request *or,
 322        osd_id partition, osd_id initial_id, struct osd_obj_id_list *list,
 323        unsigned nelem);
 324
 325/* list all objects in the partition
 326 * @list header must be init to zero on first run.
 327 *
 328 * Call osd_is_obj_list_done() to find if we got the complete list.
 329 */
 330int osd_req_list_partition_objects(struct osd_request *or,
 331        osd_id partition, osd_id initial_id, struct osd_obj_id_list *list,
 332        unsigned nelem);
 333
 334void osd_req_flush_partition(struct osd_request *or,
 335        osd_id partition, enum osd_options_flush_scope_values);
 336
 337/*
 338 * Collection commands
 339 */
 340void osd_req_create_collection(struct osd_request *or,
 341        const struct osd_obj_id *);/* NI */
 342void osd_req_remove_collection(struct osd_request *or,
 343        const struct osd_obj_id *);/* NI */
 344
 345/* list all objects in the collection */
 346int osd_req_list_collection_objects(struct osd_request *or,
 347        const struct osd_obj_id *, osd_id initial_id,
 348        struct osd_obj_id_list *list, unsigned nelem);
 349
 350/* V2 only filtered list of objects in the collection */
 351void osd_req_query(struct osd_request *or, ...);/* NI */
 352
 353void osd_req_flush_collection(struct osd_request *or,
 354        const struct osd_obj_id *, enum osd_options_flush_scope_values);
 355
 356void osd_req_get_member_attrs(struct osd_request *or, ...);/* V2-only NI */
 357void osd_req_set_member_attrs(struct osd_request *or, ...);/* V2-only NI */
 358
 359/*
 360 * Object commands
 361 */
 362void osd_req_create_object(struct osd_request *or, struct osd_obj_id *);
 363void osd_req_remove_object(struct osd_request *or, struct osd_obj_id *);
 364
 365void osd_req_write(struct osd_request *or,
 366        const struct osd_obj_id *, struct bio *data_out, u64 offset);
 367void osd_req_append(struct osd_request *or,
 368        const struct osd_obj_id *, struct bio *data_out);/* NI */
 369void osd_req_create_write(struct osd_request *or,
 370        const struct osd_obj_id *, struct bio *data_out, u64 offset);/* NI */
 371void osd_req_clear(struct osd_request *or,
 372        const struct osd_obj_id *, u64 offset, u64 len);/* NI */
 373void osd_req_punch(struct osd_request *or,
 374        const struct osd_obj_id *, u64 offset, u64 len);/* V2-only NI */
 375
 376void osd_req_flush_object(struct osd_request *or,
 377        const struct osd_obj_id *, enum osd_options_flush_scope_values,
 378        /*V2*/ u64 offset, /*V2*/ u64 len);
 379
 380void osd_req_read(struct osd_request *or,
 381        const struct osd_obj_id *, struct bio *data_in, u64 offset);
 382
 383/*
 384 * Root/Partition/Collection/Object Attributes commands
 385 */
 386
 387/* get before set */
 388void osd_req_get_attributes(struct osd_request *or, const struct osd_obj_id *);
 389
 390/* set before get */
 391void osd_req_set_attributes(struct osd_request *or, const struct osd_obj_id *);
 392
 393/*
 394 * Attributes appended to most commands
 395 */
 396
 397/* Attributes List mode (or V2 CDB) */
 398  /*
 399   * TODO: In ver2 if at finalize time only one attr was set and no gets,
 400   * then the Attributes CDB mode is used automatically to save IO.
 401   */
 402
 403/* set a list of attributes. */
 404int osd_req_add_set_attr_list(struct osd_request *or,
 405        const struct osd_attr *, unsigned nelem);
 406
 407/* get a list of attributes */
 408int osd_req_add_get_attr_list(struct osd_request *or,
 409        const struct osd_attr *, unsigned nelem);
 410
 411/*
 412 * Attributes list decoding
 413 * Must be called after osd_request.request was executed
 414 * It is called in a loop to decode the returned get_attr
 415 * (see osd_add_get_attr)
 416 */
 417int osd_req_decode_get_attr_list(struct osd_request *or,
 418        struct osd_attr *, int *nelem, void **iterator);
 419
 420/* Attributes Page mode */
 421
 422/*
 423 * Read an attribute page and optionally set one attribute
 424 *
 425 * Retrieves the attribute page directly to a user buffer.
 426 * @attr_page_data shall stay valid until end of execution.
 427 * See osd_attributes.h for common page structures
 428 */
 429int osd_req_add_get_attr_page(struct osd_request *or,
 430        u32 page_id, void *attr_page_data, unsigned max_page_len,
 431        const struct osd_attr *set_one);
 432
 433#endif /* __OSD_LIB_H__ */
 434
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.