osd_initiator.c revision 345c435dbb0b77b00ffe73801102533e24c647af
102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* 202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * osd_initiator - Main body of the osd initiator library. 302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * 402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Note: The file does not contain the advanced security functionality which 502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * is only needed by the security_manager's initiators. 602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * 702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Copyright (C) 2008 Panasas Inc. All rights reserved. 802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * 902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Authors: 1002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Boaz Harrosh <bharrosh@panasas.com> 1102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Benny Halevy <bhalevy@panasas.com> 1202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * 1302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * This program is free software; you can redistribute it and/or modify 1402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * it under the terms of the GNU General Public License version 2 1502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * 1602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Redistribution and use in source and binary forms, with or without 1702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * modification, are permitted provided that the following conditions 1802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * are met: 1902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * 2002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * 1. Redistributions of source code must retain the above copyright 2102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * notice, this list of conditions and the following disclaimer. 2202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * 2. Redistributions in binary form must reproduce the above copyright 2302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * notice, this list of conditions and the following disclaimer in the 2402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * documentation and/or other materials provided with the distribution. 2502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * 3. Neither the name of the Panasas company nor the names of its 2602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * contributors may be used to endorse or promote products derived 2702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * from this software without specific prior written permission. 2802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * 2902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 3002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 3102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 3202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 3402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 3502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 3602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 3702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 4102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 4202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh#include <scsi/osd_initiator.h> 4302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh#include <scsi/osd_sec.h> 4402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh#include <scsi/scsi_device.h> 4502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 4602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh#include "osd_debug.h" 4702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 484ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh#ifndef __unused 494ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh# define __unused __attribute__((unused)) 504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh#endif 514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshenum { OSD_REQ_RETRIES = 1 }; 5302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 5402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshMODULE_AUTHOR("Boaz Harrosh <bharrosh@panasas.com>"); 5502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshMODULE_DESCRIPTION("open-osd initiator library libosd.ko"); 5602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshMODULE_LICENSE("GPL"); 5702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 5802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic inline void build_test(void) 5902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 6002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh /* structures were not packed */ 6102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh BUILD_BUG_ON(sizeof(struct osd_capability) != OSD_CAP_LEN); 6202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh BUILD_BUG_ON(sizeof(struct osdv1_cdb) != OSDv1_TOTAL_CDB_LEN); 6302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 6402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 6502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic unsigned _osd_req_cdb_len(struct osd_request *or) 6602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 6702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return OSDv1_TOTAL_CDB_LEN; 6802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 6902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 704ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic unsigned _osd_req_alist_elem_size(struct osd_request *or, unsigned len) 714ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 724ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return osdv1_attr_list_elem_size(len); 734ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 744ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 754ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic unsigned _osd_req_alist_size(struct osd_request *or, void *list_head) 764ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 774ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return osdv1_list_size(list_head); 784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic unsigned _osd_req_sizeof_alist_header(struct osd_request *or) 814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 824ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return sizeof(struct osdv1_attributes_list_header); 834ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 844ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic void _osd_req_set_alist_type(struct osd_request *or, 864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh void *list, int list_type) 874ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 884ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osdv1_attributes_list_header *attr_list = list; 894ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 904ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh memset(attr_list, 0, sizeof(*attr_list)); 914ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr_list->type = list_type; 924ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 934ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 944ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic bool _osd_req_is_alist_type(struct osd_request *or, 954ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh void *list, int list_type) 964ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 974ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!list) 984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return false; 994ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 1004ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (1) { 1014ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osdv1_attributes_list_header *attr_list = list; 1024ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 1034ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return attr_list->type == list_type; 1044ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 1054ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 1064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 1074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic osd_cdb_offset osd_req_encode_offset(struct osd_request *or, 1084ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh u64 offset, unsigned *padding) 1094ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 1104ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return __osd_encode_offset(offset, padding, 1114ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSDv1_OFFSET_MIN_SHIFT, OSD_OFFSET_MAX_SHIFT); 1124ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 1134ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 114345c435dbb0b77b00ffe73801102533e24c647afBoaz Harroshstatic struct osd_security_parameters * 115345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh_osd_req_sec_params(struct osd_request *or) 116345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh{ 117345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh struct osd_cdb *ocdb = &or->cdb; 118345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 119345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh return &ocdb->v1.sec_params; 120345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh} 121345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 12202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_dev_init(struct osd_dev *osdd, struct scsi_device *scsi_device) 12302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 12402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh memset(osdd, 0, sizeof(*osdd)); 12502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osdd->scsi_device = scsi_device; 12602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osdd->def_timeout = BLK_DEFAULT_SG_TIMEOUT; 12702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh /* TODO: Allocate pools for osd_request attributes ... */ 12802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 12902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_dev_init); 13002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 13102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_dev_fini(struct osd_dev *osdd) 13202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 13302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh /* TODO: De-allocate pools */ 13402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 13502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osdd->scsi_device = NULL; 13602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 13702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_dev_fini); 13802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 13902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic struct osd_request *_osd_request_alloc(gfp_t gfp) 14002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 14102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct osd_request *or; 14202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 14302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh /* TODO: Use mempool with one saved request */ 14402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or = kzalloc(sizeof(*or), gfp); 14502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return or; 14602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 14702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 14802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic void _osd_request_free(struct osd_request *or) 14902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 15002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh kfree(or); 15102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 15202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 15302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstruct osd_request *osd_start_request(struct osd_dev *dev, gfp_t gfp) 15402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 15502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct osd_request *or; 15602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 15702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or = _osd_request_alloc(gfp); 15802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (!or) 15902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return NULL; 16002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 16102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->osd_dev = dev; 16202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->alloc_flags = gfp; 16302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->timeout = dev->def_timeout; 16402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->retries = OSD_REQ_RETRIES; 16502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 16602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return or; 16702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 16802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_start_request); 16902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 17002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* 17102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * If osd_finalize_request() was called but the request was not executed through 17202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * the block layer, then we must release BIOs. 17302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 17402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic void _abort_unexecuted_bios(struct request *rq) 17502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 17602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct bio *bio; 17702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 17802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh while ((bio = rq->bio) != NULL) { 17902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh rq->bio = bio->bi_next; 18002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh bio_endio(bio, 0); 18102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 18202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 18302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 1844ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic void _osd_free_seg(struct osd_request *or __unused, 1854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct _osd_req_data_segment *seg) 1864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 1874ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!seg->buff || !seg->alloc_size) 1884ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return; 1894ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 1904ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh kfree(seg->buff); 1914ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh seg->buff = NULL; 1924ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh seg->alloc_size = 0; 1934ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 1944ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 19502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_end_request(struct osd_request *or) 19602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 19702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct request *rq = or->request; 19802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 1994ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _osd_free_seg(or, &or->set_attr); 2004ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _osd_free_seg(or, &or->enc_get_attr); 2014ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _osd_free_seg(or, &or->get_attr); 2024ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 20302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (rq) { 20402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (rq->next_rq) { 20502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _abort_unexecuted_bios(rq->next_rq); 20602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh blk_put_request(rq->next_rq); 20702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 20802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 20902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _abort_unexecuted_bios(rq); 21002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh blk_put_request(rq); 21102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 21202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_request_free(or); 21302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 21402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_end_request); 21502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 21602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshint osd_execute_request(struct osd_request *or) 21702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 21802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return blk_execute_rq(or->request->q, NULL, or->request, 0); 21902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 22002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_execute_request); 22102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 22202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic void osd_request_async_done(struct request *req, int error) 22302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 22402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct osd_request *or = req->end_io_data; 22502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 22602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->async_error = error; 22702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 22802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (error) 22902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_DEBUG("osd_request_async_done error recieved %d\n", error); 23002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 23102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (or->async_done) 23202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->async_done(or, or->async_private); 23302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh else 23402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osd_end_request(or); 23502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 23602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 23702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshint osd_execute_request_async(struct osd_request *or, 23802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osd_req_done_fn *done, void *private) 23902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 24002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->request->end_io_data = or; 24102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->async_private = private; 24202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->async_done = done; 24302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 24402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh blk_execute_rq_nowait(or->request->q, NULL, or->request, 0, 24502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osd_request_async_done); 24602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return 0; 24702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 24802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_execute_request_async); 24902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 2504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshu8 sg_out_pad_buffer[1 << OSDv1_OFFSET_MIN_SHIFT]; 2514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshu8 sg_in_pad_buffer[1 << OSDv1_OFFSET_MIN_SHIFT]; 2524ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 2534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _osd_realloc_seg(struct osd_request *or, 2544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct _osd_req_data_segment *seg, unsigned max_bytes) 2554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 2564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh void *buff; 2574ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 2584ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (seg->alloc_size >= max_bytes) 2594ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 2604ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 2614ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh buff = krealloc(seg->buff, max_bytes, or->alloc_flags); 2624ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!buff) { 2634ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_ERR("Failed to Realloc %d-bytes was-%d\n", max_bytes, 2644ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh seg->alloc_size); 2654ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return -ENOMEM; 2664ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 2674ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 2684ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh memset(buff + seg->alloc_size, 0, max_bytes - seg->alloc_size); 2694ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh seg->buff = buff; 2704ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh seg->alloc_size = max_bytes; 2714ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 2724ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 2734ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 2744ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _alloc_set_attr_list(struct osd_request *or, 2754ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const struct osd_attr *oa, unsigned nelem, unsigned add_bytes) 2764ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 2774ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned total_bytes = add_bytes; 2784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 2794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh for (; nelem; --nelem, ++oa) 2804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh total_bytes += _osd_req_alist_elem_size(or, oa->len); 2814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 2824ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("total_bytes=%d\n", total_bytes); 2834ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return _osd_realloc_seg(or, &or->set_attr, total_bytes); 2844ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 2854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 2864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _alloc_get_attr_desc(struct osd_request *or, unsigned max_bytes) 2874ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 2884ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("total_bytes=%d\n", max_bytes); 2894ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return _osd_realloc_seg(or, &or->enc_get_attr, max_bytes); 2904ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 2914ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 2924ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _alloc_get_attr_list(struct osd_request *or) 2934ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 2944ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("total_bytes=%d\n", or->get_attr.total_bytes); 2954ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return _osd_realloc_seg(or, &or->get_attr, or->get_attr.total_bytes); 2964ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 2974ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 29802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* 29902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Common to all OSD commands 30002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 30102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 30202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic void _osdv1_req_encode_common(struct osd_request *or, 30302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh __be16 act, const struct osd_obj_id *obj, u64 offset, u64 len) 30402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 30502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct osdv1_cdb *ocdb = &or->cdb.v1; 30602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 30702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh /* 30802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * For speed, the commands 30902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * OSD_ACT_PERFORM_SCSI_COMMAND , V1 0x8F7E, V2 0x8F7C 31002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * OSD_ACT_SCSI_TASK_MANAGEMENT , V1 0x8F7F, V2 0x8F7D 31102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * are not supported here. Should pass zero and set after the call 31202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 31302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh act &= cpu_to_be16(~0x0080); /* V1 action code */ 31402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 31502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_DEBUG("OSDv1 execute opcode 0x%x\n", be16_to_cpu(act)); 31602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 31702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ocdb->h.varlen_cdb.opcode = VARIABLE_LENGTH_CMD; 31802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ocdb->h.varlen_cdb.additional_cdb_length = OSD_ADDITIONAL_CDB_LENGTH; 31902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ocdb->h.varlen_cdb.service_action = act; 32002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 32102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ocdb->h.partition = cpu_to_be64(obj->partition); 32202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ocdb->h.object = cpu_to_be64(obj->id); 32302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ocdb->h.v1.length = cpu_to_be64(len); 32402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ocdb->h.v1.start_address = cpu_to_be64(offset); 32502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 32602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 32702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic void _osd_req_encode_common(struct osd_request *or, 32802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh __be16 act, const struct osd_obj_id *obj, u64 offset, u64 len) 32902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 33002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osdv1_req_encode_common(or, act, obj, offset, len); 33102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 33202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 33302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* 33402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Device commands 33502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 33602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_format(struct osd_request *or, u64 tot_capacity) 33702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 33802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_req_encode_common(or, OSD_ACT_FORMAT_OSD, &osd_root_object, 0, 33902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh tot_capacity); 34002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 34102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_format); 34202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 34302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* 34402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Partition commands 34502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 34602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic void _osd_req_encode_partition(struct osd_request *or, 34702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh __be16 act, osd_id partition) 34802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 34902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct osd_obj_id par = { 35002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh .partition = partition, 35102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh .id = 0, 35202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh }; 35302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 35402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_req_encode_common(or, act, &par, 0, 0); 35502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 35602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 35702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_create_partition(struct osd_request *or, osd_id partition) 35802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 35902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_req_encode_partition(or, OSD_ACT_CREATE_PARTITION, partition); 36002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 36102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_create_partition); 36202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 36302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_remove_partition(struct osd_request *or, osd_id partition) 36402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 36502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_req_encode_partition(or, OSD_ACT_REMOVE_PARTITION, partition); 36602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 36702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_remove_partition); 36802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 36902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* 37002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Object commands 37102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 37202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_create_object(struct osd_request *or, struct osd_obj_id *obj) 37302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 37402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_req_encode_common(or, OSD_ACT_CREATE, obj, 0, 0); 37502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 37602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_create_object); 37702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 37802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_remove_object(struct osd_request *or, struct osd_obj_id *obj) 37902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 38002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_req_encode_common(or, OSD_ACT_REMOVE, obj, 0, 0); 38102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 38202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_remove_object); 38302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 38402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_write(struct osd_request *or, 38502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh const struct osd_obj_id *obj, struct bio *bio, u64 offset) 38602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 38702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_req_encode_common(or, OSD_ACT_WRITE, obj, offset, bio->bi_size); 38802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh WARN_ON(or->out.bio || or->out.total_bytes); 38902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh bio->bi_rw |= (1 << BIO_RW); 39002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->out.bio = bio; 39102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->out.total_bytes = bio->bi_size; 39202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 39302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_write); 39402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 39502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_read(struct osd_request *or, 39602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh const struct osd_obj_id *obj, struct bio *bio, u64 offset) 39702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 39802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_req_encode_common(or, OSD_ACT_READ, obj, offset, bio->bi_size); 39902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh WARN_ON(or->in.bio || or->in.total_bytes); 40002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh bio->bi_rw &= ~(1 << BIO_RW); 40102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->in.bio = bio; 40202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->in.total_bytes = bio->bi_size; 40302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 40402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_read); 40502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 4064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshvoid osd_req_get_attributes(struct osd_request *or, 4074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const struct osd_obj_id *obj) 4084ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 4094ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _osd_req_encode_common(or, OSD_ACT_GET_ATTRIBUTES, obj, 0, 0); 4104ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 4114ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_get_attributes); 4124ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4134ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshvoid osd_req_set_attributes(struct osd_request *or, 4144ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const struct osd_obj_id *obj) 4154ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 4164ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _osd_req_encode_common(or, OSD_ACT_SET_ATTRIBUTES, obj, 0, 0); 4174ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 4184ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_set_attributes); 4194ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4204ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh/* 4214ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * Attributes List-mode 4224ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh */ 4234ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4244ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshint osd_req_add_set_attr_list(struct osd_request *or, 4254ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const struct osd_attr *oa, unsigned nelem) 4264ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 4274ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned total_bytes = or->set_attr.total_bytes; 4284ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh void *attr_last; 4294ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int ret; 4304ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4314ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (or->attributes_mode && 4324ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->attributes_mode != OSD_CDB_GET_SET_ATTR_LISTS) { 4334ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh WARN_ON(1); 4344ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return -EINVAL; 4354ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 4364ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->attributes_mode = OSD_CDB_GET_SET_ATTR_LISTS; 4374ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4384ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!total_bytes) { /* first-time: allocate and put list header */ 4394ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh total_bytes = _osd_req_sizeof_alist_header(or); 4404ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _alloc_set_attr_list(or, oa, nelem, total_bytes); 4414ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 4424ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 4434ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _osd_req_set_alist_type(or, or->set_attr.buff, 4444ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_ATTR_LIST_SET_RETRIEVE); 4454ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 4464ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr_last = or->set_attr.buff + total_bytes; 4474ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4484ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh for (; nelem; --nelem) { 4494ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osd_attributes_list_element *attr; 4504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned elem_size = _osd_req_alist_elem_size(or, oa->len); 4514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4524ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh total_bytes += elem_size; 4534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (unlikely(or->set_attr.alloc_size < total_bytes)) { 4544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->set_attr.total_bytes = total_bytes - elem_size; 4554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _alloc_set_attr_list(or, oa, nelem, total_bytes); 4564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 4574ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 4584ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr_last = 4594ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->set_attr.buff + or->set_attr.total_bytes; 4604ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 4614ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4624ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr = attr_last; 4634ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr->attr_page = cpu_to_be32(oa->attr_page); 4644ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr->attr_id = cpu_to_be32(oa->attr_id); 4654ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr->attr_bytes = cpu_to_be16(oa->len); 4664ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh memcpy(attr->attr_val, oa->val_ptr, oa->len); 4674ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4684ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr_last += elem_size; 4694ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ++oa; 4704ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 4714ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4724ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->set_attr.total_bytes = total_bytes; 4734ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 4744ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 4754ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_add_set_attr_list); 4764ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4774ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _append_map_kern(struct request *req, 4784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh void *buff, unsigned len, gfp_t flags) 4794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 4804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct bio *bio; 4814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int ret; 4824ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4834ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh bio = bio_map_kern(req->q, buff, len, flags); 4844ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (IS_ERR(bio)) { 4854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_ERR("Failed bio_map_kern(%p, %d) => %ld\n", buff, len, 4864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh PTR_ERR(bio)); 4874ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return PTR_ERR(bio); 4884ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 4894ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = blk_rq_append_bio(req->q, req, bio); 4904ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) { 4914ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_ERR("Failed blk_rq_append_bio(%p) => %d\n", bio, ret); 4924ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh bio_put(bio); 4934ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 4944ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 4954ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 4964ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4974ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _req_append_segment(struct osd_request *or, 4984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned padding, struct _osd_req_data_segment *seg, 4994ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct _osd_req_data_segment *last_seg, struct _osd_io_info *io) 5004ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 5014ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh void *pad_buff; 5024ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int ret; 5034ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5044ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (padding) { 5054ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* check if we can just add it to last buffer */ 5064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (last_seg && 5074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh (padding <= last_seg->alloc_size - last_seg->total_bytes)) 5084ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh pad_buff = last_seg->buff + last_seg->total_bytes; 5094ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh else 5104ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh pad_buff = io->pad_buff; 5114ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5124ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _append_map_kern(io->req, pad_buff, padding, 5134ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->alloc_flags); 5144ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 5154ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 5164ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh io->total_bytes += padding; 5174ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 5184ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5194ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _append_map_kern(io->req, seg->buff, seg->total_bytes, 5204ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->alloc_flags); 5214ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 5224ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 5234ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5244ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh io->total_bytes += seg->total_bytes; 5254ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("padding=%d buff=%p total_bytes=%d\n", padding, seg->buff, 5264ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh seg->total_bytes); 5274ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 5284ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 5294ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5304ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _osd_req_finalize_set_attr_list(struct osd_request *or) 5314ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 5324ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 5334ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned padding; 5344ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int ret; 5354ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5364ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!or->set_attr.total_bytes) { 5374ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.set_attr_offset = OSD_OFFSET_UNUSED; 5384ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 5394ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 5404ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5414ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.set_attr_bytes = cpu_to_be32(or->set_attr.total_bytes); 5424ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.set_attr_offset = 5434ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh osd_req_encode_offset(or, or->out.total_bytes, &padding); 5444ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5454ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _req_append_segment(or, padding, &or->set_attr, 5464ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->out.last_seg, &or->out); 5474ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 5484ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 5494ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->out.last_seg = &or->set_attr; 5514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 5524ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 5534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshint osd_req_add_get_attr_list(struct osd_request *or, 5554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const struct osd_attr *oa, unsigned nelem) 5564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 5574ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned total_bytes = or->enc_get_attr.total_bytes; 5584ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh void *attr_last; 5594ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int ret; 5604ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5614ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (or->attributes_mode && 5624ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->attributes_mode != OSD_CDB_GET_SET_ATTR_LISTS) { 5634ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh WARN_ON(1); 5644ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return -EINVAL; 5654ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 5664ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->attributes_mode = OSD_CDB_GET_SET_ATTR_LISTS; 5674ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5684ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* first time calc data-in list header size */ 5694ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!or->get_attr.total_bytes) 5704ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.total_bytes = _osd_req_sizeof_alist_header(or); 5714ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5724ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* calc data-out info */ 5734ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!total_bytes) { /* first-time: allocate and put list header */ 5744ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned max_bytes; 5754ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5764ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh total_bytes = _osd_req_sizeof_alist_header(or); 5774ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh max_bytes = total_bytes + 5784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh nelem * sizeof(struct osd_attributes_list_attrid); 5794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _alloc_get_attr_desc(or, max_bytes); 5804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 5814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 5824ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5834ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _osd_req_set_alist_type(or, or->enc_get_attr.buff, 5844ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_ATTR_LIST_GET); 5854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 5864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr_last = or->enc_get_attr.buff + total_bytes; 5874ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5884ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh for (; nelem; --nelem) { 5894ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osd_attributes_list_attrid *attrid; 5904ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const unsigned cur_size = sizeof(*attrid); 5914ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5924ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh total_bytes += cur_size; 5934ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (unlikely(or->enc_get_attr.alloc_size < total_bytes)) { 5944ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->enc_get_attr.total_bytes = total_bytes - cur_size; 5954ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _alloc_get_attr_desc(or, 5964ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh total_bytes + nelem * sizeof(*attrid)); 5974ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 5984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 5994ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr_last = or->enc_get_attr.buff + 6004ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->enc_get_attr.total_bytes; 6014ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 6024ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6034ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attrid = attr_last; 6044ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attrid->attr_page = cpu_to_be32(oa->attr_page); 6054ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attrid->attr_id = cpu_to_be32(oa->attr_id); 6064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr_last += cur_size; 6084ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6094ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* calc data-in size */ 6104ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.total_bytes += 6114ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _osd_req_alist_elem_size(or, oa->len); 6124ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ++oa; 6134ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 6144ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6154ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->enc_get_attr.total_bytes = total_bytes; 6164ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6174ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG( 6184ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh "get_attr.total_bytes=%u(%u) enc_get_attr.total_bytes=%u(%Zu)\n", 6194ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.total_bytes, 6204ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.total_bytes - _osd_req_sizeof_alist_header(or), 6214ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->enc_get_attr.total_bytes, 6224ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh (or->enc_get_attr.total_bytes - _osd_req_sizeof_alist_header(or)) 6234ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh / sizeof(struct osd_attributes_list_attrid)); 6244ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6254ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 6264ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 6274ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_add_get_attr_list); 6284ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6294ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _osd_req_finalize_get_attr_list(struct osd_request *or) 6304ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 6314ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 6324ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned out_padding; 6334ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned in_padding; 6344ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int ret; 6354ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6364ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!or->enc_get_attr.total_bytes) { 6374ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.get_attr_desc_offset = OSD_OFFSET_UNUSED; 6384ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.get_attr_offset = OSD_OFFSET_UNUSED; 6394ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 6404ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 6414ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6424ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _alloc_get_attr_list(or); 6434ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 6444ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 6454ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6464ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* The out-going buffer info update */ 6474ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("out-going\n"); 6484ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.get_attr_desc_bytes = 6494ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cpu_to_be32(or->enc_get_attr.total_bytes); 6504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.get_attr_desc_offset = 6524ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh osd_req_encode_offset(or, or->out.total_bytes, &out_padding); 6534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _req_append_segment(or, out_padding, &or->enc_get_attr, 6554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->out.last_seg, &or->out); 6564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 6574ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 6584ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->out.last_seg = &or->enc_get_attr; 6594ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6604ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* The incoming buffer info update */ 6614ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("in-coming\n"); 6624ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.get_attr_alloc_length = 6634ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cpu_to_be32(or->get_attr.total_bytes); 6644ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6654ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.get_attr_offset = 6664ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh osd_req_encode_offset(or, or->in.total_bytes, &in_padding); 6674ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6684ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _req_append_segment(or, in_padding, &or->get_attr, NULL, 6694ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh &or->in); 6704ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 6714ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 6724ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->in.last_seg = &or->get_attr; 6734ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6744ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 6754ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 6764ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6774ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshint osd_req_decode_get_attr_list(struct osd_request *or, 6784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osd_attr *oa, int *nelem, void **iterator) 6794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 6804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned cur_bytes, returned_bytes; 6814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int n; 6824ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const unsigned sizeof_attr_list = _osd_req_sizeof_alist_header(or); 6834ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh void *cur_p; 6844ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!_osd_req_is_alist_type(or, or->get_attr.buff, 6864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_ATTR_LIST_SET_RETRIEVE)) { 6874ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->attr_page = 0; 6884ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->attr_id = 0; 6894ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->val_ptr = NULL; 6904ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->len = 0; 6914ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh *iterator = NULL; 6924ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 6934ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 6944ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 6954ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (*iterator) { 6964ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh BUG_ON((*iterator < or->get_attr.buff) || 6974ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh (or->get_attr.buff + or->get_attr.alloc_size < *iterator)); 6984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cur_p = *iterator; 6994ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cur_bytes = (*iterator - or->get_attr.buff) - sizeof_attr_list; 7004ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh returned_bytes = or->get_attr.total_bytes; 7014ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } else { /* first time decode the list header */ 7024ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cur_bytes = sizeof_attr_list; 7034ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh returned_bytes = _osd_req_alist_size(or, or->get_attr.buff) + 7044ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh sizeof_attr_list; 7054ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cur_p = or->get_attr.buff + sizeof_attr_list; 7074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7084ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (returned_bytes > or->get_attr.alloc_size) { 7094ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("target report: space was not big enough! " 7104ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh "Allocate=%u Needed=%u\n", 7114ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.alloc_size, 7124ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh returned_bytes + sizeof_attr_list); 7134ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7144ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh returned_bytes = 7154ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.alloc_size - sizeof_attr_list; 7164ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 7174ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.total_bytes = returned_bytes; 7184ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 7194ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7204ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh for (n = 0; (n < *nelem) && (cur_bytes < returned_bytes); ++n) { 7214ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osd_attributes_list_element *attr = cur_p; 7224ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned inc; 7234ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7244ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->len = be16_to_cpu(attr->attr_bytes); 7254ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh inc = _osd_req_alist_elem_size(or, oa->len); 7264ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("oa->len=%d inc=%d cur_bytes=%d\n", 7274ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->len, inc, cur_bytes); 7284ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cur_bytes += inc; 7294ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (cur_bytes > returned_bytes) { 7304ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_ERR("BAD FOOD from target. list not valid!" 7314ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh "c=%d r=%d n=%d\n", 7324ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cur_bytes, returned_bytes, n); 7334ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->val_ptr = NULL; 7344ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh break; 7354ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 7364ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7374ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->attr_page = be32_to_cpu(attr->attr_page); 7384ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->attr_id = be32_to_cpu(attr->attr_id); 7394ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->val_ptr = attr->attr_val; 7404ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7414ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cur_p += inc; 7424ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ++oa; 7434ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 7444ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7454ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh *iterator = (returned_bytes - cur_bytes) ? cur_p : NULL; 7464ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh *nelem = n; 7474ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return returned_bytes - cur_bytes; 7484ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 7494ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_decode_get_attr_list); 7504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh/* 7524ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * Attributes Page-mode 7534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh */ 7544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshint osd_req_add_get_attr_page(struct osd_request *or, 7564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh u32 page_id, void *attar_page, unsigned max_page_len, 7574ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const struct osd_attr *set_one_attr) 7584ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 7594ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 7604ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7614ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (or->attributes_mode && 7624ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->attributes_mode != OSD_CDB_GET_ATTR_PAGE_SET_ONE) { 7634ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh WARN_ON(1); 7644ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return -EINVAL; 7654ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 7664ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->attributes_mode = OSD_CDB_GET_ATTR_PAGE_SET_ONE; 7674ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7684ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.buff = attar_page; 7694ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.total_bytes = max_page_len; 7704ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7714ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->set_attr.buff = set_one_attr->val_ptr; 7724ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->set_attr.total_bytes = set_one_attr->len; 7734ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7744ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_page.get_attr_page = cpu_to_be32(page_id); 7754ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_page.get_attr_alloc_length = cpu_to_be32(max_page_len); 7764ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* ocdb->attrs_page.get_attr_offset; */ 7774ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_page.set_attr_page = cpu_to_be32(set_one_attr->attr_page); 7794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_page.set_attr_id = cpu_to_be32(set_one_attr->attr_id); 7804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_page.set_attr_length = cpu_to_be32(set_one_attr->len); 7814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* ocdb->attrs_page.set_attr_offset; */ 7824ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 7834ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 7844ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_add_get_attr_page); 7854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _osd_req_finalize_attr_page(struct osd_request *or) 7874ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 7884ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 7894ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned in_padding, out_padding; 7904ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int ret; 7914ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7924ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* returned page */ 7934ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_page.get_attr_offset = 7944ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh osd_req_encode_offset(or, or->in.total_bytes, &in_padding); 7954ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 7964ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _req_append_segment(or, in_padding, &or->get_attr, NULL, 7974ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh &or->in); 7984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 7994ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 8004ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 8014ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* set one value */ 8024ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_page.set_attr_offset = 8034ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh osd_req_encode_offset(or, or->out.total_bytes, &out_padding); 8044ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 8054ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _req_append_segment(or, out_padding, &or->enc_get_attr, NULL, 8064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh &or->out); 8074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 8084ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 8094ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 810345c435dbb0b77b00ffe73801102533e24c647afBoaz Harroshstatic int _osd_req_finalize_data_integrity(struct osd_request *or, 811345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh bool has_in, bool has_out, const u8 *cap_key) 812345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh{ 813345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh struct osd_security_parameters *sec_parms = _osd_req_sec_params(or); 814345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh int ret; 815345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 816345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh if (!osd_is_sec_alldata(sec_parms)) 817345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh return 0; 818345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 819345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh if (has_out) { 820345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh struct _osd_req_data_segment seg = { 821345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh .buff = &or->out_data_integ, 822345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh .total_bytes = sizeof(or->out_data_integ), 823345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh }; 824345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh unsigned pad; 825345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 826345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh or->out_data_integ.data_bytes = cpu_to_be64( 827345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh or->out.bio ? or->out.bio->bi_size : 0); 828345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh or->out_data_integ.set_attributes_bytes = cpu_to_be64( 829345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh or->set_attr.total_bytes); 830345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh or->out_data_integ.get_attributes_bytes = cpu_to_be64( 831345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh or->enc_get_attr.total_bytes); 832345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 833345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh sec_parms->data_out_integrity_check_offset = 834345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh osd_req_encode_offset(or, or->out.total_bytes, &pad); 835345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 836345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh ret = _req_append_segment(or, pad, &seg, or->out.last_seg, 837345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh &or->out); 838345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh if (ret) 839345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh return ret; 840345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh or->out.last_seg = NULL; 841345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 842345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh /* they are now all chained to request sign them all together */ 843345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh osd_sec_sign_data(&or->out_data_integ, or->out.req->bio, 844345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh cap_key); 845345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh } 846345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 847345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh if (has_in) { 848345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh struct _osd_req_data_segment seg = { 849345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh .buff = &or->in_data_integ, 850345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh .total_bytes = sizeof(or->in_data_integ), 851345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh }; 852345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh unsigned pad; 853345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 854345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh sec_parms->data_in_integrity_check_offset = 855345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh osd_req_encode_offset(or, or->in.total_bytes, &pad); 856345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 857345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh ret = _req_append_segment(or, pad, &seg, or->in.last_seg, 858345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh &or->in); 859345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh if (ret) 860345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh return ret; 861345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 862345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh or->in.last_seg = NULL; 863345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh } 864345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 865345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh return 0; 866345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh} 867345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 86802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* 86902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * osd_finalize_request and helpers 87002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 87102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 87202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic int _init_blk_request(struct osd_request *or, 87302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh bool has_in, bool has_out) 87402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 87502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh gfp_t flags = or->alloc_flags; 87602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct scsi_device *scsi_device = or->osd_dev->scsi_device; 87702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct request_queue *q = scsi_device->request_queue; 87802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct request *req; 87902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh int ret = -ENOMEM; 88002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 88102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh req = blk_get_request(q, has_out, flags); 88202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (!req) 88302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh goto out; 88402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 88502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->request = req; 88602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh req->cmd_type = REQ_TYPE_BLOCK_PC; 88702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh req->timeout = or->timeout; 88802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh req->retries = or->retries; 88902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh req->sense = or->sense; 89002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh req->sense_len = 0; 89102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 89202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (has_out) { 89302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->out.req = req; 89402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (has_in) { 89502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh /* allocate bidi request */ 89602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh req = blk_get_request(q, READ, flags); 89702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (!req) { 89802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_DEBUG("blk_get_request for bidi failed\n"); 89902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh goto out; 90002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 90102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh req->cmd_type = REQ_TYPE_BLOCK_PC; 90202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->in.req = or->request->next_rq = req; 90302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 90402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } else if (has_in) 90502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->in.req = req; 90602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 90702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ret = 0; 90802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshout: 90902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_DEBUG("or=%p has_in=%d has_out=%d => %d, %p\n", 91002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or, has_in, has_out, ret, or->request); 91102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return ret; 91202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 91302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 91402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshint osd_finalize_request(struct osd_request *or, 91502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh u8 options, const void *cap, const u8 *cap_key) 91602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 91702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 91802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh bool has_in, has_out; 91902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh int ret; 92002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 92102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (options & OSD_REQ_FUA) 92202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cdbh->options |= OSD_CDB_FUA; 92302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 92402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (options & OSD_REQ_DPO) 92502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cdbh->options |= OSD_CDB_DPO; 92602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 92702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (options & OSD_REQ_BYPASS_TIMESTAMPS) 92802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cdbh->timestamp_control = OSD_CDB_BYPASS_TIMESTAMPS; 92902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 93002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osd_set_caps(&or->cdb, cap); 93102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 93202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh has_in = or->in.bio || or->get_attr.total_bytes; 93302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh has_out = or->out.bio || or->set_attr.total_bytes || 93402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->enc_get_attr.total_bytes; 93502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 93602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ret = _init_blk_request(or, has_in, has_out); 93702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (ret) { 93802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_DEBUG("_init_blk_request failed\n"); 93902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return ret; 94002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 94102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 94202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (or->out.bio) { 94302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ret = blk_rq_append_bio(or->request->q, or->out.req, 94402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->out.bio); 94502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (ret) { 94602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_DEBUG("blk_rq_append_bio out failed\n"); 94702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return ret; 94802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 94902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_DEBUG("out bytes=%llu (bytes_req=%u)\n", 95002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _LLU(or->out.total_bytes), or->out.req->data_len); 95102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 95202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (or->in.bio) { 95302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ret = blk_rq_append_bio(or->request->q, or->in.req, or->in.bio); 95402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (ret) { 95502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_DEBUG("blk_rq_append_bio in failed\n"); 95602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return ret; 95702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 95802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_DEBUG("in bytes=%llu (bytes_req=%u)\n", 95902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _LLU(or->in.total_bytes), or->in.req->data_len); 96002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 96102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 9624ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->out.pad_buff = sg_out_pad_buffer; 9634ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->in.pad_buff = sg_in_pad_buffer; 9644ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 96502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (!or->attributes_mode) 96602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->attributes_mode = OSD_CDB_GET_SET_ATTR_LISTS; 96702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cdbh->command_specific_options |= or->attributes_mode; 9684ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (or->attributes_mode == OSD_CDB_GET_ATTR_PAGE_SET_ONE) { 9694ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _osd_req_finalize_attr_page(or); 9704ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } else { 9714ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* TODO: I think that for the GET_ATTR command these 2 should 9724ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * be reversed to keep them in execution order (for embeded 9734ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * targets with low memory footprint) 9744ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh */ 9754ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _osd_req_finalize_set_attr_list(or); 9764ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) { 9774ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("_osd_req_finalize_set_attr_list failed\n"); 9784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 9794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 9804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 9814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _osd_req_finalize_get_attr_list(or); 9824ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) { 9834ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("_osd_req_finalize_get_attr_list failed\n"); 9844ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 9854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 9864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 98702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 988345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh ret = _osd_req_finalize_data_integrity(or, has_in, has_out, cap_key); 989345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh if (ret) 990345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh return ret; 991345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 992345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh osd_sec_sign_cdb(&or->cdb, cap_key); 993345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 99402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->request->cmd = or->cdb.buff; 99502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->request->cmd_len = _osd_req_cdb_len(or); 99602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 99702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return 0; 99802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 99902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_finalize_request); 100002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 100102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* 100202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Implementation of osd_sec.h API 100302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * TODO: Move to a separate osd_sec.c file at a later stage. 100402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 100502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 100602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshenum { OSD_SEC_CAP_V1_ALL_CAPS = 100702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_SEC_CAP_APPEND | OSD_SEC_CAP_OBJ_MGMT | OSD_SEC_CAP_REMOVE | 100802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_SEC_CAP_CREATE | OSD_SEC_CAP_SET_ATTR | OSD_SEC_CAP_GET_ATTR | 100902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_SEC_CAP_WRITE | OSD_SEC_CAP_READ | OSD_SEC_CAP_POL_SEC | 101002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_SEC_CAP_GLOBAL | OSD_SEC_CAP_DEV_MGMT 101102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}; 101202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 101302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_sec_init_nosec_doall_caps(void *caps, 101402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh const struct osd_obj_id *obj, bool is_collection, const bool is_v1) 101502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 101602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct osd_capability *cap = caps; 101702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh u8 type; 101802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh u8 descriptor_type; 101902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 102002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (likely(obj->id)) { 102102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (unlikely(is_collection)) { 102202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh type = OSD_SEC_OBJ_COLLECTION; 102302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh descriptor_type = is_v1 ? OSD_SEC_OBJ_DESC_OBJ : 102402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_SEC_OBJ_DESC_COL; 102502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } else { 102602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh type = OSD_SEC_OBJ_USER; 102702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh descriptor_type = OSD_SEC_OBJ_DESC_OBJ; 102802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 102902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh WARN_ON(!obj->partition); 103002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } else { 103102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh type = obj->partition ? OSD_SEC_OBJ_PARTITION : 103202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_SEC_OBJ_ROOT; 103302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh descriptor_type = OSD_SEC_OBJ_DESC_PAR; 103402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 103502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 103602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh memset(cap, 0, sizeof(*cap)); 103702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 103802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->h.format = OSD_SEC_CAP_FORMAT_VER1; 103902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->h.integrity_algorithm__key_version = 0; /* MAKE_BYTE(0, 0); */ 104002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->h.security_method = OSD_SEC_NOSEC; 104102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* cap->expiration_time; 104202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->AUDIT[30-10]; 104302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->discriminator[42-30]; 104402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->object_created_time; */ 104502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->h.object_type = type; 104602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osd_sec_set_caps(&cap->h, OSD_SEC_CAP_V1_ALL_CAPS); 104702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->h.object_descriptor_type = descriptor_type; 104802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->od.obj_desc.policy_access_tag = 0; 104902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->od.obj_desc.allowed_partition_id = cpu_to_be64(obj->partition); 105002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->od.obj_desc.allowed_object_id = cpu_to_be64(obj->id); 105102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 105202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_sec_init_nosec_doall_caps); 105302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 105402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_set_caps(struct osd_cdb *cdb, const void *caps) 105502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 105602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh memcpy(&cdb->v1.caps, caps, OSDv1_CAP_LEN); 105702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 10584ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 1059345c435dbb0b77b00ffe73801102533e24c647afBoaz Harroshbool osd_is_sec_alldata(struct osd_security_parameters *sec_parms __unused) 1060345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh{ 1061345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh return false; 1062345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh} 1063345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 1064345c435dbb0b77b00ffe73801102533e24c647afBoaz Harroshvoid osd_sec_sign_cdb(struct osd_cdb *ocdb __unused, const u8 *cap_key __unused) 1065345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh{ 1066345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh} 1067345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 1068345c435dbb0b77b00ffe73801102533e24c647afBoaz Harroshvoid osd_sec_sign_data(void *data_integ __unused, 1069345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh struct bio *bio __unused, const u8 *cap_key __unused) 1070345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh{ 1071345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh} 1072345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 10734ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh/* 10744ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * Declared in osd_protocol.h 10754ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * 4.12.5 Data-In and Data-Out buffer offsets 10764ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * byte offset = mantissa * (2^(exponent+8)) 10774ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * Returns the smallest allowed encoded offset that contains given @offset 10784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * The actual encoded offset returned is @offset + *@padding. 10794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh */ 10804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshosd_cdb_offset __osd_encode_offset( 10814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh u64 offset, unsigned *padding, int min_shift, int max_shift) 10824ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 10834ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh u64 try_offset = -1, mod, align; 10844ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh osd_cdb_offset be32_offset; 10854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int shift; 10864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 10874ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh *padding = 0; 10884ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!offset) 10894ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 10904ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 10914ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh for (shift = min_shift; shift < max_shift; ++shift) { 10924ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh try_offset = offset >> shift; 10934ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (try_offset < (1 << OSD_OFFSET_MAX_BITS)) 10944ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh break; 10954ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 10964ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 10974ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh BUG_ON(shift == max_shift); 10984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 10994ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh align = 1 << shift; 11004ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh mod = offset & (align - 1); 11014ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (mod) { 11024ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh *padding = align - mod; 11034ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh try_offset += 1; 11044ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 11054ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 11064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh try_offset |= ((shift - 8) & 0xf) << 28; 11074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh be32_offset = cpu_to_be32((u32)try_offset); 11084ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 11094ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("offset=%llu mantissa=%llu exp=%d encoded=%x pad=%d\n", 11104ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _LLU(offset), _LLU(try_offset & 0x0FFFFFFF), shift, 11114ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh be32_offset, *padding); 11124ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return be32_offset; 11134ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 1114