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: 10aa281ac631008b9c18c405c8880007789f659c7dBoaz Harrosh * Boaz Harrosh <ooo@electrozaur.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 425a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 43acf3368ffb75fc4a83726655d697e79646fe4eb3Paul Gortmaker#include <linux/module.h> 445a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo 4502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh#include <scsi/osd_initiator.h> 4602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh#include <scsi/osd_sec.h> 471b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh#include <scsi/osd_attributes.h> 4898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh#include <scsi/osd_sense.h> 4998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 5002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh#include <scsi/scsi_device.h> 5102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 5202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh#include "osd_debug.h" 5302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh#ifndef __unused 554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh# define __unused __attribute__((unused)) 564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh#endif 574ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshenum { OSD_REQ_RETRIES = 1 }; 5902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 60aa281ac631008b9c18c405c8880007789f659c7dBoaz HarroshMODULE_AUTHOR("Boaz Harrosh <ooo@electrozaur.com>"); 6102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshMODULE_DESCRIPTION("open-osd initiator library libosd.ko"); 6202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshMODULE_LICENSE("GPL"); 6302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 6402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic inline void build_test(void) 6502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 6602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh /* structures were not packed */ 6702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh BUILD_BUG_ON(sizeof(struct osd_capability) != OSD_CAP_LEN); 68c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh BUILD_BUG_ON(sizeof(struct osdv2_cdb) != OSD_TOTAL_CDB_LEN); 6902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh BUILD_BUG_ON(sizeof(struct osdv1_cdb) != OSDv1_TOTAL_CDB_LEN); 7002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 7102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 721b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harroshstatic const char *_osd_ver_desc(struct osd_request *or) 731b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh{ 741b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh return osd_req_is_ver1(or) ? "OSD1" : "OSD2"; 751b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh} 761b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 771b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh#define ATTR_DEF_RI(id, len) ATTR_DEF(OSD_APAGE_ROOT_INFORMATION, id, len) 781b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 792cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harroshstatic int _osd_get_print_system_info(struct osd_dev *od, 802cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh void *caps, struct osd_dev_info *odi) 811b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh{ 821b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh struct osd_request *or; 831b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh struct osd_attr get_attrs[] = { 841b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh ATTR_DEF_RI(OSD_ATTR_RI_VENDOR_IDENTIFICATION, 8), 851b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_IDENTIFICATION, 16), 861b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_MODEL, 32), 871b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_REVISION_LEVEL, 4), 881b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_SERIAL_NUMBER, 64 /*variable*/), 891b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh ATTR_DEF_RI(OSD_ATTR_RI_OSD_NAME, 64 /*variable*/), 901b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh ATTR_DEF_RI(OSD_ATTR_RI_TOTAL_CAPACITY, 8), 911b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh ATTR_DEF_RI(OSD_ATTR_RI_USED_CAPACITY, 8), 921b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh ATTR_DEF_RI(OSD_ATTR_RI_NUMBER_OF_PARTITIONS, 8), 931b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh ATTR_DEF_RI(OSD_ATTR_RI_CLOCK, 6), 941b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh /* IBM-OSD-SIM Has a bug with this one put it last */ 951b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh ATTR_DEF_RI(OSD_ATTR_RI_OSD_SYSTEM_ID, 20), 961b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh }; 971b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh void *iter = NULL, *pFirst; 981b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh int nelem = ARRAY_SIZE(get_attrs), a = 0; 991b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh int ret; 1001b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 1011b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh or = osd_start_request(od, GFP_KERNEL); 1021b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh if (!or) 1031b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh return -ENOMEM; 1041b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 1051b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh /* get attrs */ 1061b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh osd_req_get_attributes(or, &osd_root_object); 1071b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh osd_req_add_get_attr_list(or, get_attrs, ARRAY_SIZE(get_attrs)); 1081b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 1091b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh ret = osd_finalize_request(or, 0, caps, NULL); 1101b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh if (ret) 1111b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh goto out; 1121b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 1131b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh ret = osd_execute_request(or); 1141b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh if (ret) { 1151b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh OSD_ERR("Failed to detect %s => %d\n", _osd_ver_desc(or), ret); 1161b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh goto out; 1171b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh } 1181b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 1191b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh osd_req_decode_get_attr_list(or, get_attrs, &nelem, &iter); 1201b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 1211b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh OSD_INFO("Detected %s device\n", 1221b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh _osd_ver_desc(or)); 1231b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 1241b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh pFirst = get_attrs[a++].val_ptr; 125de6b20385b1c14f97ccdf7da173b4c9a7405083bBoaz Harrosh OSD_INFO("VENDOR_IDENTIFICATION [%s]\n", 1261b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh (char *)pFirst); 1271b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 1281b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh pFirst = get_attrs[a++].val_ptr; 129de6b20385b1c14f97ccdf7da173b4c9a7405083bBoaz Harrosh OSD_INFO("PRODUCT_IDENTIFICATION [%s]\n", 1301b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh (char *)pFirst); 1311b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 1321b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh pFirst = get_attrs[a++].val_ptr; 133de6b20385b1c14f97ccdf7da173b4c9a7405083bBoaz Harrosh OSD_INFO("PRODUCT_MODEL [%s]\n", 1341b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh (char *)pFirst); 1351b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 1361b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh pFirst = get_attrs[a++].val_ptr; 137de6b20385b1c14f97ccdf7da173b4c9a7405083bBoaz Harrosh OSD_INFO("PRODUCT_REVISION_LEVEL [%u]\n", 13897218a1499391b174ea95e05b7a40fbb73e79813Boaz Harrosh pFirst ? get_unaligned_be32(pFirst) : ~0U); 1391b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 1401b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh pFirst = get_attrs[a++].val_ptr; 141de6b20385b1c14f97ccdf7da173b4c9a7405083bBoaz Harrosh OSD_INFO("PRODUCT_SERIAL_NUMBER [%s]\n", 1421b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh (char *)pFirst); 1431b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 1442cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh odi->osdname_len = get_attrs[a].len; 1452cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh /* Avoid NULL for memcmp optimization 0-length is good enough */ 1462cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh odi->osdname = kzalloc(odi->osdname_len + 1, GFP_KERNEL); 1476d1f6621fa12800fc84f62db9e0b7a6b623eb439Dan Carpenter if (!odi->osdname) { 1486d1f6621fa12800fc84f62db9e0b7a6b623eb439Dan Carpenter ret = -ENOMEM; 1496d1f6621fa12800fc84f62db9e0b7a6b623eb439Dan Carpenter goto out; 1506d1f6621fa12800fc84f62db9e0b7a6b623eb439Dan Carpenter } 1512cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh if (odi->osdname_len) 1522cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh memcpy(odi->osdname, get_attrs[a].val_ptr, odi->osdname_len); 1532cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh OSD_INFO("OSD_NAME [%s]\n", odi->osdname); 1541b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh a++; 1551b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 1561b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh pFirst = get_attrs[a++].val_ptr; 157de6b20385b1c14f97ccdf7da173b4c9a7405083bBoaz Harrosh OSD_INFO("TOTAL_CAPACITY [0x%llx]\n", 15897218a1499391b174ea95e05b7a40fbb73e79813Boaz Harrosh pFirst ? _LLU(get_unaligned_be64(pFirst)) : ~0ULL); 1591b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 1601b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh pFirst = get_attrs[a++].val_ptr; 161de6b20385b1c14f97ccdf7da173b4c9a7405083bBoaz Harrosh OSD_INFO("USED_CAPACITY [0x%llx]\n", 16297218a1499391b174ea95e05b7a40fbb73e79813Boaz Harrosh pFirst ? _LLU(get_unaligned_be64(pFirst)) : ~0ULL); 1631b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 1641b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh pFirst = get_attrs[a++].val_ptr; 165de6b20385b1c14f97ccdf7da173b4c9a7405083bBoaz Harrosh OSD_INFO("NUMBER_OF_PARTITIONS [%llu]\n", 16697218a1499391b174ea95e05b7a40fbb73e79813Boaz Harrosh pFirst ? _LLU(get_unaligned_be64(pFirst)) : ~0ULL); 16797218a1499391b174ea95e05b7a40fbb73e79813Boaz Harrosh 16897218a1499391b174ea95e05b7a40fbb73e79813Boaz Harrosh if (a >= nelem) 16997218a1499391b174ea95e05b7a40fbb73e79813Boaz Harrosh goto out; 1701b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 1711b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh /* FIXME: Where are the time utilities */ 1721b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh pFirst = get_attrs[a++].val_ptr; 173de6b20385b1c14f97ccdf7da173b4c9a7405083bBoaz Harrosh OSD_INFO("CLOCK [0x%02x%02x%02x%02x%02x%02x]\n", 1741b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh ((char *)pFirst)[0], ((char *)pFirst)[1], 1751b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh ((char *)pFirst)[2], ((char *)pFirst)[3], 1761b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh ((char *)pFirst)[4], ((char *)pFirst)[5]); 1771b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 1781b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh if (a < nelem) { /* IBM-OSD-SIM bug, Might not have it */ 1791b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh unsigned len = get_attrs[a].len; 1801b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh char sid_dump[32*4 + 2]; /* 2nibbles+space+ASCII */ 1811b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 1821b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh hex_dump_to_buffer(get_attrs[a].val_ptr, len, 32, 1, 1831b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh sid_dump, sizeof(sid_dump), true); 184de6b20385b1c14f97ccdf7da173b4c9a7405083bBoaz Harrosh OSD_INFO("OSD_SYSTEM_ID(%d)\n" 185de6b20385b1c14f97ccdf7da173b4c9a7405083bBoaz Harrosh " [%s]\n", len, sid_dump); 1862cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh 1872cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh if (unlikely(len > sizeof(odi->systemid))) { 1882cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh OSD_ERR("OSD Target error: OSD_SYSTEM_ID too long(%d). " 1892cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh "device idetification might not work\n", len); 1902cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh len = sizeof(odi->systemid); 1912cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh } 1922cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh odi->systemid_len = len; 1932cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh memcpy(odi->systemid, get_attrs[a].val_ptr, len); 1941b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh a++; 1951b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh } 1961b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harroshout: 1971b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh osd_end_request(or); 1981b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh return ret; 1991b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh} 2001b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 2012cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harroshint osd_auto_detect_ver(struct osd_dev *od, 2022cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh void *caps, struct osd_dev_info *odi) 2031b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh{ 2041b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh int ret; 2051b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 2061b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh /* Auto-detect the osd version */ 2072cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh ret = _osd_get_print_system_info(od, caps, odi); 2081b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh if (ret) { 2091b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh osd_dev_set_ver(od, OSD_VER1); 2101b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh OSD_DEBUG("converting to OSD1\n"); 2112cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh ret = _osd_get_print_system_info(od, caps, odi); 2121b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh } 2131b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 2141b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh return ret; 2151b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh} 2161b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz HarroshEXPORT_SYMBOL(osd_auto_detect_ver); 2171b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh 21802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic unsigned _osd_req_cdb_len(struct osd_request *or) 21902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 220c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh return osd_req_is_ver1(or) ? OSDv1_TOTAL_CDB_LEN : OSD_TOTAL_CDB_LEN; 22102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 22202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 2234ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic unsigned _osd_req_alist_elem_size(struct osd_request *or, unsigned len) 2244ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 225c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh return osd_req_is_ver1(or) ? 226c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh osdv1_attr_list_elem_size(len) : 227c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh osdv2_attr_list_elem_size(len); 2284ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 2294ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 23071f32e31e5638df37904697e2d04182935add85dBoaz Harroshstatic void _osd_req_alist_elem_encode(struct osd_request *or, 23171f32e31e5638df37904697e2d04182935add85dBoaz Harrosh void *attr_last, const struct osd_attr *oa) 23271f32e31e5638df37904697e2d04182935add85dBoaz Harrosh{ 23371f32e31e5638df37904697e2d04182935add85dBoaz Harrosh if (osd_req_is_ver1(or)) { 23471f32e31e5638df37904697e2d04182935add85dBoaz Harrosh struct osdv1_attributes_list_element *attr = attr_last; 23571f32e31e5638df37904697e2d04182935add85dBoaz Harrosh 23671f32e31e5638df37904697e2d04182935add85dBoaz Harrosh attr->attr_page = cpu_to_be32(oa->attr_page); 23771f32e31e5638df37904697e2d04182935add85dBoaz Harrosh attr->attr_id = cpu_to_be32(oa->attr_id); 23871f32e31e5638df37904697e2d04182935add85dBoaz Harrosh attr->attr_bytes = cpu_to_be16(oa->len); 23971f32e31e5638df37904697e2d04182935add85dBoaz Harrosh memcpy(attr->attr_val, oa->val_ptr, oa->len); 24071f32e31e5638df37904697e2d04182935add85dBoaz Harrosh } else { 24171f32e31e5638df37904697e2d04182935add85dBoaz Harrosh struct osdv2_attributes_list_element *attr = attr_last; 24271f32e31e5638df37904697e2d04182935add85dBoaz Harrosh 24371f32e31e5638df37904697e2d04182935add85dBoaz Harrosh attr->attr_page = cpu_to_be32(oa->attr_page); 24471f32e31e5638df37904697e2d04182935add85dBoaz Harrosh attr->attr_id = cpu_to_be32(oa->attr_id); 24571f32e31e5638df37904697e2d04182935add85dBoaz Harrosh attr->attr_bytes = cpu_to_be16(oa->len); 24671f32e31e5638df37904697e2d04182935add85dBoaz Harrosh memcpy(attr->attr_val, oa->val_ptr, oa->len); 24771f32e31e5638df37904697e2d04182935add85dBoaz Harrosh } 24871f32e31e5638df37904697e2d04182935add85dBoaz Harrosh} 24971f32e31e5638df37904697e2d04182935add85dBoaz Harrosh 25071f32e31e5638df37904697e2d04182935add85dBoaz Harroshstatic int _osd_req_alist_elem_decode(struct osd_request *or, 25171f32e31e5638df37904697e2d04182935add85dBoaz Harrosh void *cur_p, struct osd_attr *oa, unsigned max_bytes) 25271f32e31e5638df37904697e2d04182935add85dBoaz Harrosh{ 25371f32e31e5638df37904697e2d04182935add85dBoaz Harrosh unsigned inc; 25471f32e31e5638df37904697e2d04182935add85dBoaz Harrosh if (osd_req_is_ver1(or)) { 25571f32e31e5638df37904697e2d04182935add85dBoaz Harrosh struct osdv1_attributes_list_element *attr = cur_p; 25671f32e31e5638df37904697e2d04182935add85dBoaz Harrosh 25771f32e31e5638df37904697e2d04182935add85dBoaz Harrosh if (max_bytes < sizeof(*attr)) 25871f32e31e5638df37904697e2d04182935add85dBoaz Harrosh return -1; 25971f32e31e5638df37904697e2d04182935add85dBoaz Harrosh 26071f32e31e5638df37904697e2d04182935add85dBoaz Harrosh oa->len = be16_to_cpu(attr->attr_bytes); 26171f32e31e5638df37904697e2d04182935add85dBoaz Harrosh inc = _osd_req_alist_elem_size(or, oa->len); 26271f32e31e5638df37904697e2d04182935add85dBoaz Harrosh if (inc > max_bytes) 26371f32e31e5638df37904697e2d04182935add85dBoaz Harrosh return -1; 26471f32e31e5638df37904697e2d04182935add85dBoaz Harrosh 26571f32e31e5638df37904697e2d04182935add85dBoaz Harrosh oa->attr_page = be32_to_cpu(attr->attr_page); 26671f32e31e5638df37904697e2d04182935add85dBoaz Harrosh oa->attr_id = be32_to_cpu(attr->attr_id); 26771f32e31e5638df37904697e2d04182935add85dBoaz Harrosh 26871f32e31e5638df37904697e2d04182935add85dBoaz Harrosh /* OSD1: On empty attributes we return a pointer to 2 bytes 26971f32e31e5638df37904697e2d04182935add85dBoaz Harrosh * of zeros. This keeps similar behaviour with OSD2. 27071f32e31e5638df37904697e2d04182935add85dBoaz Harrosh * (See below) 27171f32e31e5638df37904697e2d04182935add85dBoaz Harrosh */ 27271f32e31e5638df37904697e2d04182935add85dBoaz Harrosh oa->val_ptr = likely(oa->len) ? attr->attr_val : 27371f32e31e5638df37904697e2d04182935add85dBoaz Harrosh (u8 *)&attr->attr_bytes; 27471f32e31e5638df37904697e2d04182935add85dBoaz Harrosh } else { 27571f32e31e5638df37904697e2d04182935add85dBoaz Harrosh struct osdv2_attributes_list_element *attr = cur_p; 27671f32e31e5638df37904697e2d04182935add85dBoaz Harrosh 27771f32e31e5638df37904697e2d04182935add85dBoaz Harrosh if (max_bytes < sizeof(*attr)) 27871f32e31e5638df37904697e2d04182935add85dBoaz Harrosh return -1; 27971f32e31e5638df37904697e2d04182935add85dBoaz Harrosh 28071f32e31e5638df37904697e2d04182935add85dBoaz Harrosh oa->len = be16_to_cpu(attr->attr_bytes); 28171f32e31e5638df37904697e2d04182935add85dBoaz Harrosh inc = _osd_req_alist_elem_size(or, oa->len); 28271f32e31e5638df37904697e2d04182935add85dBoaz Harrosh if (inc > max_bytes) 28371f32e31e5638df37904697e2d04182935add85dBoaz Harrosh return -1; 28471f32e31e5638df37904697e2d04182935add85dBoaz Harrosh 28571f32e31e5638df37904697e2d04182935add85dBoaz Harrosh oa->attr_page = be32_to_cpu(attr->attr_page); 28671f32e31e5638df37904697e2d04182935add85dBoaz Harrosh oa->attr_id = be32_to_cpu(attr->attr_id); 28771f32e31e5638df37904697e2d04182935add85dBoaz Harrosh 288e9da4d7f731dafc2b93ce7b31aa09c4d935ef978Boaz Harrosh /* OSD2: For convenience, on empty attributes, we return 8 bytes 289e9da4d7f731dafc2b93ce7b31aa09c4d935ef978Boaz Harrosh * of zeros here. This keeps the same behaviour with OSD2r04, 290e9da4d7f731dafc2b93ce7b31aa09c4d935ef978Boaz Harrosh * and is nice with null terminating ASCII fields. 291e9da4d7f731dafc2b93ce7b31aa09c4d935ef978Boaz Harrosh * oa->val_ptr == NULL marks the end-of-list, or error. 292e9da4d7f731dafc2b93ce7b31aa09c4d935ef978Boaz Harrosh */ 293e9da4d7f731dafc2b93ce7b31aa09c4d935ef978Boaz Harrosh oa->val_ptr = likely(oa->len) ? attr->attr_val : attr->reserved; 29471f32e31e5638df37904697e2d04182935add85dBoaz Harrosh } 29571f32e31e5638df37904697e2d04182935add85dBoaz Harrosh return inc; 29671f32e31e5638df37904697e2d04182935add85dBoaz Harrosh} 29771f32e31e5638df37904697e2d04182935add85dBoaz Harrosh 2984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic unsigned _osd_req_alist_size(struct osd_request *or, void *list_head) 2994ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 300c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh return osd_req_is_ver1(or) ? 301c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh osdv1_list_size(list_head) : 302c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh osdv2_list_size(list_head); 3034ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 3044ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 3054ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic unsigned _osd_req_sizeof_alist_header(struct osd_request *or) 3064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 307c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh return osd_req_is_ver1(or) ? 308c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh sizeof(struct osdv1_attributes_list_header) : 309c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh sizeof(struct osdv2_attributes_list_header); 3104ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 3114ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 3124ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic void _osd_req_set_alist_type(struct osd_request *or, 3134ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh void *list, int list_type) 3144ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 315c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh if (osd_req_is_ver1(or)) { 316c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh struct osdv1_attributes_list_header *attr_list = list; 317c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh 318c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh memset(attr_list, 0, sizeof(*attr_list)); 319c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh attr_list->type = list_type; 320c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh } else { 321c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh struct osdv2_attributes_list_header *attr_list = list; 3224ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 323c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh memset(attr_list, 0, sizeof(*attr_list)); 324c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh attr_list->type = list_type; 325c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh } 3264ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 3274ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 3284ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic bool _osd_req_is_alist_type(struct osd_request *or, 3294ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh void *list, int list_type) 3304ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 3314ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!list) 3324ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return false; 3334ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 334c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh if (osd_req_is_ver1(or)) { 3354ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osdv1_attributes_list_header *attr_list = list; 3364ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 3374ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return attr_list->type == list_type; 338c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh } else { 339c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh struct osdv2_attributes_list_header *attr_list = list; 340c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh 341c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh return attr_list->type == list_type; 3424ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 3434ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 3444ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 3453e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh/* This is for List-objects not Attributes-Lists */ 3463e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harroshstatic void _osd_req_encode_olist(struct osd_request *or, 3473e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh struct osd_obj_id_list *list) 3483e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh{ 3493e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 3503e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh 351c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh if (osd_req_is_ver1(or)) { 352c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh cdbh->v1.list_identifier = list->list_identifier; 353c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh cdbh->v1.start_address = list->continuation_id; 354c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh } else { 355c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh cdbh->v2.list_identifier = list->list_identifier; 356c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh cdbh->v2.start_address = list->continuation_id; 357c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh } 3583e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh} 3593e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh 3604ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic osd_cdb_offset osd_req_encode_offset(struct osd_request *or, 3614ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh u64 offset, unsigned *padding) 3624ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 3634ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return __osd_encode_offset(offset, padding, 364c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh osd_req_is_ver1(or) ? 365c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh OSDv1_OFFSET_MIN_SHIFT : OSD_OFFSET_MIN_SHIFT, 366c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh OSD_OFFSET_MAX_SHIFT); 3674ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 3684ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 369345c435dbb0b77b00ffe73801102533e24c647afBoaz Harroshstatic struct osd_security_parameters * 370345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh_osd_req_sec_params(struct osd_request *or) 371345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh{ 372345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh struct osd_cdb *ocdb = &or->cdb; 373345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 374c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh if (osd_req_is_ver1(or)) 375f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh return (struct osd_security_parameters *)&ocdb->v1.sec_params; 376c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh else 377f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh return (struct osd_security_parameters *)&ocdb->v2.sec_params; 378345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh} 379345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 38002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_dev_init(struct osd_dev *osdd, struct scsi_device *scsi_device) 38102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 38202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh memset(osdd, 0, sizeof(*osdd)); 38302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osdd->scsi_device = scsi_device; 38402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osdd->def_timeout = BLK_DEFAULT_SG_TIMEOUT; 385c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh#ifdef OSD_VER1_SUPPORT 386c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh osdd->version = OSD_VER2; 387c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh#endif 38802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh /* TODO: Allocate pools for osd_request attributes ... */ 38902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 39002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_dev_init); 39102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 39202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_dev_fini(struct osd_dev *osdd) 39302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 39402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh /* TODO: De-allocate pools */ 39502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 39602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osdd->scsi_device = NULL; 39702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 39802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_dev_fini); 39902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 40002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic struct osd_request *_osd_request_alloc(gfp_t gfp) 40102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 40202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct osd_request *or; 40302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 40402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh /* TODO: Use mempool with one saved request */ 40502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or = kzalloc(sizeof(*or), gfp); 40602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return or; 40702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 40802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 40902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic void _osd_request_free(struct osd_request *or) 41002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 41102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh kfree(or); 41202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 41302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 41402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstruct osd_request *osd_start_request(struct osd_dev *dev, gfp_t gfp) 41502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 41602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct osd_request *or; 41702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 41802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or = _osd_request_alloc(gfp); 41902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (!or) 42002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return NULL; 42102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 42202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->osd_dev = dev; 42302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->alloc_flags = gfp; 42402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->timeout = dev->def_timeout; 42502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->retries = OSD_REQ_RETRIES; 42602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 42702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return or; 42802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 42902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_start_request); 43002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 4314ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic void _osd_free_seg(struct osd_request *or __unused, 4324ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct _osd_req_data_segment *seg) 4334ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 4344ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!seg->buff || !seg->alloc_size) 4354ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return; 4364ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4374ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh kfree(seg->buff); 4384ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh seg->buff = NULL; 4394ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh seg->alloc_size = 0; 4404ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 4414ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 4425d0961fd1f25e117f907f3af3aaa870637049252Boaz Harroshstatic void _put_request(struct request *rq) 4438c0baccadc86d9f07e663dd255751dd70e461ba3Boaz Harrosh{ 4445d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh /* 4455d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh * If osd_finalize_request() was called but the request was not 4465d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh * executed through the block layer, then we must release BIOs. 4475d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh * TODO: Keep error code in or->async_error. Need to audit all 4485d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh * code paths. 4495d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh */ 4505d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh if (unlikely(rq->bio)) 4515d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh blk_end_request(rq, -ENOMEM, blk_rq_bytes(rq)); 4525d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh else 4535d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh blk_put_request(rq); 4548c0baccadc86d9f07e663dd255751dd70e461ba3Boaz Harrosh} 4558c0baccadc86d9f07e663dd255751dd70e461ba3Boaz Harrosh 45602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_end_request(struct osd_request *or) 45702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 45802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct request *rq = or->request; 45902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 46002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (rq) { 46102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (rq->next_rq) { 4625d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh _put_request(rq->next_rq); 4638c0baccadc86d9f07e663dd255751dd70e461ba3Boaz Harrosh rq->next_rq = NULL; 46402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 46502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 4665d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh _put_request(rq); 46702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 468c4df46c49d8677158c7fb070a08e0d386c80205fBoaz Harrosh 469c4df46c49d8677158c7fb070a08e0d386c80205fBoaz Harrosh _osd_free_seg(or, &or->get_attr); 470c4df46c49d8677158c7fb070a08e0d386c80205fBoaz Harrosh _osd_free_seg(or, &or->enc_get_attr); 471c4df46c49d8677158c7fb070a08e0d386c80205fBoaz Harrosh _osd_free_seg(or, &or->set_attr); 472e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh _osd_free_seg(or, &or->cdb_cont); 473c4df46c49d8677158c7fb070a08e0d386c80205fBoaz Harrosh 47402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_request_free(or); 47502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 47602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_end_request); 47702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 4785d0961fd1f25e117f907f3af3aaa870637049252Boaz Harroshstatic void _set_error_resid(struct osd_request *or, struct request *req, 4795d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh int error) 4805d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh{ 4815d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh or->async_error = error; 4825d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh or->req_errors = req->errors ? : error; 4835d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh or->sense_len = req->sense_len; 4845d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh if (or->out.req) 4855d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh or->out.residual = or->out.req->resid_len; 4865d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh if (or->in.req) 4875d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh or->in.residual = or->in.req->resid_len; 4885d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh} 4895d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh 49002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshint osd_execute_request(struct osd_request *or) 49102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 4925d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh int error = blk_execute_rq(or->request->q, NULL, or->request, 0); 4935d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh 4945d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh _set_error_resid(or, or->request, error); 4955d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh return error; 49602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 49702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_execute_request); 49802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 49902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic void osd_request_async_done(struct request *req, int error) 50002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 50102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct osd_request *or = req->end_io_data; 50202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 5035d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh _set_error_resid(or, req, error); 5045d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh if (req->next_rq) { 5055d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh __blk_put_request(req->q, req->next_rq); 5065d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh req->next_rq = NULL; 507aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh } 50802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 5095d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh __blk_put_request(req->q, req); 5105d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh or->request = NULL; 5115d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh or->in.req = NULL; 5125d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh or->out.req = NULL; 5135d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh 51402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (or->async_done) 51502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->async_done(or, or->async_private); 51602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh else 51702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osd_end_request(or); 51802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 51902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 52002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshint osd_execute_request_async(struct osd_request *or, 52102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osd_req_done_fn *done, void *private) 52202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 52302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->request->end_io_data = or; 52402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->async_private = private; 52502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->async_done = done; 52602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 52702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh blk_execute_rq_nowait(or->request->q, NULL, or->request, 0, 52802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osd_request_async_done); 52902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return 0; 53002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 53102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_execute_request_async); 53202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 5334ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshu8 sg_out_pad_buffer[1 << OSDv1_OFFSET_MIN_SHIFT]; 5344ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshu8 sg_in_pad_buffer[1 << OSDv1_OFFSET_MIN_SHIFT]; 5354ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5364ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _osd_realloc_seg(struct osd_request *or, 5374ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct _osd_req_data_segment *seg, unsigned max_bytes) 5384ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 5394ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh void *buff; 5404ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5414ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (seg->alloc_size >= max_bytes) 5424ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 5434ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5444ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh buff = krealloc(seg->buff, max_bytes, or->alloc_flags); 5454ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!buff) { 5464ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_ERR("Failed to Realloc %d-bytes was-%d\n", max_bytes, 5474ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh seg->alloc_size); 5484ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return -ENOMEM; 5494ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 5504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh memset(buff + seg->alloc_size, 0, max_bytes - seg->alloc_size); 5524ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh seg->buff = buff; 5534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh seg->alloc_size = max_bytes; 5544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 5554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 5564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 557e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harroshstatic int _alloc_cdb_cont(struct osd_request *or, unsigned total_bytes) 558e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh{ 559e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh OSD_DEBUG("total_bytes=%d\n", total_bytes); 560e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh return _osd_realloc_seg(or, &or->cdb_cont, total_bytes); 561e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh} 562e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh 5634ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _alloc_set_attr_list(struct osd_request *or, 5644ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const struct osd_attr *oa, unsigned nelem, unsigned add_bytes) 5654ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 5664ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned total_bytes = add_bytes; 5674ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5684ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh for (; nelem; --nelem, ++oa) 5694ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh total_bytes += _osd_req_alist_elem_size(or, oa->len); 5704ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5714ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("total_bytes=%d\n", total_bytes); 5724ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return _osd_realloc_seg(or, &or->set_attr, total_bytes); 5734ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 5744ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5754ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _alloc_get_attr_desc(struct osd_request *or, unsigned max_bytes) 5764ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 5774ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("total_bytes=%d\n", max_bytes); 5784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return _osd_realloc_seg(or, &or->enc_get_attr, max_bytes); 5794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 5804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 5814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _alloc_get_attr_list(struct osd_request *or) 5824ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 5834ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("total_bytes=%d\n", or->get_attr.total_bytes); 5844ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return _osd_realloc_seg(or, &or->get_attr, or->get_attr.total_bytes); 5854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 5864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 58702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* 58802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Common to all OSD commands 58902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 59002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 59102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic void _osdv1_req_encode_common(struct osd_request *or, 59202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh __be16 act, const struct osd_obj_id *obj, u64 offset, u64 len) 59302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 59402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct osdv1_cdb *ocdb = &or->cdb.v1; 59502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 59602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh /* 59702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * For speed, the commands 59802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * OSD_ACT_PERFORM_SCSI_COMMAND , V1 0x8F7E, V2 0x8F7C 59902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * OSD_ACT_SCSI_TASK_MANAGEMENT , V1 0x8F7F, V2 0x8F7D 60002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * are not supported here. Should pass zero and set after the call 60102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 60202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh act &= cpu_to_be16(~0x0080); /* V1 action code */ 60302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 60402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_DEBUG("OSDv1 execute opcode 0x%x\n", be16_to_cpu(act)); 60502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 60602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ocdb->h.varlen_cdb.opcode = VARIABLE_LENGTH_CMD; 60702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ocdb->h.varlen_cdb.additional_cdb_length = OSD_ADDITIONAL_CDB_LENGTH; 60802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ocdb->h.varlen_cdb.service_action = act; 60902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 61002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ocdb->h.partition = cpu_to_be64(obj->partition); 61102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ocdb->h.object = cpu_to_be64(obj->id); 61202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ocdb->h.v1.length = cpu_to_be64(len); 61302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ocdb->h.v1.start_address = cpu_to_be64(offset); 61402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 61502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 616c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harroshstatic void _osdv2_req_encode_common(struct osd_request *or, 617c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh __be16 act, const struct osd_obj_id *obj, u64 offset, u64 len) 618c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh{ 619c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh struct osdv2_cdb *ocdb = &or->cdb.v2; 620c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh 621c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh OSD_DEBUG("OSDv2 execute opcode 0x%x\n", be16_to_cpu(act)); 622c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh 623c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh ocdb->h.varlen_cdb.opcode = VARIABLE_LENGTH_CMD; 624c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh ocdb->h.varlen_cdb.additional_cdb_length = OSD_ADDITIONAL_CDB_LENGTH; 625c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh ocdb->h.varlen_cdb.service_action = act; 626c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh 627c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh ocdb->h.partition = cpu_to_be64(obj->partition); 628c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh ocdb->h.object = cpu_to_be64(obj->id); 629c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh ocdb->h.v2.length = cpu_to_be64(len); 630c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh ocdb->h.v2.start_address = cpu_to_be64(offset); 631c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh} 632c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh 63302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic void _osd_req_encode_common(struct osd_request *or, 63402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh __be16 act, const struct osd_obj_id *obj, u64 offset, u64 len) 63502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 636c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh if (osd_req_is_ver1(or)) 637c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh _osdv1_req_encode_common(or, act, obj, offset, len); 638c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh else 639c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh _osdv2_req_encode_common(or, act, obj, offset, len); 64002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 64102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 64202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* 64302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Device commands 64402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 645ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_set_master_seed_xchg(struct osd_request *, ...); */ 646ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_set_master_key(struct osd_request *, ...); */ 647ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh 64802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_format(struct osd_request *or, u64 tot_capacity) 64902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 65002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_req_encode_common(or, OSD_ACT_FORMAT_OSD, &osd_root_object, 0, 65102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh tot_capacity); 65202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 65302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_format); 65402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 6553e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harroshint osd_req_list_dev_partitions(struct osd_request *or, 6563e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh osd_id initial_id, struct osd_obj_id_list *list, unsigned nelem) 6573e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh{ 6583e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh return osd_req_list_partition_objects(or, 0, initial_id, list, nelem); 6593e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh} 6603e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz HarroshEXPORT_SYMBOL(osd_req_list_dev_partitions); 6613e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh 6623e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harroshstatic void _osd_req_encode_flush(struct osd_request *or, 6633e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh enum osd_options_flush_scope_values op) 6643e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh{ 6653e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh struct osd_cdb_head *ocdb = osd_cdb_head(&or->cdb); 6663e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh 6673e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh ocdb->command_specific_options = op; 6683e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh} 6693e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh 6703e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harroshvoid osd_req_flush_obsd(struct osd_request *or, 6713e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh enum osd_options_flush_scope_values op) 6723e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh{ 6733e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh _osd_req_encode_common(or, OSD_ACT_FLUSH_OSD, &osd_root_object, 0, 0); 6743e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh _osd_req_encode_flush(or, op); 6753e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh} 6763e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz HarroshEXPORT_SYMBOL(osd_req_flush_obsd); 6773e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh 678ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_perform_scsi_command(struct osd_request *, 679ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh const u8 *cdb, ...); */ 680ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_task_management(struct osd_request *, ...); */ 681ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh 68202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* 68302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Partition commands 68402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 68502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic void _osd_req_encode_partition(struct osd_request *or, 68602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh __be16 act, osd_id partition) 68702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 68802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct osd_obj_id par = { 68902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh .partition = partition, 69002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh .id = 0, 69102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh }; 69202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 69302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_req_encode_common(or, act, &par, 0, 0); 69402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 69502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 69602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_create_partition(struct osd_request *or, osd_id partition) 69702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 69802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_req_encode_partition(or, OSD_ACT_CREATE_PARTITION, partition); 69902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 70002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_create_partition); 70102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 70202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_remove_partition(struct osd_request *or, osd_id partition) 70302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 70402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_req_encode_partition(or, OSD_ACT_REMOVE_PARTITION, partition); 70502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 70602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_remove_partition); 70702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 708ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_set_partition_key(struct osd_request *, 709ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh osd_id partition, u8 new_key_id[OSD_CRYPTO_KEYID_SIZE], 710ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh u8 seed[OSD_CRYPTO_SEED_SIZE]); */ 711ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh 7123e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harroshstatic int _osd_req_list_objects(struct osd_request *or, 7133e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh __be16 action, const struct osd_obj_id *obj, osd_id initial_id, 7143e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh struct osd_obj_id_list *list, unsigned nelem) 7153e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh{ 716fc2fac5b5f11e2bee3bf37215c8746236f5ea188Boaz Harrosh struct request_queue *q = osd_request_queue(or->osd_dev); 7173e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh u64 len = nelem * sizeof(osd_id) + sizeof(*list); 7183e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh struct bio *bio; 7193e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh 7203e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh _osd_req_encode_common(or, action, obj, (u64)initial_id, len); 7213e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh 7223e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh if (list->list_identifier) 7233e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh _osd_req_encode_olist(or, list); 7243e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh 7253e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh WARN_ON(or->in.bio); 7263e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh bio = bio_map_kern(q, list, len, or->alloc_flags); 727bf5e84f69618f416e89a5a53434a8c865e70252eDan Carpenter if (IS_ERR(bio)) { 7283e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh OSD_ERR("!!! Failed to allocate list_objects BIO\n"); 729bf5e84f69618f416e89a5a53434a8c865e70252eDan Carpenter return PTR_ERR(bio); 7303e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh } 7313e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh 7327b6d91daee5cac6402186ff224c3af39d79f4a0eChristoph Hellwig bio->bi_rw &= ~REQ_WRITE; 7333e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh or->in.bio = bio; 7344f024f3797c43cb4b73cd2c50cec728842d0e49eKent Overstreet or->in.total_bytes = bio->bi_iter.bi_size; 7353e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh return 0; 7363e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh} 7373e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh 7383e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harroshint osd_req_list_partition_collections(struct osd_request *or, 7393e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh osd_id partition, osd_id initial_id, struct osd_obj_id_list *list, 7403e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh unsigned nelem) 7413e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh{ 7423e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh struct osd_obj_id par = { 7433e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh .partition = partition, 7443e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh .id = 0, 7453e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh }; 7463e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh 7473e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh return osd_req_list_collection_objects(or, &par, initial_id, list, 7483e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh nelem); 7493e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh} 7503e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz HarroshEXPORT_SYMBOL(osd_req_list_partition_collections); 7513e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh 7523e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harroshint osd_req_list_partition_objects(struct osd_request *or, 7533e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh osd_id partition, osd_id initial_id, struct osd_obj_id_list *list, 7543e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh unsigned nelem) 7553e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh{ 7563e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh struct osd_obj_id par = { 7573e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh .partition = partition, 7583e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh .id = 0, 7593e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh }; 7603e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh 7613e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh return _osd_req_list_objects(or, OSD_ACT_LIST, &par, initial_id, list, 7623e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh nelem); 7633e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh} 7643e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz HarroshEXPORT_SYMBOL(osd_req_list_partition_objects); 7653e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh 7663e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harroshvoid osd_req_flush_partition(struct osd_request *or, 7673e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh osd_id partition, enum osd_options_flush_scope_values op) 7683e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh{ 7693e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh _osd_req_encode_partition(or, OSD_ACT_FLUSH_PARTITION, partition); 7703e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh _osd_req_encode_flush(or, op); 7713e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh} 7723e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz HarroshEXPORT_SYMBOL(osd_req_flush_partition); 7733e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh 7743e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh/* 7753e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh * Collection commands 7763e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh */ 777ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_create_collection(struct osd_request *, 778ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh const struct osd_obj_id *); */ 779ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_remove_collection(struct osd_request *, 780ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh const struct osd_obj_id *); */ 781ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh 7823e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harroshint osd_req_list_collection_objects(struct osd_request *or, 7833e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh const struct osd_obj_id *obj, osd_id initial_id, 7843e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh struct osd_obj_id_list *list, unsigned nelem) 7853e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh{ 7863e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh return _osd_req_list_objects(or, OSD_ACT_LIST_COLLECTION, obj, 7873e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh initial_id, list, nelem); 7883e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh} 7893e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz HarroshEXPORT_SYMBOL(osd_req_list_collection_objects); 7903e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh 791ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void query(struct osd_request *, ...); V2 */ 792ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh 7933e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harroshvoid osd_req_flush_collection(struct osd_request *or, 7943e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh const struct osd_obj_id *obj, enum osd_options_flush_scope_values op) 7953e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh{ 7963e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh _osd_req_encode_common(or, OSD_ACT_FLUSH_PARTITION, obj, 0, 0); 7973e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh _osd_req_encode_flush(or, op); 7983e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh} 7993e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz HarroshEXPORT_SYMBOL(osd_req_flush_collection); 8003e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh 801ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void get_member_attrs(struct osd_request *, ...); V2 */ 802ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void set_member_attrs(struct osd_request *, ...); V2 */ 803ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh 80402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* 80502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Object commands 80602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 80702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_create_object(struct osd_request *or, struct osd_obj_id *obj) 80802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 80902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_req_encode_common(or, OSD_ACT_CREATE, obj, 0, 0); 81002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 81102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_create_object); 81202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 81302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_remove_object(struct osd_request *or, struct osd_obj_id *obj) 81402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 81502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh _osd_req_encode_common(or, OSD_ACT_REMOVE, obj, 0, 0); 81602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 81702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_remove_object); 81802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 819ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh 820ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_create_multi(struct osd_request *or, 821ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh struct osd_obj_id *first, struct osd_obj_id_list *list, unsigned nelem); 822ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh*/ 823ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh 82402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_write(struct osd_request *or, 82562f469b596dd0aadf046a69027087c18db43734eBoaz Harrosh const struct osd_obj_id *obj, u64 offset, 82662f469b596dd0aadf046a69027087c18db43734eBoaz Harrosh struct bio *bio, u64 len) 82702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 82862f469b596dd0aadf046a69027087c18db43734eBoaz Harrosh _osd_req_encode_common(or, OSD_ACT_WRITE, obj, offset, len); 82902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh WARN_ON(or->out.bio || or->out.total_bytes); 8307b6d91daee5cac6402186ff224c3af39d79f4a0eChristoph Hellwig WARN_ON(0 == (bio->bi_rw & REQ_WRITE)); 83102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->out.bio = bio; 83262f469b596dd0aadf046a69027087c18db43734eBoaz Harrosh or->out.total_bytes = len; 83302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 83402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_write); 83502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 8360e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harroshint osd_req_write_kern(struct osd_request *or, 8370e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh const struct osd_obj_id *obj, u64 offset, void* buff, u64 len) 8380e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh{ 839fc2fac5b5f11e2bee3bf37215c8746236f5ea188Boaz Harrosh struct request_queue *req_q = osd_request_queue(or->osd_dev); 8400e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh struct bio *bio = bio_map_kern(req_q, buff, len, GFP_KERNEL); 8410e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh 8420e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh if (IS_ERR(bio)) 8430e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh return PTR_ERR(bio); 8440e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh 8457b6d91daee5cac6402186ff224c3af39d79f4a0eChristoph Hellwig bio->bi_rw |= REQ_WRITE; /* FIXME: bio_set_dir() */ 84662f469b596dd0aadf046a69027087c18db43734eBoaz Harrosh osd_req_write(or, obj, offset, bio, len); 8470e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh return 0; 8480e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh} 8490e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz HarroshEXPORT_SYMBOL(osd_req_write_kern); 8500e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh 851ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_append(struct osd_request *, 852ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh const struct osd_obj_id *, struct bio *data_out); */ 853ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_create_write(struct osd_request *, 854ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh const struct osd_obj_id *, struct bio *data_out, u64 offset); */ 855ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_clear(struct osd_request *, 856ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh const struct osd_obj_id *, u64 offset, u64 len); */ 857ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_punch(struct osd_request *, 858ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh const struct osd_obj_id *, u64 offset, u64 len); V2 */ 859ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh 8603e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harroshvoid osd_req_flush_object(struct osd_request *or, 8613e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh const struct osd_obj_id *obj, enum osd_options_flush_scope_values op, 8623e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh /*V2*/ u64 offset, /*V2*/ u64 len) 8633e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh{ 864c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh if (unlikely(osd_req_is_ver1(or) && (offset || len))) { 865c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh OSD_DEBUG("OSD Ver1 flush on specific range ignored\n"); 866c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh offset = 0; 867c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh len = 0; 868c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh } 869c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh 8703e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh _osd_req_encode_common(or, OSD_ACT_FLUSH, obj, offset, len); 8713e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh _osd_req_encode_flush(or, op); 8723e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh} 8733e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz HarroshEXPORT_SYMBOL(osd_req_flush_object); 8743e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh 87502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_read(struct osd_request *or, 87662f469b596dd0aadf046a69027087c18db43734eBoaz Harrosh const struct osd_obj_id *obj, u64 offset, 87762f469b596dd0aadf046a69027087c18db43734eBoaz Harrosh struct bio *bio, u64 len) 87802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 87962f469b596dd0aadf046a69027087c18db43734eBoaz Harrosh _osd_req_encode_common(or, OSD_ACT_READ, obj, offset, len); 88002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh WARN_ON(or->in.bio || or->in.total_bytes); 881d842a93c4b3a20d31f4fb97357e0964210d6066fJiri Slaby WARN_ON(bio->bi_rw & REQ_WRITE); 88202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->in.bio = bio; 88362f469b596dd0aadf046a69027087c18db43734eBoaz Harrosh or->in.total_bytes = len; 88402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 88502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_read); 88602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 8870e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harroshint osd_req_read_kern(struct osd_request *or, 8880e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh const struct osd_obj_id *obj, u64 offset, void* buff, u64 len) 8890e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh{ 890fc2fac5b5f11e2bee3bf37215c8746236f5ea188Boaz Harrosh struct request_queue *req_q = osd_request_queue(or->osd_dev); 8910e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh struct bio *bio = bio_map_kern(req_q, buff, len, GFP_KERNEL); 8920e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh 8930e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh if (IS_ERR(bio)) 8940e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh return PTR_ERR(bio); 8950e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh 89662f469b596dd0aadf046a69027087c18db43734eBoaz Harrosh osd_req_read(or, obj, offset, bio, len); 8970e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh return 0; 8980e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh} 8990e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz HarroshEXPORT_SYMBOL(osd_req_read_kern); 9000e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh 901e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harroshstatic int _add_sg_continuation_descriptor(struct osd_request *or, 902e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh const struct osd_sg_entry *sglist, unsigned numentries, u64 *len) 903e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh{ 904e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh struct osd_sg_continuation_descriptor *oscd; 905e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh u32 oscd_size; 906e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh unsigned i; 907e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh int ret; 908e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh 909e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh oscd_size = sizeof(*oscd) + numentries * sizeof(oscd->entries[0]); 910e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh 911e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh if (!or->cdb_cont.total_bytes) { 912e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh /* First time, jump over the header, we will write to: 913e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh * cdb_cont.buff + cdb_cont.total_bytes 914e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh */ 915e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh or->cdb_cont.total_bytes = 916e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh sizeof(struct osd_continuation_segment_header); 917e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh } 918e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh 919e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh ret = _alloc_cdb_cont(or, or->cdb_cont.total_bytes + oscd_size); 920e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh if (unlikely(ret)) 921e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh return ret; 922e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh 923e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh oscd = or->cdb_cont.buff + or->cdb_cont.total_bytes; 924e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh oscd->hdr.type = cpu_to_be16(SCATTER_GATHER_LIST); 925e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh oscd->hdr.pad_length = 0; 926e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh oscd->hdr.length = cpu_to_be32(oscd_size - sizeof(*oscd)); 927e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh 928e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh *len = 0; 929e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh /* copy the sg entries and convert to network byte order */ 930e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh for (i = 0; i < numentries; i++) { 931e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh oscd->entries[i].offset = cpu_to_be64(sglist[i].offset); 932e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh oscd->entries[i].len = cpu_to_be64(sglist[i].len); 933e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh *len += sglist[i].len; 934e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh } 935e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh 936e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh or->cdb_cont.total_bytes += oscd_size; 937e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh OSD_DEBUG("total_bytes=%d oscd_size=%d numentries=%d\n", 938e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh or->cdb_cont.total_bytes, oscd_size, numentries); 939e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh return 0; 940e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh} 941e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh 942e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harroshstatic int _osd_req_finalize_cdb_cont(struct osd_request *or, const u8 *cap_key) 943e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh{ 944e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh struct request_queue *req_q = osd_request_queue(or->osd_dev); 945e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh struct bio *bio; 946e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 947e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh struct osd_continuation_segment_header *cont_seg_hdr; 948e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh 949e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh if (!or->cdb_cont.total_bytes) 950e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh return 0; 951e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh 952e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh cont_seg_hdr = or->cdb_cont.buff; 953e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh cont_seg_hdr->format = CDB_CONTINUATION_FORMAT_V2; 954e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh cont_seg_hdr->service_action = cdbh->varlen_cdb.service_action; 955e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh 956e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh /* create a bio for continuation segment */ 957e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh bio = bio_map_kern(req_q, or->cdb_cont.buff, or->cdb_cont.total_bytes, 958e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh GFP_KERNEL); 959057f02a38e67a944a2d0b89bb0111efb9dbe6e6eDan Carpenter if (IS_ERR(bio)) 960057f02a38e67a944a2d0b89bb0111efb9dbe6e6eDan Carpenter return PTR_ERR(bio); 961e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh 962e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh bio->bi_rw |= REQ_WRITE; 963e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh 964e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh /* integrity check the continuation before the bio is linked 965e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh * with the other data segments since the continuation 966e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh * integrity is separate from the other data segments. 967e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh */ 968e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh osd_sec_sign_data(cont_seg_hdr->integrity_check, bio, cap_key); 969e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh 970e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh cdbh->v2.cdb_continuation_length = cpu_to_be32(or->cdb_cont.total_bytes); 971e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh 972e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh /* we can't use _req_append_segment, because we need to link in the 973e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh * continuation bio to the head of the bio list - the 974e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh * continuation segment (if it exists) is always the first segment in 975e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh * the out data buffer. 976e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh */ 977e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh bio->bi_next = or->out.bio; 978e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh or->out.bio = bio; 979e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh or->out.total_bytes += or->cdb_cont.total_bytes; 980e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh 981e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh return 0; 982e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh} 983e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh 984e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh/* osd_req_write_sg: Takes a @bio that points to the data out buffer and an 985e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh * @sglist that has the scatter gather entries. Scatter-gather enables a write 986e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh * of multiple none-contiguous areas of an object, in a single call. The extents 987e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh * may overlap and/or be in any order. The only constrain is that: 988e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh * total_bytes(sglist) >= total_bytes(bio) 989e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh */ 990e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harroshint osd_req_write_sg(struct osd_request *or, 991e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh const struct osd_obj_id *obj, struct bio *bio, 992e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh const struct osd_sg_entry *sglist, unsigned numentries) 993e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh{ 994e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh u64 len; 995e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh int ret = _add_sg_continuation_descriptor(or, sglist, numentries, &len); 996e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh 997e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh if (ret) 998e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh return ret; 999e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh osd_req_write(or, obj, 0, bio, len); 1000e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh 1001e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh return 0; 1002e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh} 1003e96e72c45a1e78e9266dd70113b851395a440ef3Boaz HarroshEXPORT_SYMBOL(osd_req_write_sg); 1004e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh 1005e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh/* osd_req_read_sg: Read multiple extents of an object into @bio 1006e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh * See osd_req_write_sg 1007e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh */ 1008e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harroshint osd_req_read_sg(struct osd_request *or, 1009e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh const struct osd_obj_id *obj, struct bio *bio, 1010e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh const struct osd_sg_entry *sglist, unsigned numentries) 1011e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh{ 1012e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh u64 len; 10134977c82504f58d7579acabd21688183eaa8768fbBoaz Harrosh u64 off; 10144977c82504f58d7579acabd21688183eaa8768fbBoaz Harrosh int ret; 1015e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh 10164977c82504f58d7579acabd21688183eaa8768fbBoaz Harrosh if (numentries > 1) { 10174977c82504f58d7579acabd21688183eaa8768fbBoaz Harrosh off = 0; 10184977c82504f58d7579acabd21688183eaa8768fbBoaz Harrosh ret = _add_sg_continuation_descriptor(or, sglist, numentries, 10194977c82504f58d7579acabd21688183eaa8768fbBoaz Harrosh &len); 10204977c82504f58d7579acabd21688183eaa8768fbBoaz Harrosh if (ret) 10214977c82504f58d7579acabd21688183eaa8768fbBoaz Harrosh return ret; 10224977c82504f58d7579acabd21688183eaa8768fbBoaz Harrosh } else { 10234977c82504f58d7579acabd21688183eaa8768fbBoaz Harrosh /* Optimize the case of single segment, read_sg is a 10244977c82504f58d7579acabd21688183eaa8768fbBoaz Harrosh * bidi operation. 10254977c82504f58d7579acabd21688183eaa8768fbBoaz Harrosh */ 10264977c82504f58d7579acabd21688183eaa8768fbBoaz Harrosh len = sglist->len; 10274977c82504f58d7579acabd21688183eaa8768fbBoaz Harrosh off = sglist->offset; 10284977c82504f58d7579acabd21688183eaa8768fbBoaz Harrosh } 10294977c82504f58d7579acabd21688183eaa8768fbBoaz Harrosh osd_req_read(or, obj, off, bio, len); 1030e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh 1031e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh return 0; 1032e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh} 1033e96e72c45a1e78e9266dd70113b851395a440ef3Boaz HarroshEXPORT_SYMBOL(osd_req_read_sg); 1034e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh 10356dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh/* SG-list write/read Kern API 10366dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh * 10376dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh * osd_req_{write,read}_sg_kern takes an array of @buff pointers and an array 10386dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh * of sg_entries. @numentries indicates how many pointers and sg_entries there 10396dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh * are. By requiring an array of buff pointers. This allows a caller to do a 10406dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh * single write/read and scatter into multiple buffers. 10416dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh * NOTE: Each buffer + len should not cross a page boundary. 10426dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh */ 10436dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harroshstatic struct bio *_create_sg_bios(struct osd_request *or, 10446dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh void **buff, const struct osd_sg_entry *sglist, unsigned numentries) 10456dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh{ 10466dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh struct request_queue *q = osd_request_queue(or->osd_dev); 10476dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh struct bio *bio; 10486dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh unsigned i; 10496dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh 10506dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh bio = bio_kmalloc(GFP_KERNEL, numentries); 10516dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh if (unlikely(!bio)) { 10521051e9b33bbf550be52bdd674b519f3dc99f0dd9Masanari Iida OSD_DEBUG("Failed to allocate BIO size=%u\n", numentries); 10536dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh return ERR_PTR(-ENOMEM); 10546dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh } 10556dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh 10566dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh for (i = 0; i < numentries; i++) { 10576dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh unsigned offset = offset_in_page(buff[i]); 10586dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh struct page *page = virt_to_page(buff[i]); 10596dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh unsigned len = sglist[i].len; 10606dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh unsigned added_len; 10616dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh 10626dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh BUG_ON(offset + len > PAGE_SIZE); 10636dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh added_len = bio_add_pc_page(q, bio, page, len, offset); 10646dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh if (unlikely(len != added_len)) { 10656dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh OSD_DEBUG("bio_add_pc_page len(%d) != added_len(%d)\n", 10666dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh len, added_len); 10676dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh bio_put(bio); 10686dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh return ERR_PTR(-ENOMEM); 10696dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh } 10706dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh } 10716dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh 10726dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh return bio; 10736dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh} 10746dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh 10756dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harroshint osd_req_write_sg_kern(struct osd_request *or, 10766dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh const struct osd_obj_id *obj, void **buff, 10776dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh const struct osd_sg_entry *sglist, unsigned numentries) 10786dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh{ 10796dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh struct bio *bio = _create_sg_bios(or, buff, sglist, numentries); 10806dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh if (IS_ERR(bio)) 10816dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh return PTR_ERR(bio); 10826dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh 10836dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh bio->bi_rw |= REQ_WRITE; 10846dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh osd_req_write_sg(or, obj, bio, sglist, numentries); 10856dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh 10866dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh return 0; 10876dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh} 10886dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz HarroshEXPORT_SYMBOL(osd_req_write_sg_kern); 10896dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh 10906dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harroshint osd_req_read_sg_kern(struct osd_request *or, 10916dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh const struct osd_obj_id *obj, void **buff, 10926dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh const struct osd_sg_entry *sglist, unsigned numentries) 10936dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh{ 10946dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh struct bio *bio = _create_sg_bios(or, buff, sglist, numentries); 10956dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh if (IS_ERR(bio)) 10966dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh return PTR_ERR(bio); 10976dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh 10986dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh osd_req_read_sg(or, obj, bio, sglist, numentries); 10996dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh 11006dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh return 0; 11016dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh} 11026dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz HarroshEXPORT_SYMBOL(osd_req_read_sg_kern); 11036dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh 11046dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh 11056dd1d8a7953cdc203c6eb694ce8eafe2dcd3e9daBoaz Harrosh 11064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshvoid osd_req_get_attributes(struct osd_request *or, 11074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const struct osd_obj_id *obj) 11084ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 11094ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _osd_req_encode_common(or, OSD_ACT_GET_ATTRIBUTES, obj, 0, 0); 11104ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 11114ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_get_attributes); 11124ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 11134ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshvoid osd_req_set_attributes(struct osd_request *or, 11144ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const struct osd_obj_id *obj) 11154ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 11164ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _osd_req_encode_common(or, OSD_ACT_SET_ATTRIBUTES, obj, 0, 0); 11174ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 11184ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_set_attributes); 11194ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 11204ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh/* 11214ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * Attributes List-mode 11224ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh */ 11234ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 11244ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshint osd_req_add_set_attr_list(struct osd_request *or, 11254ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const struct osd_attr *oa, unsigned nelem) 11264ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 11274ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned total_bytes = or->set_attr.total_bytes; 11284ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh void *attr_last; 11294ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int ret; 11304ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 11314ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (or->attributes_mode && 11324ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->attributes_mode != OSD_CDB_GET_SET_ATTR_LISTS) { 11334ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh WARN_ON(1); 11344ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return -EINVAL; 11354ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 11364ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->attributes_mode = OSD_CDB_GET_SET_ATTR_LISTS; 11374ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 11384ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!total_bytes) { /* first-time: allocate and put list header */ 11394ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh total_bytes = _osd_req_sizeof_alist_header(or); 11404ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _alloc_set_attr_list(or, oa, nelem, total_bytes); 11414ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 11424ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 11434ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _osd_req_set_alist_type(or, or->set_attr.buff, 11444ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_ATTR_LIST_SET_RETRIEVE); 11454ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 11464ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr_last = or->set_attr.buff + total_bytes; 11474ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 11484ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh for (; nelem; --nelem) { 11494ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned elem_size = _osd_req_alist_elem_size(or, oa->len); 11504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 11514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh total_bytes += elem_size; 11524ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (unlikely(or->set_attr.alloc_size < total_bytes)) { 11534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->set_attr.total_bytes = total_bytes - elem_size; 11544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _alloc_set_attr_list(or, oa, nelem, total_bytes); 11554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 11564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 11574ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr_last = 11584ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->set_attr.buff + or->set_attr.total_bytes; 11594ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 11604ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 116171f32e31e5638df37904697e2d04182935add85dBoaz Harrosh _osd_req_alist_elem_encode(or, attr_last, oa); 11624ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 11634ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr_last += elem_size; 11644ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ++oa; 11654ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 11664ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 11674ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->set_attr.total_bytes = total_bytes; 11684ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 11694ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 11704ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_add_set_attr_list); 11714ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 11724ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _req_append_segment(struct osd_request *or, 11734ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned padding, struct _osd_req_data_segment *seg, 11744ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct _osd_req_data_segment *last_seg, struct _osd_io_info *io) 11754ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 11764ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh void *pad_buff; 11774ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int ret; 11784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 11794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (padding) { 11804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* check if we can just add it to last buffer */ 11814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (last_seg && 11824ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh (padding <= last_seg->alloc_size - last_seg->total_bytes)) 11834ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh pad_buff = last_seg->buff + last_seg->total_bytes; 11844ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh else 11854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh pad_buff = io->pad_buff; 11864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 1187bc38bf106c967389a465d926be22c7371abba69dBoaz Harrosh ret = blk_rq_map_kern(io->req->q, io->req, pad_buff, padding, 11884ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->alloc_flags); 11894ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 11904ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 11914ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh io->total_bytes += padding; 11924ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 11934ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 1194bc38bf106c967389a465d926be22c7371abba69dBoaz Harrosh ret = blk_rq_map_kern(io->req->q, io->req, seg->buff, seg->total_bytes, 11954ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->alloc_flags); 11964ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 11974ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 11984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 11994ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh io->total_bytes += seg->total_bytes; 12004ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("padding=%d buff=%p total_bytes=%d\n", padding, seg->buff, 12014ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh seg->total_bytes); 12024ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 12034ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 12044ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 12054ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _osd_req_finalize_set_attr_list(struct osd_request *or) 12064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 12074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 12084ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned padding; 12094ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int ret; 12104ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 12114ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!or->set_attr.total_bytes) { 12124ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.set_attr_offset = OSD_OFFSET_UNUSED; 12134ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 12144ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 12154ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 12164ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.set_attr_bytes = cpu_to_be32(or->set_attr.total_bytes); 12174ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.set_attr_offset = 12184ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh osd_req_encode_offset(or, or->out.total_bytes, &padding); 12194ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 12204ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _req_append_segment(or, padding, &or->set_attr, 12214ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->out.last_seg, &or->out); 12224ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 12234ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 12244ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 12254ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->out.last_seg = &or->set_attr; 12264ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 12274ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 12284ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 12294ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshint osd_req_add_get_attr_list(struct osd_request *or, 12304ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const struct osd_attr *oa, unsigned nelem) 12314ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 12324ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned total_bytes = or->enc_get_attr.total_bytes; 12334ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh void *attr_last; 12344ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int ret; 12354ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 12364ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (or->attributes_mode && 12374ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->attributes_mode != OSD_CDB_GET_SET_ATTR_LISTS) { 12384ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh WARN_ON(1); 12394ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return -EINVAL; 12404ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 12414ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->attributes_mode = OSD_CDB_GET_SET_ATTR_LISTS; 12424ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 12434ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* first time calc data-in list header size */ 12444ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!or->get_attr.total_bytes) 12454ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.total_bytes = _osd_req_sizeof_alist_header(or); 12464ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 12474ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* calc data-out info */ 12484ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!total_bytes) { /* first-time: allocate and put list header */ 12494ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned max_bytes; 12504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 12514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh total_bytes = _osd_req_sizeof_alist_header(or); 12524ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh max_bytes = total_bytes + 12534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh nelem * sizeof(struct osd_attributes_list_attrid); 12544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _alloc_get_attr_desc(or, max_bytes); 12554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 12564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 12574ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 12584ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _osd_req_set_alist_type(or, or->enc_get_attr.buff, 12594ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_ATTR_LIST_GET); 12604ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 12614ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr_last = or->enc_get_attr.buff + total_bytes; 12624ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 12634ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh for (; nelem; --nelem) { 12644ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osd_attributes_list_attrid *attrid; 12654ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const unsigned cur_size = sizeof(*attrid); 12664ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 12674ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh total_bytes += cur_size; 12684ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (unlikely(or->enc_get_attr.alloc_size < total_bytes)) { 12694ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->enc_get_attr.total_bytes = total_bytes - cur_size; 12704ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _alloc_get_attr_desc(or, 12714ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh total_bytes + nelem * sizeof(*attrid)); 12724ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 12734ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 12744ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr_last = or->enc_get_attr.buff + 12754ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->enc_get_attr.total_bytes; 12764ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 12774ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 12784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attrid = attr_last; 12794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attrid->attr_page = cpu_to_be32(oa->attr_page); 12804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attrid->attr_id = cpu_to_be32(oa->attr_id); 12814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 12824ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh attr_last += cur_size; 12834ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 12844ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* calc data-in size */ 12854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.total_bytes += 12864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _osd_req_alist_elem_size(or, oa->len); 12874ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ++oa; 12884ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 12894ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 12904ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->enc_get_attr.total_bytes = total_bytes; 12914ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 12924ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG( 12934ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh "get_attr.total_bytes=%u(%u) enc_get_attr.total_bytes=%u(%Zu)\n", 12944ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.total_bytes, 12954ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.total_bytes - _osd_req_sizeof_alist_header(or), 12964ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->enc_get_attr.total_bytes, 12974ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh (or->enc_get_attr.total_bytes - _osd_req_sizeof_alist_header(or)) 12984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh / sizeof(struct osd_attributes_list_attrid)); 12994ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 13004ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 13014ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 13024ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_add_get_attr_list); 13034ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 13044ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _osd_req_finalize_get_attr_list(struct osd_request *or) 13054ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 13064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 13074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned out_padding; 13084ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned in_padding; 13094ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int ret; 13104ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 13114ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!or->enc_get_attr.total_bytes) { 13124ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.get_attr_desc_offset = OSD_OFFSET_UNUSED; 13134ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.get_attr_offset = OSD_OFFSET_UNUSED; 13144ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 13154ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 13164ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 13174ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _alloc_get_attr_list(or); 13184ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 13194ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 13204ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 13214ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* The out-going buffer info update */ 13224ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("out-going\n"); 13234ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.get_attr_desc_bytes = 13244ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cpu_to_be32(or->enc_get_attr.total_bytes); 13254ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 13264ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.get_attr_desc_offset = 13274ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh osd_req_encode_offset(or, or->out.total_bytes, &out_padding); 13284ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 13294ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _req_append_segment(or, out_padding, &or->enc_get_attr, 13304ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->out.last_seg, &or->out); 13314ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 13324ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 13334ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->out.last_seg = &or->enc_get_attr; 13344ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 13354ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* The incoming buffer info update */ 13364ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("in-coming\n"); 13374ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.get_attr_alloc_length = 13384ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cpu_to_be32(or->get_attr.total_bytes); 13394ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 13404ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_list.get_attr_offset = 13414ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh osd_req_encode_offset(or, or->in.total_bytes, &in_padding); 13424ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 13434ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _req_append_segment(or, in_padding, &or->get_attr, NULL, 13444ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh &or->in); 13454ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 13464ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 13474ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->in.last_seg = &or->get_attr; 13484ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 13494ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 13504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 13514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 13524ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshint osd_req_decode_get_attr_list(struct osd_request *or, 13534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osd_attr *oa, int *nelem, void **iterator) 13544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 13554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned cur_bytes, returned_bytes; 13564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int n; 13574ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const unsigned sizeof_attr_list = _osd_req_sizeof_alist_header(or); 13584ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh void *cur_p; 13594ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 13604ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!_osd_req_is_alist_type(or, or->get_attr.buff, 13614ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_ATTR_LIST_SET_RETRIEVE)) { 13624ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->attr_page = 0; 13634ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->attr_id = 0; 13644ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->val_ptr = NULL; 13654ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->len = 0; 13664ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh *iterator = NULL; 13674ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 13684ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 13694ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 13704ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (*iterator) { 13714ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh BUG_ON((*iterator < or->get_attr.buff) || 13724ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh (or->get_attr.buff + or->get_attr.alloc_size < *iterator)); 13734ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cur_p = *iterator; 13744ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cur_bytes = (*iterator - or->get_attr.buff) - sizeof_attr_list; 13754ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh returned_bytes = or->get_attr.total_bytes; 13764ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } else { /* first time decode the list header */ 13774ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cur_bytes = sizeof_attr_list; 13784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh returned_bytes = _osd_req_alist_size(or, or->get_attr.buff) + 13794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh sizeof_attr_list; 13804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 13814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cur_p = or->get_attr.buff + sizeof_attr_list; 13824ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 13834ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (returned_bytes > or->get_attr.alloc_size) { 13844ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("target report: space was not big enough! " 13854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh "Allocate=%u Needed=%u\n", 13864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.alloc_size, 13874ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh returned_bytes + sizeof_attr_list); 13884ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 13894ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh returned_bytes = 13904ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.alloc_size - sizeof_attr_list; 13914ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 13924ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.total_bytes = returned_bytes; 13934ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 13944ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 13954ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh for (n = 0; (n < *nelem) && (cur_bytes < returned_bytes); ++n) { 139671f32e31e5638df37904697e2d04182935add85dBoaz Harrosh int inc = _osd_req_alist_elem_decode(or, cur_p, oa, 139771f32e31e5638df37904697e2d04182935add85dBoaz Harrosh returned_bytes - cur_bytes); 13984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 139971f32e31e5638df37904697e2d04182935add85dBoaz Harrosh if (inc < 0) { 14004ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_ERR("BAD FOOD from target. list not valid!" 14014ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh "c=%d r=%d n=%d\n", 14024ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cur_bytes, returned_bytes, n); 14034ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh oa->val_ptr = NULL; 1404eff21490c91f981126f0ead3c081dde4f425d387Boaz Harrosh cur_bytes = returned_bytes; /* break the caller loop */ 14054ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh break; 14064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 14074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 140871f32e31e5638df37904697e2d04182935add85dBoaz Harrosh cur_bytes += inc; 14094ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cur_p += inc; 14104ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ++oa; 14114ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 14124ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 14134ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh *iterator = (returned_bytes - cur_bytes) ? cur_p : NULL; 14144ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh *nelem = n; 14154ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return returned_bytes - cur_bytes; 14164ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 14174ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_decode_get_attr_list); 14184ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 14194ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh/* 14204ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * Attributes Page-mode 14214ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh */ 14224ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 14234ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshint osd_req_add_get_attr_page(struct osd_request *or, 14244ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh u32 page_id, void *attar_page, unsigned max_page_len, 14254ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh const struct osd_attr *set_one_attr) 14264ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 14274ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 14284ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 14294ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (or->attributes_mode && 14304ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->attributes_mode != OSD_CDB_GET_ATTR_PAGE_SET_ONE) { 14314ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh WARN_ON(1); 14324ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return -EINVAL; 14334ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 14344ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->attributes_mode = OSD_CDB_GET_ATTR_PAGE_SET_ONE; 14354ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 14364ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.buff = attar_page; 14374ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->get_attr.total_bytes = max_page_len; 14384ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 14394ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_page.get_attr_page = cpu_to_be32(page_id); 14404ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_page.get_attr_alloc_length = cpu_to_be32(max_page_len); 1441ec6a0a41b57feb54b3830918a8fb07147c2ee778Boaz Harrosh 1442ec6a0a41b57feb54b3830918a8fb07147c2ee778Boaz Harrosh if (!set_one_attr || !set_one_attr->attr_page) 1443ec6a0a41b57feb54b3830918a8fb07147c2ee778Boaz Harrosh return 0; /* The set is optional */ 1444ec6a0a41b57feb54b3830918a8fb07147c2ee778Boaz Harrosh 1445ec6a0a41b57feb54b3830918a8fb07147c2ee778Boaz Harrosh or->set_attr.buff = set_one_attr->val_ptr; 1446ec6a0a41b57feb54b3830918a8fb07147c2ee778Boaz Harrosh or->set_attr.total_bytes = set_one_attr->len; 14474ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 14484ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_page.set_attr_page = cpu_to_be32(set_one_attr->attr_page); 14494ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_page.set_attr_id = cpu_to_be32(set_one_attr->attr_id); 14504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_page.set_attr_length = cpu_to_be32(set_one_attr->len); 14514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 14524ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 14534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_add_get_attr_page); 14544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 14554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _osd_req_finalize_attr_page(struct osd_request *or) 14564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 14574ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 14584ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh unsigned in_padding, out_padding; 14594ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int ret; 14604ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 14614ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* returned page */ 14624ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_page.get_attr_offset = 14634ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh osd_req_encode_offset(or, or->in.total_bytes, &in_padding); 14644ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 14654ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _req_append_segment(or, in_padding, &or->get_attr, NULL, 14664ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh &or->in); 14674ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) 14684ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 14694ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 1470ec6a0a41b57feb54b3830918a8fb07147c2ee778Boaz Harrosh if (or->set_attr.total_bytes == 0) 1471ec6a0a41b57feb54b3830918a8fb07147c2ee778Boaz Harrosh return 0; 1472ec6a0a41b57feb54b3830918a8fb07147c2ee778Boaz Harrosh 14734ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* set one value */ 14744ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh cdbh->attrs_page.set_attr_offset = 14754ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh osd_req_encode_offset(or, or->out.total_bytes, &out_padding); 14764ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 1477ec6a0a41b57feb54b3830918a8fb07147c2ee778Boaz Harrosh ret = _req_append_segment(or, out_padding, &or->set_attr, NULL, 14784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh &or->out); 14794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 14804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 14814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 1482f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harroshstatic inline void osd_sec_parms_set_out_offset(bool is_v1, 1483f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh struct osd_security_parameters *sec_parms, osd_cdb_offset offset) 1484f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh{ 1485f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh if (is_v1) 1486f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh sec_parms->v1.data_out_integrity_check_offset = offset; 1487f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh else 1488f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh sec_parms->v2.data_out_integrity_check_offset = offset; 1489f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh} 1490f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh 1491f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harroshstatic inline void osd_sec_parms_set_in_offset(bool is_v1, 1492f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh struct osd_security_parameters *sec_parms, osd_cdb_offset offset) 1493f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh{ 1494f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh if (is_v1) 1495f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh sec_parms->v1.data_in_integrity_check_offset = offset; 1496f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh else 1497f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh sec_parms->v2.data_in_integrity_check_offset = offset; 1498f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh} 1499f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh 1500345c435dbb0b77b00ffe73801102533e24c647afBoaz Harroshstatic int _osd_req_finalize_data_integrity(struct osd_request *or, 1501e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh bool has_in, bool has_out, struct bio *out_data_bio, u64 out_data_bytes, 1502e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh const u8 *cap_key) 1503345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh{ 1504345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh struct osd_security_parameters *sec_parms = _osd_req_sec_params(or); 1505345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh int ret; 1506345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 1507345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh if (!osd_is_sec_alldata(sec_parms)) 1508345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh return 0; 1509345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 1510345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh if (has_out) { 1511345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh struct _osd_req_data_segment seg = { 1512345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh .buff = &or->out_data_integ, 1513345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh .total_bytes = sizeof(or->out_data_integ), 1514345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh }; 1515345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh unsigned pad; 1516345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 1517546881aea9787ed5c626ac99ab80158ea9ae0515Boaz Harrosh or->out_data_integ.data_bytes = cpu_to_be64(out_data_bytes); 1518345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh or->out_data_integ.set_attributes_bytes = cpu_to_be64( 1519345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh or->set_attr.total_bytes); 1520345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh or->out_data_integ.get_attributes_bytes = cpu_to_be64( 1521345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh or->enc_get_attr.total_bytes); 1522345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 1523f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh osd_sec_parms_set_out_offset(osd_req_is_ver1(or), sec_parms, 1524f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh osd_req_encode_offset(or, or->out.total_bytes, &pad)); 1525345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 1526345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh ret = _req_append_segment(or, pad, &seg, or->out.last_seg, 1527345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh &or->out); 1528345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh if (ret) 1529345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh return ret; 1530345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh or->out.last_seg = NULL; 1531345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 1532345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh /* they are now all chained to request sign them all together */ 1533e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh osd_sec_sign_data(&or->out_data_integ, out_data_bio, 1534345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh cap_key); 1535345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh } 1536345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 1537345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh if (has_in) { 1538345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh struct _osd_req_data_segment seg = { 1539345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh .buff = &or->in_data_integ, 1540345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh .total_bytes = sizeof(or->in_data_integ), 1541345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh }; 1542345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh unsigned pad; 1543345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 1544f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh osd_sec_parms_set_in_offset(osd_req_is_ver1(or), sec_parms, 1545f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh osd_req_encode_offset(or, or->in.total_bytes, &pad)); 1546345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 1547345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh ret = _req_append_segment(or, pad, &seg, or->in.last_seg, 1548345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh &or->in); 1549345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh if (ret) 1550345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh return ret; 1551345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 1552345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh or->in.last_seg = NULL; 1553345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh } 1554345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 1555345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh return 0; 1556345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh} 1557345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 155802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* 155902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * osd_finalize_request and helpers 156002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 1561c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harroshstatic struct request *_make_request(struct request_queue *q, bool has_write, 1562c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh struct _osd_io_info *oii, gfp_t flags) 1563c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh{ 1564c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh if (oii->bio) 1565c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh return blk_make_request(q, oii->bio, flags); 1566c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh else { 1567c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh struct request *req; 1568c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh 1569c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh req = blk_get_request(q, has_write ? WRITE : READ, flags); 1570a492f075450f3ba87de36e5ffe92a9d0c7af9723Joe Lawrence if (IS_ERR(req)) 1571a492f075450f3ba87de36e5ffe92a9d0c7af9723Joe Lawrence return req; 1572c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh 1573f27b087b81b70513b8c61ec20596c868f7b93474Jens Axboe blk_rq_set_block_pc(req); 1574c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh return req; 1575c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh } 1576c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh} 157702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 157802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic int _init_blk_request(struct osd_request *or, 157902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh bool has_in, bool has_out) 158002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 158102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh gfp_t flags = or->alloc_flags; 158202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct scsi_device *scsi_device = or->osd_dev->scsi_device; 158302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct request_queue *q = scsi_device->request_queue; 158402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct request *req; 1585c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh int ret; 158602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 1587c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh req = _make_request(q, has_out, has_out ? &or->out : &or->in, flags); 1588c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh if (IS_ERR(req)) { 1589c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh ret = PTR_ERR(req); 159002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh goto out; 1591c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh } 159202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 159302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->request = req; 159403306793e686fd895ab8fa095bb9ec33658ea53aBoaz Harrosh req->cmd_flags |= REQ_QUIET; 159503306793e686fd895ab8fa095bb9ec33658ea53aBoaz Harrosh 159602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh req->timeout = or->timeout; 159702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh req->retries = or->retries; 159802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh req->sense = or->sense; 159902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh req->sense_len = 0; 160002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 160102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (has_out) { 160202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->out.req = req; 160302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (has_in) { 160402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh /* allocate bidi request */ 1605c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh req = _make_request(q, false, &or->in, flags); 1606c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh if (IS_ERR(req)) { 160702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_DEBUG("blk_get_request for bidi failed\n"); 1608c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh ret = PTR_ERR(req); 160902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh goto out; 161002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 1611f27b087b81b70513b8c61ec20596c868f7b93474Jens Axboe blk_rq_set_block_pc(req); 161202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->in.req = or->request->next_rq = req; 161302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 161402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } else if (has_in) 161502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->in.req = req; 161602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 161702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ret = 0; 161802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshout: 161902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_DEBUG("or=%p has_in=%d has_out=%d => %d, %p\n", 162002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or, has_in, has_out, ret, or->request); 162102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return ret; 162202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 162302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 162402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshint osd_finalize_request(struct osd_request *or, 162502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh u8 options, const void *cap, const u8 *cap_key) 162602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 162702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb); 162802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh bool has_in, has_out; 1629e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh /* Save for data_integrity without the cdb_continuation */ 1630e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh struct bio *out_data_bio = or->out.bio; 1631546881aea9787ed5c626ac99ab80158ea9ae0515Boaz Harrosh u64 out_data_bytes = or->out.total_bytes; 163202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh int ret; 163302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 163402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (options & OSD_REQ_FUA) 163502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cdbh->options |= OSD_CDB_FUA; 163602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 163702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (options & OSD_REQ_DPO) 163802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cdbh->options |= OSD_CDB_DPO; 163902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 164002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (options & OSD_REQ_BYPASS_TIMESTAMPS) 164102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cdbh->timestamp_control = OSD_CDB_BYPASS_TIMESTAMPS; 164202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 164302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osd_set_caps(&or->cdb, cap); 164402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 164502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh has_in = or->in.bio || or->get_attr.total_bytes; 1646e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh has_out = or->out.bio || or->cdb_cont.total_bytes || 1647e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh or->set_attr.total_bytes || or->enc_get_attr.total_bytes; 164802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 1649e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh ret = _osd_req_finalize_cdb_cont(or, cap_key); 1650e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh if (ret) { 1651e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh OSD_DEBUG("_osd_req_finalize_cdb_cont failed\n"); 1652e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh return ret; 1653e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh } 165402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh ret = _init_blk_request(or, has_in, has_out); 165502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (ret) { 165602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_DEBUG("_init_blk_request failed\n"); 165702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return ret; 165802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 165902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 16604ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->out.pad_buff = sg_out_pad_buffer; 16614ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh or->in.pad_buff = sg_in_pad_buffer; 16624ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 166302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (!or->attributes_mode) 166402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->attributes_mode = OSD_CDB_GET_SET_ATTR_LISTS; 166502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cdbh->command_specific_options |= or->attributes_mode; 16664ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (or->attributes_mode == OSD_CDB_GET_ATTR_PAGE_SET_ONE) { 16674ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _osd_req_finalize_attr_page(or); 166898e1e0f07c3f1820b8ac424569ee9e9916d3665bBoaz Harrosh if (ret) { 166998e1e0f07c3f1820b8ac424569ee9e9916d3665bBoaz Harrosh OSD_DEBUG("_osd_req_finalize_attr_page failed\n"); 167098e1e0f07c3f1820b8ac424569ee9e9916d3665bBoaz Harrosh return ret; 167198e1e0f07c3f1820b8ac424569ee9e9916d3665bBoaz Harrosh } 16724ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } else { 16734ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh /* TODO: I think that for the GET_ATTR command these 2 should 16744ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * be reversed to keep them in execution order (for embeded 16754ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * targets with low memory footprint) 16764ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh */ 16774ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _osd_req_finalize_set_attr_list(or); 16784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) { 16794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("_osd_req_finalize_set_attr_list failed\n"); 16804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 16814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 16824ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 16834ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh ret = _osd_req_finalize_get_attr_list(or); 16844ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (ret) { 16854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("_osd_req_finalize_get_attr_list failed\n"); 16864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return ret; 16874ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 16884ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 168902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 1690546881aea9787ed5c626ac99ab80158ea9ae0515Boaz Harrosh ret = _osd_req_finalize_data_integrity(or, has_in, has_out, 1691e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh out_data_bio, out_data_bytes, 1692e96e72c45a1e78e9266dd70113b851395a440ef3Boaz Harrosh cap_key); 1693345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh if (ret) 1694345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh return ret; 1695345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 1696345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh osd_sec_sign_cdb(&or->cdb, cap_key); 1697345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 169802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->request->cmd = or->cdb.buff; 169902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh or->request->cmd_len = _osd_req_cdb_len(or); 170002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 170102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh return 0; 170202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 170302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_finalize_request); 170402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 1705aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harroshstatic bool _is_osd_security_code(int code) 1706aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh{ 1707aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh return (code == osd_security_audit_value_frozen) || 1708aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh (code == osd_security_working_key_frozen) || 1709aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh (code == osd_nonce_not_unique) || 1710aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh (code == osd_nonce_timestamp_out_of_range) || 1711aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh (code == osd_invalid_dataout_buffer_integrity_check_value); 1712aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh} 1713aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh 171498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh#define OSD_SENSE_PRINT1(fmt, a...) \ 171598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh do { \ 171698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh if (__cur_sense_need_output) \ 171798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh OSD_ERR(fmt, ##a); \ 171898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh } while (0) 171998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 172098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh#define OSD_SENSE_PRINT2(fmt, a...) OSD_SENSE_PRINT1(" " fmt, ##a) 172198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 172298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harroshint osd_req_decode_sense_full(struct osd_request *or, 172398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh struct osd_sense_info *osi, bool silent, 172498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh struct osd_obj_id *bad_obj_list __unused, int max_obj __unused, 172598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh struct osd_attr *bad_attr_list, int max_attr) 172698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh{ 172798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh int sense_len, original_sense_len; 172898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh struct osd_sense_info local_osi; 172998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh struct scsi_sense_descriptor_based *ssdb; 173098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh void *cur_descriptor; 173198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh#if (CONFIG_SCSI_OSD_DPRINT_SENSE == 0) 173298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh const bool __cur_sense_need_output = false; 173398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh#else 173498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh bool __cur_sense_need_output = !silent; 173598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh#endif 1736aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh int ret; 173798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 17385d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh if (likely(!or->req_errors)) 173998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh return 0; 1740aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh 1741aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh osi = osi ? : &local_osi; 1742aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh memset(osi, 0, sizeof(*osi)); 174398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 17445d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh ssdb = (typeof(ssdb))or->sense; 17455d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh sense_len = or->sense_len; 174698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh if ((sense_len < (int)sizeof(*ssdb) || !ssdb->sense_key)) { 174798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh OSD_ERR("Block-layer returned error(0x%x) but " 174898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh "sense_len(%u) || key(%d) is empty\n", 17495d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh or->req_errors, sense_len, ssdb->sense_key); 1750aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh goto analyze; 175198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh } 175298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 175398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh if ((ssdb->response_code != 0x72) && (ssdb->response_code != 0x73)) { 175498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh OSD_ERR("Unrecognized scsi sense: rcode=%x length=%d\n", 175598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh ssdb->response_code, sense_len); 1756aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh goto analyze; 175798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh } 175898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 175998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh osi->key = ssdb->sense_key; 176098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh osi->additional_code = be16_to_cpu(ssdb->additional_sense_code); 176198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh original_sense_len = ssdb->additional_sense_length + 8; 176298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 176398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh#if (CONFIG_SCSI_OSD_DPRINT_SENSE == 1) 176498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh if (__cur_sense_need_output) 176598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh __cur_sense_need_output = (osi->key > scsi_sk_recovered_error); 176698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh#endif 176798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh OSD_SENSE_PRINT1("Main Sense information key=0x%x length(%d, %d) " 1768aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh "additional_code=0x%x async_error=%d errors=0x%x\n", 176998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh osi->key, original_sense_len, sense_len, 1770aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh osi->additional_code, or->async_error, 17715d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh or->req_errors); 177298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 177398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh if (original_sense_len < sense_len) 177498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh sense_len = original_sense_len; 177598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 177698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh cur_descriptor = ssdb->ssd; 177798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh sense_len -= sizeof(*ssdb); 177898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh while (sense_len > 0) { 177998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh struct scsi_sense_descriptor *ssd = cur_descriptor; 178098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh int cur_len = ssd->additional_length + 2; 178198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 178298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh sense_len -= cur_len; 178398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 178498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh if (sense_len < 0) 178598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh break; /* sense was truncated */ 178698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 178798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh switch (ssd->descriptor_type) { 178898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh case scsi_sense_information: 178998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh case scsi_sense_command_specific_information: 179098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh { 179198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh struct scsi_sense_command_specific_data_descriptor 179298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh *sscd = cur_descriptor; 179398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 179498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh osi->command_info = 179598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh get_unaligned_be64(&sscd->information) ; 179698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh OSD_SENSE_PRINT2( 179798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh "command_specific_information 0x%llx \n", 179898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh _LLU(osi->command_info)); 179998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh break; 180098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh } 180198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh case scsi_sense_key_specific: 180298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh { 180398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh struct scsi_sense_key_specific_data_descriptor 180498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh *ssks = cur_descriptor; 180598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 180698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh osi->sense_info = get_unaligned_be16(&ssks->value); 180798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh OSD_SENSE_PRINT2( 180898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh "sense_key_specific_information %u" 180998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh "sksv_cd_bpv_bp (0x%x)\n", 181098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh osi->sense_info, ssks->sksv_cd_bpv_bp); 181198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh break; 181298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh } 181398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh case osd_sense_object_identification: 181498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh { /*FIXME: Keep first not last, Store in array*/ 181598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh struct osd_sense_identification_data_descriptor 181698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh *osidd = cur_descriptor; 181798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 181898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh osi->not_initiated_command_functions = 181998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh le32_to_cpu(osidd->not_initiated_functions); 182098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh osi->completed_command_functions = 182198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh le32_to_cpu(osidd->completed_functions); 182298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh osi->obj.partition = be64_to_cpu(osidd->partition_id); 182398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh osi->obj.id = be64_to_cpu(osidd->object_id); 182498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh OSD_SENSE_PRINT2( 182598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh "object_identification pid=0x%llx oid=0x%llx\n", 182698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh _LLU(osi->obj.partition), _LLU(osi->obj.id)); 182798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh OSD_SENSE_PRINT2( 182898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh "not_initiated_bits(%x) " 182998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh "completed_command_bits(%x)\n", 183098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh osi->not_initiated_command_functions, 183198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh osi->completed_command_functions); 183298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh break; 183398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh } 183498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh case osd_sense_response_integrity_check: 183598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh { 183698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh struct osd_sense_response_integrity_check_descriptor 183798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh *osricd = cur_descriptor; 183898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh const unsigned len = 183998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh sizeof(osricd->integrity_check_value); 184098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh char key_dump[len*4 + 2]; /* 2nibbles+space+ASCII */ 184198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 184298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh hex_dump_to_buffer(osricd->integrity_check_value, len, 184398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 32, 1, key_dump, sizeof(key_dump), true); 184498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh OSD_SENSE_PRINT2("response_integrity [%s]\n", key_dump); 184598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh } 184698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh case osd_sense_attribute_identification: 184798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh { 184898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh struct osd_sense_attributes_data_descriptor 184998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh *osadd = cur_descriptor; 185071ecb74b15377a6c0e0e6ea95d4b549580fb4d48Boaz Harrosh unsigned len = min(cur_len, sense_len); 185198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh struct osd_sense_attr *pattr = osadd->sense_attrs; 185298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 185371ecb74b15377a6c0e0e6ea95d4b549580fb4d48Boaz Harrosh while (len >= sizeof(*pattr)) { 185498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh u32 attr_page = be32_to_cpu(pattr->attr_page); 185598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh u32 attr_id = be32_to_cpu(pattr->attr_id); 185698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 185771ecb74b15377a6c0e0e6ea95d4b549580fb4d48Boaz Harrosh if (!osi->attr.attr_page) { 185898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh osi->attr.attr_page = attr_page; 185998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh osi->attr.attr_id = attr_id; 186098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh } 186198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 186298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh if (bad_attr_list && max_attr) { 186398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh bad_attr_list->attr_page = attr_page; 186498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh bad_attr_list->attr_id = attr_id; 186598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh bad_attr_list++; 186698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh max_attr--; 186798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh } 186871ecb74b15377a6c0e0e6ea95d4b549580fb4d48Boaz Harrosh 186971ecb74b15377a6c0e0e6ea95d4b549580fb4d48Boaz Harrosh len -= sizeof(*pattr); 187098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh OSD_SENSE_PRINT2( 187198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh "osd_sense_attribute_identification" 187298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh "attr_page=0x%x attr_id=0x%x\n", 187398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh attr_page, attr_id); 187498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh } 187598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh } 187698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh /*These are not legal for OSD*/ 187798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh case scsi_sense_field_replaceable_unit: 187898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh OSD_SENSE_PRINT2("scsi_sense_field_replaceable_unit\n"); 187998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh break; 188098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh case scsi_sense_stream_commands: 188198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh OSD_SENSE_PRINT2("scsi_sense_stream_commands\n"); 188298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh break; 188398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh case scsi_sense_block_commands: 188498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh OSD_SENSE_PRINT2("scsi_sense_block_commands\n"); 188598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh break; 188698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh case scsi_sense_ata_return: 188798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh OSD_SENSE_PRINT2("scsi_sense_ata_return\n"); 188898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh break; 188998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh default: 189098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh if (ssd->descriptor_type <= scsi_sense_Reserved_last) 189198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh OSD_SENSE_PRINT2( 189298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh "scsi_sense Reserved descriptor (0x%x)", 189398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh ssd->descriptor_type); 189498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh else 189598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh OSD_SENSE_PRINT2( 189698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh "scsi_sense Vendor descriptor (0x%x)", 189798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh ssd->descriptor_type); 189898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh } 189998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 190098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh cur_descriptor += cur_len; 190198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh } 190298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 1903aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harroshanalyze: 1904aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh if (!osi->key) { 1905aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh /* scsi sense is Empty, the request was never issued to target 1906aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh * linux return code might tell us what happened. 1907aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh */ 1908aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh if (or->async_error == -ENOMEM) 1909aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh osi->osd_err_pri = OSD_ERR_PRI_RESOURCE; 1910aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh else 1911aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh osi->osd_err_pri = OSD_ERR_PRI_UNREACHABLE; 1912aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh ret = or->async_error; 1913aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh } else if (osi->key <= scsi_sk_recovered_error) { 1914aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh osi->osd_err_pri = 0; 1915aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh ret = 0; 1916aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh } else if (osi->additional_code == scsi_invalid_field_in_cdb) { 1917aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh if (osi->cdb_field_offset == OSD_CFO_STARTING_BYTE) { 1918aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh osi->osd_err_pri = OSD_ERR_PRI_CLEAR_PAGES; 1919aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh ret = -EFAULT; /* caller should recover from this */ 1920aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh } else if (osi->cdb_field_offset == OSD_CFO_OBJECT_ID) { 1921aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh osi->osd_err_pri = OSD_ERR_PRI_NOT_FOUND; 1922aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh ret = -ENOENT; 1923aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh } else if (osi->cdb_field_offset == OSD_CFO_PERMISSIONS) { 1924aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh osi->osd_err_pri = OSD_ERR_PRI_NO_ACCESS; 1925aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh ret = -EACCES; 1926aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh } else { 1927aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh osi->osd_err_pri = OSD_ERR_PRI_BAD_CRED; 1928aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh ret = -EINVAL; 1929aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh } 1930aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh } else if (osi->additional_code == osd_quota_error) { 1931aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh osi->osd_err_pri = OSD_ERR_PRI_NO_SPACE; 1932aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh ret = -ENOSPC; 1933aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh } else if (_is_osd_security_code(osi->additional_code)) { 1934aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh osi->osd_err_pri = OSD_ERR_PRI_BAD_CRED; 1935aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh ret = -EINVAL; 1936aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh } else { 1937aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh osi->osd_err_pri = OSD_ERR_PRI_EIO; 1938aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh ret = -EIO; 1939aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh } 1940aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh 19415d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh if (!or->out.residual) 19425d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh or->out.residual = or->out.total_bytes; 19435d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh if (!or->in.residual) 19445d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh or->in.residual = or->in.total_bytes; 1945aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh 1946aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh return ret; 194798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh} 194898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz HarroshEXPORT_SYMBOL(osd_req_decode_sense_full); 194998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh 195002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* 195102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Implementation of osd_sec.h API 195202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * TODO: Move to a separate osd_sec.c file at a later stage. 195302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */ 195402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 195502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshenum { OSD_SEC_CAP_V1_ALL_CAPS = 195602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_SEC_CAP_APPEND | OSD_SEC_CAP_OBJ_MGMT | OSD_SEC_CAP_REMOVE | 195702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_SEC_CAP_CREATE | OSD_SEC_CAP_SET_ATTR | OSD_SEC_CAP_GET_ATTR | 195802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_SEC_CAP_WRITE | OSD_SEC_CAP_READ | OSD_SEC_CAP_POL_SEC | 195902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_SEC_CAP_GLOBAL | OSD_SEC_CAP_DEV_MGMT 196002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}; 196102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 1962c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harroshenum { OSD_SEC_CAP_V2_ALL_CAPS = 1963c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh OSD_SEC_CAP_V1_ALL_CAPS | OSD_SEC_CAP_QUERY | OSD_SEC_CAP_M_OBJECT 1964c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh}; 1965c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh 196602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_sec_init_nosec_doall_caps(void *caps, 196702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh const struct osd_obj_id *obj, bool is_collection, const bool is_v1) 196802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 196902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh struct osd_capability *cap = caps; 197002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh u8 type; 197102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh u8 descriptor_type; 197202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 197302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (likely(obj->id)) { 197402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh if (unlikely(is_collection)) { 197502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh type = OSD_SEC_OBJ_COLLECTION; 197602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh descriptor_type = is_v1 ? OSD_SEC_OBJ_DESC_OBJ : 197702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_SEC_OBJ_DESC_COL; 197802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } else { 197902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh type = OSD_SEC_OBJ_USER; 198002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh descriptor_type = OSD_SEC_OBJ_DESC_OBJ; 198102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 198202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh WARN_ON(!obj->partition); 198302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } else { 198402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh type = obj->partition ? OSD_SEC_OBJ_PARTITION : 198502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh OSD_SEC_OBJ_ROOT; 198602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh descriptor_type = OSD_SEC_OBJ_DESC_PAR; 198702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh } 198802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 198902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh memset(cap, 0, sizeof(*cap)); 199002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 199102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->h.format = OSD_SEC_CAP_FORMAT_VER1; 199202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->h.integrity_algorithm__key_version = 0; /* MAKE_BYTE(0, 0); */ 199302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->h.security_method = OSD_SEC_NOSEC; 199402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/* cap->expiration_time; 199502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->AUDIT[30-10]; 199602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->discriminator[42-30]; 199702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->object_created_time; */ 199802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->h.object_type = type; 199902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh osd_sec_set_caps(&cap->h, OSD_SEC_CAP_V1_ALL_CAPS); 200002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->h.object_descriptor_type = descriptor_type; 200102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->od.obj_desc.policy_access_tag = 0; 200202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->od.obj_desc.allowed_partition_id = cpu_to_be64(obj->partition); 200302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh cap->od.obj_desc.allowed_object_id = cpu_to_be64(obj->id); 200402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 200502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_sec_init_nosec_doall_caps); 200602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh 2007c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh/* FIXME: Extract version from caps pointer. 2008c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh * Also Pete's target only supports caps from OSDv1 for now 2009c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh */ 201002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_set_caps(struct osd_cdb *cdb, const void *caps) 201102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{ 2012c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh bool is_ver1 = true; 2013c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh /* NOTE: They start at same address */ 2014c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh memcpy(&cdb->v1.caps, caps, is_ver1 ? OSDv1_CAP_LEN : OSD_CAP_LEN); 201502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh} 20164ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 2017345c435dbb0b77b00ffe73801102533e24c647afBoaz Harroshbool osd_is_sec_alldata(struct osd_security_parameters *sec_parms __unused) 2018345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh{ 2019345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh return false; 2020345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh} 2021345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 2022345c435dbb0b77b00ffe73801102533e24c647afBoaz Harroshvoid osd_sec_sign_cdb(struct osd_cdb *ocdb __unused, const u8 *cap_key __unused) 2023345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh{ 2024345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh} 2025345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 2026345c435dbb0b77b00ffe73801102533e24c647afBoaz Harroshvoid osd_sec_sign_data(void *data_integ __unused, 2027345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh struct bio *bio __unused, const u8 *cap_key __unused) 2028345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh{ 2029345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh} 2030345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh 20314ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh/* 20324ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * Declared in osd_protocol.h 20334ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * 4.12.5 Data-In and Data-Out buffer offsets 20344ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * byte offset = mantissa * (2^(exponent+8)) 20354ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * Returns the smallest allowed encoded offset that contains given @offset 20364ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * The actual encoded offset returned is @offset + *@padding. 20374ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh */ 20384ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshosd_cdb_offset __osd_encode_offset( 20394ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh u64 offset, unsigned *padding, int min_shift, int max_shift) 20404ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{ 20414ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh u64 try_offset = -1, mod, align; 20424ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh osd_cdb_offset be32_offset; 20434ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh int shift; 20444ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 20454ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh *padding = 0; 20464ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (!offset) 20474ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return 0; 20484ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 20494ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh for (shift = min_shift; shift < max_shift; ++shift) { 20504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh try_offset = offset >> shift; 20514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (try_offset < (1 << OSD_OFFSET_MAX_BITS)) 20524ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh break; 20534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 20544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 20554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh BUG_ON(shift == max_shift); 20564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 20574ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh align = 1 << shift; 20584ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh mod = offset & (align - 1); 20594ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh if (mod) { 20604ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh *padding = align - mod; 20614ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh try_offset += 1; 20624ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh } 20634ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 20644ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh try_offset |= ((shift - 8) & 0xf) << 28; 20654ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh be32_offset = cpu_to_be32((u32)try_offset); 20664ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh 20674ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh OSD_DEBUG("offset=%llu mantissa=%llu exp=%d encoded=%x pad=%d\n", 20684ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh _LLU(offset), _LLU(try_offset & 0x0FFFFFFF), shift, 20694ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh be32_offset, *padding); 20704ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh return be32_offset; 20714ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh} 2072