osd_initiator.c revision 5d0961fd1f25e117f907f3af3aaa870637049252
102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/*
202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * osd_initiator - Main body of the osd initiator library.
302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh *
402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Note: The file does not contain the advanced security functionality which
502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * is only needed by the security_manager's initiators.
602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh *
702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Copyright (C) 2008 Panasas Inc.  All rights reserved.
802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh *
902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Authors:
1002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh *   Boaz Harrosh <bharrosh@panasas.com>
1102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh *   Benny Halevy <bhalevy@panasas.com>
1202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh *
1302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * This program is free software; you can redistribute it and/or modify
1402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * it under the terms of the GNU General Public License version 2
1502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh *
1602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Redistribution and use in source and binary forms, with or without
1702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * modification, are permitted provided that the following conditions
1802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * are met:
1902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh *
2002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh *  1. Redistributions of source code must retain the above copyright
2102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh *     notice, this list of conditions and the following disclaimer.
2202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh *  2. Redistributions in binary form must reproduce the above copyright
2302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh *     notice, this list of conditions and the following disclaimer in the
2402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh *     documentation and/or other materials provided with the distribution.
2502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh *  3. Neither the name of the Panasas company nor the names of its
2602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh *     contributors may be used to endorse or promote products derived
2702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh *     from this software without specific prior written permission.
2802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh *
2902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
3002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
3102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
3302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
3402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
3602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
3702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */
4102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
4202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh#include <scsi/osd_initiator.h>
4302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh#include <scsi/osd_sec.h>
441b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh#include <scsi/osd_attributes.h>
4598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh#include <scsi/osd_sense.h>
4698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh
4702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh#include <scsi/scsi_device.h>
4802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
4902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh#include "osd_debug.h"
5002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh#ifndef __unused
524ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh#    define __unused			__attribute__((unused))
534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh#endif
544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
5502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshenum { OSD_REQ_RETRIES = 1 };
5602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
5702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshMODULE_AUTHOR("Boaz Harrosh <bharrosh@panasas.com>");
5802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshMODULE_DESCRIPTION("open-osd initiator library libosd.ko");
5902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshMODULE_LICENSE("GPL");
6002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
6102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic inline void build_test(void)
6202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
6302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	/* structures were not packed */
6402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	BUILD_BUG_ON(sizeof(struct osd_capability) != OSD_CAP_LEN);
65c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	BUILD_BUG_ON(sizeof(struct osdv2_cdb) != OSD_TOTAL_CDB_LEN);
6602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	BUILD_BUG_ON(sizeof(struct osdv1_cdb) != OSDv1_TOTAL_CDB_LEN);
6702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
6802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
691b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harroshstatic const char *_osd_ver_desc(struct osd_request *or)
701b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh{
711b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	return osd_req_is_ver1(or) ? "OSD1" : "OSD2";
721b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh}
731b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
741b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh#define ATTR_DEF_RI(id, len) ATTR_DEF(OSD_APAGE_ROOT_INFORMATION, id, len)
751b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
762cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harroshstatic int _osd_get_print_system_info(struct osd_dev *od,
772cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh	void *caps, struct osd_dev_info *odi)
781b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh{
791b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	struct osd_request *or;
801b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	struct osd_attr get_attrs[] = {
811b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		ATTR_DEF_RI(OSD_ATTR_RI_VENDOR_IDENTIFICATION, 8),
821b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_IDENTIFICATION, 16),
831b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_MODEL, 32),
841b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_REVISION_LEVEL, 4),
851b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		ATTR_DEF_RI(OSD_ATTR_RI_PRODUCT_SERIAL_NUMBER, 64 /*variable*/),
861b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		ATTR_DEF_RI(OSD_ATTR_RI_OSD_NAME, 64 /*variable*/),
871b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		ATTR_DEF_RI(OSD_ATTR_RI_TOTAL_CAPACITY, 8),
881b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		ATTR_DEF_RI(OSD_ATTR_RI_USED_CAPACITY, 8),
891b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		ATTR_DEF_RI(OSD_ATTR_RI_NUMBER_OF_PARTITIONS, 8),
901b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		ATTR_DEF_RI(OSD_ATTR_RI_CLOCK, 6),
911b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		/* IBM-OSD-SIM Has a bug with this one put it last */
921b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		ATTR_DEF_RI(OSD_ATTR_RI_OSD_SYSTEM_ID, 20),
931b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	};
941b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	void *iter = NULL, *pFirst;
951b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	int nelem = ARRAY_SIZE(get_attrs), a = 0;
961b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	int ret;
971b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
981b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	or = osd_start_request(od, GFP_KERNEL);
991b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	if (!or)
1001b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		return -ENOMEM;
1011b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
1021b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	/* get attrs */
1031b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	osd_req_get_attributes(or, &osd_root_object);
1041b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	osd_req_add_get_attr_list(or, get_attrs, ARRAY_SIZE(get_attrs));
1051b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
1061b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	ret = osd_finalize_request(or, 0, caps, NULL);
1071b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	if (ret)
1081b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		goto out;
1091b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
1101b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	ret = osd_execute_request(or);
1111b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	if (ret) {
1121b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		OSD_ERR("Failed to detect %s => %d\n", _osd_ver_desc(or), ret);
1131b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		goto out;
1141b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	}
1151b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
1161b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	osd_req_decode_get_attr_list(or, get_attrs, &nelem, &iter);
1171b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
1181b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	OSD_INFO("Detected %s device\n",
1191b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		_osd_ver_desc(or));
1201b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
1211b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	pFirst = get_attrs[a++].val_ptr;
122de6b20385b1c14f97ccdf7da173b4c9a7405083bBoaz Harrosh	OSD_INFO("VENDOR_IDENTIFICATION  [%s]\n",
1231b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		(char *)pFirst);
1241b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
1251b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	pFirst = get_attrs[a++].val_ptr;
126de6b20385b1c14f97ccdf7da173b4c9a7405083bBoaz Harrosh	OSD_INFO("PRODUCT_IDENTIFICATION [%s]\n",
1271b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		(char *)pFirst);
1281b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
1291b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	pFirst = get_attrs[a++].val_ptr;
130de6b20385b1c14f97ccdf7da173b4c9a7405083bBoaz Harrosh	OSD_INFO("PRODUCT_MODEL          [%s]\n",
1311b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		(char *)pFirst);
1321b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
1331b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	pFirst = get_attrs[a++].val_ptr;
134de6b20385b1c14f97ccdf7da173b4c9a7405083bBoaz Harrosh	OSD_INFO("PRODUCT_REVISION_LEVEL [%u]\n",
13597218a1499391b174ea95e05b7a40fbb73e79813Boaz Harrosh		pFirst ? get_unaligned_be32(pFirst) : ~0U);
1361b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
1371b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	pFirst = get_attrs[a++].val_ptr;
138de6b20385b1c14f97ccdf7da173b4c9a7405083bBoaz Harrosh	OSD_INFO("PRODUCT_SERIAL_NUMBER  [%s]\n",
1391b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		(char *)pFirst);
1401b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
1412cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh	odi->osdname_len = get_attrs[a].len;
1422cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh	/* Avoid NULL for memcmp optimization 0-length is good enough */
1432cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh	odi->osdname = kzalloc(odi->osdname_len + 1, GFP_KERNEL);
1442cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh	if (odi->osdname_len)
1452cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh		memcpy(odi->osdname, get_attrs[a].val_ptr, odi->osdname_len);
1462cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh	OSD_INFO("OSD_NAME               [%s]\n", odi->osdname);
1471b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	a++;
1481b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
1491b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	pFirst = get_attrs[a++].val_ptr;
150de6b20385b1c14f97ccdf7da173b4c9a7405083bBoaz Harrosh	OSD_INFO("TOTAL_CAPACITY         [0x%llx]\n",
15197218a1499391b174ea95e05b7a40fbb73e79813Boaz Harrosh		pFirst ? _LLU(get_unaligned_be64(pFirst)) : ~0ULL);
1521b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
1531b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	pFirst = get_attrs[a++].val_ptr;
154de6b20385b1c14f97ccdf7da173b4c9a7405083bBoaz Harrosh	OSD_INFO("USED_CAPACITY          [0x%llx]\n",
15597218a1499391b174ea95e05b7a40fbb73e79813Boaz Harrosh		pFirst ? _LLU(get_unaligned_be64(pFirst)) : ~0ULL);
1561b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
1571b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	pFirst = get_attrs[a++].val_ptr;
158de6b20385b1c14f97ccdf7da173b4c9a7405083bBoaz Harrosh	OSD_INFO("NUMBER_OF_PARTITIONS   [%llu]\n",
15997218a1499391b174ea95e05b7a40fbb73e79813Boaz Harrosh		pFirst ? _LLU(get_unaligned_be64(pFirst)) : ~0ULL);
16097218a1499391b174ea95e05b7a40fbb73e79813Boaz Harrosh
16197218a1499391b174ea95e05b7a40fbb73e79813Boaz Harrosh	if (a >= nelem)
16297218a1499391b174ea95e05b7a40fbb73e79813Boaz Harrosh		goto out;
1631b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
1641b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	/* FIXME: Where are the time utilities */
1651b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	pFirst = get_attrs[a++].val_ptr;
166de6b20385b1c14f97ccdf7da173b4c9a7405083bBoaz Harrosh	OSD_INFO("CLOCK                  [0x%02x%02x%02x%02x%02x%02x]\n",
1671b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		((char *)pFirst)[0], ((char *)pFirst)[1],
1681b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		((char *)pFirst)[2], ((char *)pFirst)[3],
1691b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		((char *)pFirst)[4], ((char *)pFirst)[5]);
1701b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
1711b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	if (a < nelem) { /* IBM-OSD-SIM bug, Might not have it */
1721b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		unsigned len = get_attrs[a].len;
1731b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		char sid_dump[32*4 + 2]; /* 2nibbles+space+ASCII */
1741b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
1751b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		hex_dump_to_buffer(get_attrs[a].val_ptr, len, 32, 1,
1761b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh				   sid_dump, sizeof(sid_dump), true);
177de6b20385b1c14f97ccdf7da173b4c9a7405083bBoaz Harrosh		OSD_INFO("OSD_SYSTEM_ID(%d)\n"
178de6b20385b1c14f97ccdf7da173b4c9a7405083bBoaz Harrosh			 "        [%s]\n", len, sid_dump);
1792cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh
1802cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh		if (unlikely(len > sizeof(odi->systemid))) {
1812cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh			OSD_ERR("OSD Target error: OSD_SYSTEM_ID too long(%d). "
1822cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh				"device idetification might not work\n", len);
1832cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh			len = sizeof(odi->systemid);
1842cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh		}
1852cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh		odi->systemid_len = len;
1862cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh		memcpy(odi->systemid, get_attrs[a].val_ptr, len);
1871b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		a++;
1881b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	}
1891b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harroshout:
1901b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	osd_end_request(or);
1911b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	return ret;
1921b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh}
1931b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
1942cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harroshint osd_auto_detect_ver(struct osd_dev *od,
1952cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh	void *caps, struct osd_dev_info *odi)
1961b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh{
1971b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	int ret;
1981b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
1991b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	/* Auto-detect the osd version */
2002cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh	ret = _osd_get_print_system_info(od, caps, odi);
2011b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	if (ret) {
2021b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		osd_dev_set_ver(od, OSD_VER1);
2031b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh		OSD_DEBUG("converting to OSD1\n");
2042cdd6410e5a1665823f2a048fc7f8f6a8384be1dBoaz Harrosh		ret = _osd_get_print_system_info(od, caps, odi);
2051b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	}
2061b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
2071b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh	return ret;
2081b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh}
2091b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz HarroshEXPORT_SYMBOL(osd_auto_detect_ver);
2101b9dce94c8a24a3f1a01fcdf688f2d903b32acdfBoaz Harrosh
21102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic unsigned _osd_req_cdb_len(struct osd_request *or)
21202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
213c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	return osd_req_is_ver1(or) ? OSDv1_TOTAL_CDB_LEN : OSD_TOTAL_CDB_LEN;
21402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
21502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
2164ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic unsigned _osd_req_alist_elem_size(struct osd_request *or, unsigned len)
2174ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{
218c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	return osd_req_is_ver1(or) ?
219c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh		osdv1_attr_list_elem_size(len) :
220c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh		osdv2_attr_list_elem_size(len);
2214ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh}
2224ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
22371f32e31e5638df37904697e2d04182935add85dBoaz Harroshstatic void _osd_req_alist_elem_encode(struct osd_request *or,
22471f32e31e5638df37904697e2d04182935add85dBoaz Harrosh	void *attr_last, const struct osd_attr *oa)
22571f32e31e5638df37904697e2d04182935add85dBoaz Harrosh{
22671f32e31e5638df37904697e2d04182935add85dBoaz Harrosh	if (osd_req_is_ver1(or)) {
22771f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		struct osdv1_attributes_list_element *attr = attr_last;
22871f32e31e5638df37904697e2d04182935add85dBoaz Harrosh
22971f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		attr->attr_page = cpu_to_be32(oa->attr_page);
23071f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		attr->attr_id = cpu_to_be32(oa->attr_id);
23171f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		attr->attr_bytes = cpu_to_be16(oa->len);
23271f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		memcpy(attr->attr_val, oa->val_ptr, oa->len);
23371f32e31e5638df37904697e2d04182935add85dBoaz Harrosh	} else {
23471f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		struct osdv2_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	}
24171f32e31e5638df37904697e2d04182935add85dBoaz Harrosh}
24271f32e31e5638df37904697e2d04182935add85dBoaz Harrosh
24371f32e31e5638df37904697e2d04182935add85dBoaz Harroshstatic int _osd_req_alist_elem_decode(struct osd_request *or,
24471f32e31e5638df37904697e2d04182935add85dBoaz Harrosh	void *cur_p, struct osd_attr *oa, unsigned max_bytes)
24571f32e31e5638df37904697e2d04182935add85dBoaz Harrosh{
24671f32e31e5638df37904697e2d04182935add85dBoaz Harrosh	unsigned inc;
24771f32e31e5638df37904697e2d04182935add85dBoaz Harrosh	if (osd_req_is_ver1(or)) {
24871f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		struct osdv1_attributes_list_element *attr = cur_p;
24971f32e31e5638df37904697e2d04182935add85dBoaz Harrosh
25071f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		if (max_bytes < sizeof(*attr))
25171f32e31e5638df37904697e2d04182935add85dBoaz Harrosh			return -1;
25271f32e31e5638df37904697e2d04182935add85dBoaz Harrosh
25371f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		oa->len = be16_to_cpu(attr->attr_bytes);
25471f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		inc = _osd_req_alist_elem_size(or, oa->len);
25571f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		if (inc > max_bytes)
25671f32e31e5638df37904697e2d04182935add85dBoaz Harrosh			return -1;
25771f32e31e5638df37904697e2d04182935add85dBoaz Harrosh
25871f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		oa->attr_page = be32_to_cpu(attr->attr_page);
25971f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		oa->attr_id = be32_to_cpu(attr->attr_id);
26071f32e31e5638df37904697e2d04182935add85dBoaz Harrosh
26171f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		/* OSD1: On empty attributes we return a pointer to 2 bytes
26271f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		 * of zeros. This keeps similar behaviour with OSD2.
26371f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		 * (See below)
26471f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		 */
26571f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		oa->val_ptr = likely(oa->len) ? attr->attr_val :
26671f32e31e5638df37904697e2d04182935add85dBoaz Harrosh						(u8 *)&attr->attr_bytes;
26771f32e31e5638df37904697e2d04182935add85dBoaz Harrosh	} else {
26871f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		struct osdv2_attributes_list_element *attr = cur_p;
26971f32e31e5638df37904697e2d04182935add85dBoaz Harrosh
27071f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		if (max_bytes < sizeof(*attr))
27171f32e31e5638df37904697e2d04182935add85dBoaz Harrosh			return -1;
27271f32e31e5638df37904697e2d04182935add85dBoaz Harrosh
27371f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		oa->len = be16_to_cpu(attr->attr_bytes);
27471f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		inc = _osd_req_alist_elem_size(or, oa->len);
27571f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		if (inc > max_bytes)
27671f32e31e5638df37904697e2d04182935add85dBoaz Harrosh			return -1;
27771f32e31e5638df37904697e2d04182935add85dBoaz Harrosh
27871f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		oa->attr_page = be32_to_cpu(attr->attr_page);
27971f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		oa->attr_id = be32_to_cpu(attr->attr_id);
28071f32e31e5638df37904697e2d04182935add85dBoaz Harrosh
281e9da4d7f731dafc2b93ce7b31aa09c4d935ef978Boaz Harrosh		/* OSD2: For convenience, on empty attributes, we return 8 bytes
282e9da4d7f731dafc2b93ce7b31aa09c4d935ef978Boaz Harrosh		 * of zeros here. This keeps the same behaviour with OSD2r04,
283e9da4d7f731dafc2b93ce7b31aa09c4d935ef978Boaz Harrosh		 * and is nice with null terminating ASCII fields.
284e9da4d7f731dafc2b93ce7b31aa09c4d935ef978Boaz Harrosh		 * oa->val_ptr == NULL marks the end-of-list, or error.
285e9da4d7f731dafc2b93ce7b31aa09c4d935ef978Boaz Harrosh		 */
286e9da4d7f731dafc2b93ce7b31aa09c4d935ef978Boaz Harrosh		oa->val_ptr = likely(oa->len) ? attr->attr_val : attr->reserved;
28771f32e31e5638df37904697e2d04182935add85dBoaz Harrosh	}
28871f32e31e5638df37904697e2d04182935add85dBoaz Harrosh	return inc;
28971f32e31e5638df37904697e2d04182935add85dBoaz Harrosh}
29071f32e31e5638df37904697e2d04182935add85dBoaz Harrosh
2914ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic unsigned _osd_req_alist_size(struct osd_request *or, void *list_head)
2924ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{
293c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	return osd_req_is_ver1(or) ?
294c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh		osdv1_list_size(list_head) :
295c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh		osdv2_list_size(list_head);
2964ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh}
2974ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
2984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic unsigned _osd_req_sizeof_alist_header(struct osd_request *or)
2994ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{
300c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	return osd_req_is_ver1(or) ?
301c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh		sizeof(struct osdv1_attributes_list_header) :
302c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh		sizeof(struct osdv2_attributes_list_header);
3034ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh}
3044ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
3054ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic void _osd_req_set_alist_type(struct osd_request *or,
3064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	void *list, int list_type)
3074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{
308c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	if (osd_req_is_ver1(or)) {
309c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh		struct osdv1_attributes_list_header *attr_list = list;
310c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh
311c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh		memset(attr_list, 0, sizeof(*attr_list));
312c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh		attr_list->type = list_type;
313c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	} else {
314c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh		struct osdv2_attributes_list_header *attr_list = list;
3154ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
316c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh		memset(attr_list, 0, sizeof(*attr_list));
317c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh		attr_list->type = list_type;
318c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	}
3194ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh}
3204ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
3214ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic bool _osd_req_is_alist_type(struct osd_request *or,
3224ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	void *list, int list_type)
3234ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{
3244ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (!list)
3254ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		return false;
3264ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
327c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	if (osd_req_is_ver1(or)) {
3284ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		struct osdv1_attributes_list_header *attr_list = list;
3294ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
3304ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		return attr_list->type == list_type;
331c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	} else {
332c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh		struct osdv2_attributes_list_header *attr_list = list;
333c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh
334c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh		return attr_list->type == list_type;
3354ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	}
3364ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh}
3374ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
3383e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh/* This is for List-objects not Attributes-Lists */
3393e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harroshstatic void _osd_req_encode_olist(struct osd_request *or,
3403e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	struct osd_obj_id_list *list)
3413e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh{
3423e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb);
3433e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh
344c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	if (osd_req_is_ver1(or)) {
345c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh		cdbh->v1.list_identifier = list->list_identifier;
346c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh		cdbh->v1.start_address = list->continuation_id;
347c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	} else {
348c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh		cdbh->v2.list_identifier = list->list_identifier;
349c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh		cdbh->v2.start_address = list->continuation_id;
350c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	}
3513e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh}
3523e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh
3534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic osd_cdb_offset osd_req_encode_offset(struct osd_request *or,
3544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	u64 offset, unsigned *padding)
3554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{
3564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	return __osd_encode_offset(offset, padding,
357c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh			osd_req_is_ver1(or) ?
358c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh				OSDv1_OFFSET_MIN_SHIFT : OSD_OFFSET_MIN_SHIFT,
359c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh			OSD_OFFSET_MAX_SHIFT);
3604ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh}
3614ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
362345c435dbb0b77b00ffe73801102533e24c647afBoaz Harroshstatic struct osd_security_parameters *
363345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh_osd_req_sec_params(struct osd_request *or)
364345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh{
365345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh	struct osd_cdb *ocdb = &or->cdb;
366345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh
367c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	if (osd_req_is_ver1(or))
368f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh		return (struct osd_security_parameters *)&ocdb->v1.sec_params;
369c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	else
370f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh		return (struct osd_security_parameters *)&ocdb->v2.sec_params;
371345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh}
372345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh
37302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_dev_init(struct osd_dev *osdd, struct scsi_device *scsi_device)
37402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
37502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	memset(osdd, 0, sizeof(*osdd));
37602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	osdd->scsi_device = scsi_device;
37702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	osdd->def_timeout = BLK_DEFAULT_SG_TIMEOUT;
378c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh#ifdef OSD_VER1_SUPPORT
379c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	osdd->version = OSD_VER2;
380c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh#endif
38102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	/* TODO: Allocate pools for osd_request attributes ... */
38202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
38302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_dev_init);
38402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
38502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_dev_fini(struct osd_dev *osdd)
38602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
38702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	/* TODO: De-allocate pools */
38802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
38902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	osdd->scsi_device = NULL;
39002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
39102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_dev_fini);
39202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
39302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic struct osd_request *_osd_request_alloc(gfp_t gfp)
39402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
39502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	struct osd_request *or;
39602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
39702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	/* TODO: Use mempool with one saved request */
39802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	or = kzalloc(sizeof(*or), gfp);
39902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	return or;
40002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
40102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
40202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic void _osd_request_free(struct osd_request *or)
40302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
40402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	kfree(or);
40502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
40602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
40702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstruct osd_request *osd_start_request(struct osd_dev *dev, gfp_t gfp)
40802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
40902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	struct osd_request *or;
41002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
41102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	or = _osd_request_alloc(gfp);
41202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	if (!or)
41302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		return NULL;
41402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
41502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	or->osd_dev = dev;
41602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	or->alloc_flags = gfp;
41702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	or->timeout = dev->def_timeout;
41802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	or->retries = OSD_REQ_RETRIES;
41902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
42002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	return or;
42102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
42202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_start_request);
42302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
4244ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic void _osd_free_seg(struct osd_request *or __unused,
4254ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	struct _osd_req_data_segment *seg)
4264ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{
4274ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (!seg->buff || !seg->alloc_size)
4284ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		return;
4294ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
4304ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	kfree(seg->buff);
4314ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	seg->buff = NULL;
4324ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	seg->alloc_size = 0;
4334ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh}
4344ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
4355d0961fd1f25e117f907f3af3aaa870637049252Boaz Harroshstatic void _put_request(struct request *rq)
4368c0baccadc86d9f07e663dd255751dd70e461ba3Boaz Harrosh{
4375d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	/*
4385d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	 * If osd_finalize_request() was called but the request was not
4395d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	 * executed through the block layer, then we must release BIOs.
4405d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	 * TODO: Keep error code in or->async_error. Need to audit all
4415d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	 *       code paths.
4425d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	 */
4435d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	if (unlikely(rq->bio))
4445d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh		blk_end_request(rq, -ENOMEM, blk_rq_bytes(rq));
4455d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	else
4465d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh		blk_put_request(rq);
4478c0baccadc86d9f07e663dd255751dd70e461ba3Boaz Harrosh}
4488c0baccadc86d9f07e663dd255751dd70e461ba3Boaz Harrosh
44902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_end_request(struct osd_request *or)
45002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
45102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	struct request *rq = or->request;
45202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
4534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	_osd_free_seg(or, &or->set_attr);
4544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	_osd_free_seg(or, &or->enc_get_attr);
4554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	_osd_free_seg(or, &or->get_attr);
4564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
45702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	if (rq) {
45802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		if (rq->next_rq) {
4595d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh			_put_request(rq->next_rq);
4608c0baccadc86d9f07e663dd255751dd70e461ba3Boaz Harrosh			rq->next_rq = NULL;
46102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		}
46202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
4635d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh		_put_request(rq);
46402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	}
46502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	_osd_request_free(or);
46602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
46702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_end_request);
46802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
4695d0961fd1f25e117f907f3af3aaa870637049252Boaz Harroshstatic void _set_error_resid(struct osd_request *or, struct request *req,
4705d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh			     int error)
4715d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh{
4725d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	or->async_error = error;
4735d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	or->req_errors = req->errors ? : error;
4745d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	or->sense_len = req->sense_len;
4755d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	if (or->out.req)
4765d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh		or->out.residual = or->out.req->resid_len;
4775d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	if (or->in.req)
4785d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh		or->in.residual = or->in.req->resid_len;
4795d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh}
4805d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh
48102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshint osd_execute_request(struct osd_request *or)
48202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
4835d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	int error = blk_execute_rq(or->request->q, NULL, or->request, 0);
4845d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh
4855d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	_set_error_resid(or, or->request, error);
4865d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	return error;
48702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
48802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_execute_request);
48902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
49002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic void osd_request_async_done(struct request *req, int error)
49102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
49202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	struct osd_request *or = req->end_io_data;
49302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
4945d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	_set_error_resid(or, req, error);
4955d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	if (req->next_rq) {
4965d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh		__blk_put_request(req->q, req->next_rq);
4975d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh		req->next_rq = NULL;
498aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh	}
49902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
5005d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	__blk_put_request(req->q, req);
5015d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	or->request = NULL;
5025d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	or->in.req = NULL;
5035d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	or->out.req = NULL;
5045d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh
50502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	if (or->async_done)
50602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		or->async_done(or, or->async_private);
50702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	else
50802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		osd_end_request(or);
50902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
51002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
51102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshint osd_execute_request_async(struct osd_request *or,
51202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	osd_req_done_fn *done, void *private)
51302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
51402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	or->request->end_io_data = or;
51502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	or->async_private = private;
51602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	or->async_done = done;
51702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
51802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	blk_execute_rq_nowait(or->request->q, NULL, or->request, 0,
51902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh			      osd_request_async_done);
52002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	return 0;
52102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
52202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_execute_request_async);
52302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
5244ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshu8 sg_out_pad_buffer[1 << OSDv1_OFFSET_MIN_SHIFT];
5254ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshu8 sg_in_pad_buffer[1 << OSDv1_OFFSET_MIN_SHIFT];
5264ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
5274ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _osd_realloc_seg(struct osd_request *or,
5284ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	struct _osd_req_data_segment *seg, unsigned max_bytes)
5294ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{
5304ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	void *buff;
5314ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
5324ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (seg->alloc_size >= max_bytes)
5334ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		return 0;
5344ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
5354ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	buff = krealloc(seg->buff, max_bytes, or->alloc_flags);
5364ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (!buff) {
5374ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		OSD_ERR("Failed to Realloc %d-bytes was-%d\n", max_bytes,
5384ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			seg->alloc_size);
5394ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		return -ENOMEM;
5404ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	}
5414ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
5424ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	memset(buff + seg->alloc_size, 0, max_bytes - seg->alloc_size);
5434ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	seg->buff = buff;
5444ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	seg->alloc_size = max_bytes;
5454ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	return 0;
5464ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh}
5474ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
5484ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _alloc_set_attr_list(struct osd_request *or,
5494ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	const struct osd_attr *oa, unsigned nelem, unsigned add_bytes)
5504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{
5514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	unsigned total_bytes = add_bytes;
5524ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
5534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	for (; nelem; --nelem, ++oa)
5544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		total_bytes += _osd_req_alist_elem_size(or, oa->len);
5554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
5564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	OSD_DEBUG("total_bytes=%d\n", total_bytes);
5574ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	return _osd_realloc_seg(or, &or->set_attr, total_bytes);
5584ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh}
5594ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
5604ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _alloc_get_attr_desc(struct osd_request *or, unsigned max_bytes)
5614ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{
5624ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	OSD_DEBUG("total_bytes=%d\n", max_bytes);
5634ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	return _osd_realloc_seg(or, &or->enc_get_attr, max_bytes);
5644ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh}
5654ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
5664ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _alloc_get_attr_list(struct osd_request *or)
5674ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{
5684ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	OSD_DEBUG("total_bytes=%d\n", or->get_attr.total_bytes);
5694ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	return _osd_realloc_seg(or, &or->get_attr, or->get_attr.total_bytes);
5704ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh}
5714ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
57202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/*
57302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Common to all OSD commands
57402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */
57502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
57602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic void _osdv1_req_encode_common(struct osd_request *or,
57702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	__be16 act, const struct osd_obj_id *obj, u64 offset, u64 len)
57802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
57902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	struct osdv1_cdb *ocdb = &or->cdb.v1;
58002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
58102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	/*
58202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	 * For speed, the commands
58302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	 *	OSD_ACT_PERFORM_SCSI_COMMAND	, V1 0x8F7E, V2 0x8F7C
58402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	 *	OSD_ACT_SCSI_TASK_MANAGEMENT	, V1 0x8F7F, V2 0x8F7D
58502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	 * are not supported here. Should pass zero and set after the call
58602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	 */
58702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	act &= cpu_to_be16(~0x0080); /* V1 action code */
58802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
58902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	OSD_DEBUG("OSDv1 execute opcode 0x%x\n", be16_to_cpu(act));
59002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
59102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	ocdb->h.varlen_cdb.opcode = VARIABLE_LENGTH_CMD;
59202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	ocdb->h.varlen_cdb.additional_cdb_length = OSD_ADDITIONAL_CDB_LENGTH;
59302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	ocdb->h.varlen_cdb.service_action = act;
59402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
59502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	ocdb->h.partition = cpu_to_be64(obj->partition);
59602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	ocdb->h.object = cpu_to_be64(obj->id);
59702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	ocdb->h.v1.length = cpu_to_be64(len);
59802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	ocdb->h.v1.start_address = cpu_to_be64(offset);
59902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
60002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
601c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harroshstatic void _osdv2_req_encode_common(struct osd_request *or,
602c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	 __be16 act, const struct osd_obj_id *obj, u64 offset, u64 len)
603c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh{
604c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	struct osdv2_cdb *ocdb = &or->cdb.v2;
605c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh
606c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	OSD_DEBUG("OSDv2 execute opcode 0x%x\n", be16_to_cpu(act));
607c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh
608c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	ocdb->h.varlen_cdb.opcode = VARIABLE_LENGTH_CMD;
609c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	ocdb->h.varlen_cdb.additional_cdb_length = OSD_ADDITIONAL_CDB_LENGTH;
610c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	ocdb->h.varlen_cdb.service_action = act;
611c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh
612c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	ocdb->h.partition = cpu_to_be64(obj->partition);
613c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	ocdb->h.object = cpu_to_be64(obj->id);
614c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	ocdb->h.v2.length = cpu_to_be64(len);
615c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	ocdb->h.v2.start_address = cpu_to_be64(offset);
616c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh}
617c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh
61802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic void _osd_req_encode_common(struct osd_request *or,
61902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	__be16 act, const struct osd_obj_id *obj, u64 offset, u64 len)
62002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
621c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	if (osd_req_is_ver1(or))
622c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh		_osdv1_req_encode_common(or, act, obj, offset, len);
623c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	else
624c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh		_osdv2_req_encode_common(or, act, obj, offset, len);
62502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
62602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
62702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/*
62802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Device commands
62902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */
630ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_set_master_seed_xchg(struct osd_request *, ...); */
631ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_set_master_key(struct osd_request *, ...); */
632ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh
63302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_format(struct osd_request *or, u64 tot_capacity)
63402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
63502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	_osd_req_encode_common(or, OSD_ACT_FORMAT_OSD, &osd_root_object, 0,
63602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh				tot_capacity);
63702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
63802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_format);
63902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
6403e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harroshint osd_req_list_dev_partitions(struct osd_request *or,
6413e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	osd_id initial_id, struct osd_obj_id_list *list, unsigned nelem)
6423e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh{
6433e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	return osd_req_list_partition_objects(or, 0, initial_id, list, nelem);
6443e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh}
6453e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz HarroshEXPORT_SYMBOL(osd_req_list_dev_partitions);
6463e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh
6473e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harroshstatic void _osd_req_encode_flush(struct osd_request *or,
6483e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	enum osd_options_flush_scope_values op)
6493e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh{
6503e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	struct osd_cdb_head *ocdb = osd_cdb_head(&or->cdb);
6513e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh
6523e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	ocdb->command_specific_options = op;
6533e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh}
6543e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh
6553e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harroshvoid osd_req_flush_obsd(struct osd_request *or,
6563e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	enum osd_options_flush_scope_values op)
6573e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh{
6583e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	_osd_req_encode_common(or, OSD_ACT_FLUSH_OSD, &osd_root_object, 0, 0);
6593e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	_osd_req_encode_flush(or, op);
6603e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh}
6613e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz HarroshEXPORT_SYMBOL(osd_req_flush_obsd);
6623e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh
663ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_perform_scsi_command(struct osd_request *,
664ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh	const u8 *cdb, ...); */
665ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_task_management(struct osd_request *, ...); */
666ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh
66702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/*
66802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Partition commands
66902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */
67002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic void _osd_req_encode_partition(struct osd_request *or,
67102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	__be16 act, osd_id partition)
67202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
67302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	struct osd_obj_id par = {
67402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		.partition = partition,
67502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		.id = 0,
67602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	};
67702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
67802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	_osd_req_encode_common(or, act, &par, 0, 0);
67902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
68002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
68102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_create_partition(struct osd_request *or, osd_id partition)
68202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
68302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	_osd_req_encode_partition(or, OSD_ACT_CREATE_PARTITION, partition);
68402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
68502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_create_partition);
68602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
68702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_remove_partition(struct osd_request *or, osd_id partition)
68802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
68902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	_osd_req_encode_partition(or, OSD_ACT_REMOVE_PARTITION, partition);
69002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
69102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_remove_partition);
69202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
693ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_set_partition_key(struct osd_request *,
694ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh	osd_id partition, u8 new_key_id[OSD_CRYPTO_KEYID_SIZE],
695ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh	u8 seed[OSD_CRYPTO_SEED_SIZE]); */
696ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh
6973e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harroshstatic int _osd_req_list_objects(struct osd_request *or,
6983e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	__be16 action, const struct osd_obj_id *obj, osd_id initial_id,
6993e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	struct osd_obj_id_list *list, unsigned nelem)
7003e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh{
701fc2fac5b5f11e2bee3bf37215c8746236f5ea188Boaz Harrosh	struct request_queue *q = osd_request_queue(or->osd_dev);
7023e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	u64 len = nelem * sizeof(osd_id) + sizeof(*list);
7033e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	struct bio *bio;
7043e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh
7053e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	_osd_req_encode_common(or, action, obj, (u64)initial_id, len);
7063e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh
7073e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	if (list->list_identifier)
7083e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh		_osd_req_encode_olist(or, list);
7093e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh
7103e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	WARN_ON(or->in.bio);
7113e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	bio = bio_map_kern(q, list, len, or->alloc_flags);
712bf5e84f69618f416e89a5a53434a8c865e70252eDan Carpenter	if (IS_ERR(bio)) {
7133e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh		OSD_ERR("!!! Failed to allocate list_objects BIO\n");
714bf5e84f69618f416e89a5a53434a8c865e70252eDan Carpenter		return PTR_ERR(bio);
7153e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	}
7163e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh
7173e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	bio->bi_rw &= ~(1 << BIO_RW);
7183e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	or->in.bio = bio;
7193e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	or->in.total_bytes = bio->bi_size;
7203e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	return 0;
7213e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh}
7223e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh
7233e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harroshint osd_req_list_partition_collections(struct osd_request *or,
7243e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	osd_id partition, osd_id initial_id, struct osd_obj_id_list *list,
7253e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	unsigned nelem)
7263e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh{
7273e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	struct osd_obj_id par = {
7283e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh		.partition = partition,
7293e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh		.id = 0,
7303e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	};
7313e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh
7323e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	return osd_req_list_collection_objects(or, &par, initial_id, list,
7333e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh					       nelem);
7343e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh}
7353e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz HarroshEXPORT_SYMBOL(osd_req_list_partition_collections);
7363e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh
7373e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harroshint osd_req_list_partition_objects(struct osd_request *or,
7383e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	osd_id partition, osd_id initial_id, struct osd_obj_id_list *list,
7393e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	unsigned nelem)
7403e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh{
7413e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	struct osd_obj_id par = {
7423e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh		.partition = partition,
7433e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh		.id = 0,
7443e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	};
7453e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh
7463e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	return _osd_req_list_objects(or, OSD_ACT_LIST, &par, initial_id, list,
7473e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh				     nelem);
7483e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh}
7493e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz HarroshEXPORT_SYMBOL(osd_req_list_partition_objects);
7503e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh
7513e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harroshvoid osd_req_flush_partition(struct osd_request *or,
7523e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	osd_id partition, enum osd_options_flush_scope_values op)
7533e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh{
7543e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	_osd_req_encode_partition(or, OSD_ACT_FLUSH_PARTITION, partition);
7553e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	_osd_req_encode_flush(or, op);
7563e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh}
7573e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz HarroshEXPORT_SYMBOL(osd_req_flush_partition);
7583e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh
7593e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh/*
7603e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh * Collection commands
7613e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh */
762ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_create_collection(struct osd_request *,
763ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh	const struct osd_obj_id *); */
764ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_remove_collection(struct osd_request *,
765ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh	const struct osd_obj_id *); */
766ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh
7673e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harroshint osd_req_list_collection_objects(struct osd_request *or,
7683e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	const struct osd_obj_id *obj, osd_id initial_id,
7693e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	struct osd_obj_id_list *list, unsigned nelem)
7703e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh{
7713e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	return _osd_req_list_objects(or, OSD_ACT_LIST_COLLECTION, obj,
7723e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh				     initial_id, list, nelem);
7733e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh}
7743e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz HarroshEXPORT_SYMBOL(osd_req_list_collection_objects);
7753e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh
776ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void query(struct osd_request *, ...); V2 */
777ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh
7783e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harroshvoid osd_req_flush_collection(struct osd_request *or,
7793e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	const struct osd_obj_id *obj, enum osd_options_flush_scope_values op)
7803e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh{
7813e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	_osd_req_encode_common(or, OSD_ACT_FLUSH_PARTITION, obj, 0, 0);
7823e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	_osd_req_encode_flush(or, op);
7833e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh}
7843e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz HarroshEXPORT_SYMBOL(osd_req_flush_collection);
7853e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh
786ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void get_member_attrs(struct osd_request *, ...); V2 */
787ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void set_member_attrs(struct osd_request *, ...); V2 */
788ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh
78902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/*
79002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Object commands
79102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */
79202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_create_object(struct osd_request *or, struct osd_obj_id *obj)
79302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
79402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	_osd_req_encode_common(or, OSD_ACT_CREATE, obj, 0, 0);
79502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
79602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_create_object);
79702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
79802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_remove_object(struct osd_request *or, struct osd_obj_id *obj)
79902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
80002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	_osd_req_encode_common(or, OSD_ACT_REMOVE, obj, 0, 0);
80102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
80202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_remove_object);
80302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
804ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh
805ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_create_multi(struct osd_request *or,
806ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh	struct osd_obj_id *first, struct osd_obj_id_list *list, unsigned nelem);
807ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh*/
808ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh
80902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_write(struct osd_request *or,
81062f469b596dd0aadf046a69027087c18db43734eBoaz Harrosh	const struct osd_obj_id *obj, u64 offset,
81162f469b596dd0aadf046a69027087c18db43734eBoaz Harrosh	struct bio *bio, u64 len)
81202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
81362f469b596dd0aadf046a69027087c18db43734eBoaz Harrosh	_osd_req_encode_common(or, OSD_ACT_WRITE, obj, offset, len);
81402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	WARN_ON(or->out.bio || or->out.total_bytes);
81562f469b596dd0aadf046a69027087c18db43734eBoaz Harrosh	WARN_ON(0 ==  bio_rw_flagged(bio, BIO_RW));
81602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	or->out.bio = bio;
81762f469b596dd0aadf046a69027087c18db43734eBoaz Harrosh	or->out.total_bytes = len;
81802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
81902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_write);
82002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
8210e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harroshint osd_req_write_kern(struct osd_request *or,
8220e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh	const struct osd_obj_id *obj, u64 offset, void* buff, u64 len)
8230e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh{
824fc2fac5b5f11e2bee3bf37215c8746236f5ea188Boaz Harrosh	struct request_queue *req_q = osd_request_queue(or->osd_dev);
8250e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh	struct bio *bio = bio_map_kern(req_q, buff, len, GFP_KERNEL);
8260e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh
8270e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh	if (IS_ERR(bio))
8280e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh		return PTR_ERR(bio);
8290e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh
83062f469b596dd0aadf046a69027087c18db43734eBoaz Harrosh	bio->bi_rw |= (1 << BIO_RW); /* FIXME: bio_set_dir() */
83162f469b596dd0aadf046a69027087c18db43734eBoaz Harrosh	osd_req_write(or, obj, offset, bio, len);
8320e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh	return 0;
8330e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh}
8340e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz HarroshEXPORT_SYMBOL(osd_req_write_kern);
8350e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh
836ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_append(struct osd_request *,
837ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh	const struct osd_obj_id *, struct bio *data_out); */
838ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_create_write(struct osd_request *,
839ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh	const struct osd_obj_id *, struct bio *data_out, u64 offset); */
840ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_clear(struct osd_request *,
841ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh	const struct osd_obj_id *, u64 offset, u64 len); */
842ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh/*TODO: void osd_req_punch(struct osd_request *,
843ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh	const struct osd_obj_id *, u64 offset, u64 len); V2 */
844ae30c994a4bb70510fdcb9e7223805bb2a8bc9eeBoaz Harrosh
8453e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harroshvoid osd_req_flush_object(struct osd_request *or,
8463e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	const struct osd_obj_id *obj, enum osd_options_flush_scope_values op,
8473e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	/*V2*/ u64 offset, /*V2*/ u64 len)
8483e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh{
849c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	if (unlikely(osd_req_is_ver1(or) && (offset || len))) {
850c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh		OSD_DEBUG("OSD Ver1 flush on specific range ignored\n");
851c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh		offset = 0;
852c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh		len = 0;
853c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	}
854c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh
8553e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	_osd_req_encode_common(or, OSD_ACT_FLUSH, obj, offset, len);
8563e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh	_osd_req_encode_flush(or, op);
8573e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh}
8583e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz HarroshEXPORT_SYMBOL(osd_req_flush_object);
8593e08613037fd4ec0b716a215602c4bdb3d0d9171Boaz Harrosh
86002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_req_read(struct osd_request *or,
86162f469b596dd0aadf046a69027087c18db43734eBoaz Harrosh	const struct osd_obj_id *obj, u64 offset,
86262f469b596dd0aadf046a69027087c18db43734eBoaz Harrosh	struct bio *bio, u64 len)
86302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
86462f469b596dd0aadf046a69027087c18db43734eBoaz Harrosh	_osd_req_encode_common(or, OSD_ACT_READ, obj, offset, len);
86502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	WARN_ON(or->in.bio || or->in.total_bytes);
86662f469b596dd0aadf046a69027087c18db43734eBoaz Harrosh	WARN_ON(1 == bio_rw_flagged(bio, BIO_RW));
86702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	or->in.bio = bio;
86862f469b596dd0aadf046a69027087c18db43734eBoaz Harrosh	or->in.total_bytes = len;
86902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
87002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_req_read);
87102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
8720e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harroshint osd_req_read_kern(struct osd_request *or,
8730e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh	const struct osd_obj_id *obj, u64 offset, void* buff, u64 len)
8740e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh{
875fc2fac5b5f11e2bee3bf37215c8746236f5ea188Boaz Harrosh	struct request_queue *req_q = osd_request_queue(or->osd_dev);
8760e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh	struct bio *bio = bio_map_kern(req_q, buff, len, GFP_KERNEL);
8770e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh
8780e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh	if (IS_ERR(bio))
8790e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh		return PTR_ERR(bio);
8800e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh
88162f469b596dd0aadf046a69027087c18db43734eBoaz Harrosh	osd_req_read(or, obj, offset, bio, len);
8820e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh	return 0;
8830e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh}
8840e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz HarroshEXPORT_SYMBOL(osd_req_read_kern);
8850e35afbc8b054e04a35faa796c72abb3b82bd33bBoaz Harrosh
8864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshvoid osd_req_get_attributes(struct osd_request *or,
8874ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	const struct osd_obj_id *obj)
8884ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{
8894ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	_osd_req_encode_common(or, OSD_ACT_GET_ATTRIBUTES, obj, 0, 0);
8904ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh}
8914ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_get_attributes);
8924ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
8934ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshvoid osd_req_set_attributes(struct osd_request *or,
8944ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	const struct osd_obj_id *obj)
8954ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{
8964ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	_osd_req_encode_common(or, OSD_ACT_SET_ATTRIBUTES, obj, 0, 0);
8974ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh}
8984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_set_attributes);
8994ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
9004ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh/*
9014ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * Attributes List-mode
9024ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh */
9034ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
9044ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshint osd_req_add_set_attr_list(struct osd_request *or,
9054ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	const struct osd_attr *oa, unsigned nelem)
9064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{
9074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	unsigned total_bytes = or->set_attr.total_bytes;
9084ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	void *attr_last;
9094ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	int ret;
9104ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
9114ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (or->attributes_mode &&
9124ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	    or->attributes_mode != OSD_CDB_GET_SET_ATTR_LISTS) {
9134ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		WARN_ON(1);
9144ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		return -EINVAL;
9154ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	}
9164ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	or->attributes_mode = OSD_CDB_GET_SET_ATTR_LISTS;
9174ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
9184ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (!total_bytes) { /* first-time: allocate and put list header */
9194ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		total_bytes = _osd_req_sizeof_alist_header(or);
9204ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		ret = _alloc_set_attr_list(or, oa, nelem, total_bytes);
9214ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		if (ret)
9224ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			return ret;
9234ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		_osd_req_set_alist_type(or, or->set_attr.buff,
9244ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh					OSD_ATTR_LIST_SET_RETRIEVE);
9254ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	}
9264ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	attr_last = or->set_attr.buff + total_bytes;
9274ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
9284ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	for (; nelem; --nelem) {
9294ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		unsigned elem_size = _osd_req_alist_elem_size(or, oa->len);
9304ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
9314ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		total_bytes += elem_size;
9324ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		if (unlikely(or->set_attr.alloc_size < total_bytes)) {
9334ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			or->set_attr.total_bytes = total_bytes - elem_size;
9344ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			ret = _alloc_set_attr_list(or, oa, nelem, total_bytes);
9354ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			if (ret)
9364ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh				return ret;
9374ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			attr_last =
9384ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh				or->set_attr.buff + or->set_attr.total_bytes;
9394ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		}
9404ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
94171f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		_osd_req_alist_elem_encode(or, attr_last, oa);
9424ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
9434ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		attr_last += elem_size;
9444ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		++oa;
9454ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	}
9464ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
9474ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	or->set_attr.total_bytes = total_bytes;
9484ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	return 0;
9494ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh}
9504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_add_set_attr_list);
9514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
9524ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _req_append_segment(struct osd_request *or,
9534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	unsigned padding, struct _osd_req_data_segment *seg,
9544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	struct _osd_req_data_segment *last_seg, struct _osd_io_info *io)
9554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{
9564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	void *pad_buff;
9574ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	int ret;
9584ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
9594ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (padding) {
9604ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		/* check if we can just add it to last buffer */
9614ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		if (last_seg &&
9624ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		    (padding <= last_seg->alloc_size - last_seg->total_bytes))
9634ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			pad_buff = last_seg->buff + last_seg->total_bytes;
9644ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		else
9654ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			pad_buff = io->pad_buff;
9664ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
967bc38bf106c967389a465d926be22c7371abba69dBoaz Harrosh		ret = blk_rq_map_kern(io->req->q, io->req, pad_buff, padding,
9684ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh				       or->alloc_flags);
9694ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		if (ret)
9704ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			return ret;
9714ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		io->total_bytes += padding;
9724ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	}
9734ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
974bc38bf106c967389a465d926be22c7371abba69dBoaz Harrosh	ret = blk_rq_map_kern(io->req->q, io->req, seg->buff, seg->total_bytes,
9754ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			       or->alloc_flags);
9764ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (ret)
9774ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		return ret;
9784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
9794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	io->total_bytes += seg->total_bytes;
9804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	OSD_DEBUG("padding=%d buff=%p total_bytes=%d\n", padding, seg->buff,
9814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		  seg->total_bytes);
9824ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	return 0;
9834ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh}
9844ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
9854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _osd_req_finalize_set_attr_list(struct osd_request *or)
9864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{
9874ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb);
9884ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	unsigned padding;
9894ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	int ret;
9904ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
9914ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (!or->set_attr.total_bytes) {
9924ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		cdbh->attrs_list.set_attr_offset = OSD_OFFSET_UNUSED;
9934ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		return 0;
9944ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	}
9954ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
9964ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	cdbh->attrs_list.set_attr_bytes = cpu_to_be32(or->set_attr.total_bytes);
9974ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	cdbh->attrs_list.set_attr_offset =
9984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		osd_req_encode_offset(or, or->out.total_bytes, &padding);
9994ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
10004ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	ret = _req_append_segment(or, padding, &or->set_attr,
10014ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh				  or->out.last_seg, &or->out);
10024ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (ret)
10034ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		return ret;
10044ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
10054ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	or->out.last_seg = &or->set_attr;
10064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	return 0;
10074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh}
10084ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
10094ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshint osd_req_add_get_attr_list(struct osd_request *or,
10104ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	const struct osd_attr *oa, unsigned nelem)
10114ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{
10124ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	unsigned total_bytes = or->enc_get_attr.total_bytes;
10134ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	void *attr_last;
10144ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	int ret;
10154ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
10164ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (or->attributes_mode &&
10174ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	    or->attributes_mode != OSD_CDB_GET_SET_ATTR_LISTS) {
10184ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		WARN_ON(1);
10194ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		return -EINVAL;
10204ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	}
10214ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	or->attributes_mode = OSD_CDB_GET_SET_ATTR_LISTS;
10224ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
10234ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	/* first time calc data-in list header size */
10244ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (!or->get_attr.total_bytes)
10254ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		or->get_attr.total_bytes = _osd_req_sizeof_alist_header(or);
10264ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
10274ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	/* calc data-out info */
10284ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (!total_bytes) { /* first-time: allocate and put list header */
10294ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		unsigned max_bytes;
10304ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
10314ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		total_bytes = _osd_req_sizeof_alist_header(or);
10324ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		max_bytes = total_bytes +
10334ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			nelem * sizeof(struct osd_attributes_list_attrid);
10344ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		ret = _alloc_get_attr_desc(or, max_bytes);
10354ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		if (ret)
10364ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			return ret;
10374ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
10384ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		_osd_req_set_alist_type(or, or->enc_get_attr.buff,
10394ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh					OSD_ATTR_LIST_GET);
10404ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	}
10414ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	attr_last = or->enc_get_attr.buff + total_bytes;
10424ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
10434ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	for (; nelem; --nelem) {
10444ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		struct osd_attributes_list_attrid *attrid;
10454ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		const unsigned cur_size = sizeof(*attrid);
10464ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
10474ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		total_bytes += cur_size;
10484ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		if (unlikely(or->enc_get_attr.alloc_size < total_bytes)) {
10494ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			or->enc_get_attr.total_bytes = total_bytes - cur_size;
10504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			ret = _alloc_get_attr_desc(or,
10514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh					total_bytes + nelem * sizeof(*attrid));
10524ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			if (ret)
10534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh				return ret;
10544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			attr_last = or->enc_get_attr.buff +
10554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh				or->enc_get_attr.total_bytes;
10564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		}
10574ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
10584ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		attrid = attr_last;
10594ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		attrid->attr_page = cpu_to_be32(oa->attr_page);
10604ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		attrid->attr_id = cpu_to_be32(oa->attr_id);
10614ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
10624ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		attr_last += cur_size;
10634ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
10644ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		/* calc data-in size */
10654ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		or->get_attr.total_bytes +=
10664ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			_osd_req_alist_elem_size(or, oa->len);
10674ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		++oa;
10684ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	}
10694ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
10704ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	or->enc_get_attr.total_bytes = total_bytes;
10714ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
10724ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	OSD_DEBUG(
10734ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	       "get_attr.total_bytes=%u(%u) enc_get_attr.total_bytes=%u(%Zu)\n",
10744ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	       or->get_attr.total_bytes,
10754ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	       or->get_attr.total_bytes - _osd_req_sizeof_alist_header(or),
10764ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	       or->enc_get_attr.total_bytes,
10774ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	       (or->enc_get_attr.total_bytes - _osd_req_sizeof_alist_header(or))
10784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			/ sizeof(struct osd_attributes_list_attrid));
10794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
10804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	return 0;
10814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh}
10824ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_add_get_attr_list);
10834ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
10844ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _osd_req_finalize_get_attr_list(struct osd_request *or)
10854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{
10864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb);
10874ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	unsigned out_padding;
10884ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	unsigned in_padding;
10894ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	int ret;
10904ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
10914ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (!or->enc_get_attr.total_bytes) {
10924ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		cdbh->attrs_list.get_attr_desc_offset = OSD_OFFSET_UNUSED;
10934ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		cdbh->attrs_list.get_attr_offset = OSD_OFFSET_UNUSED;
10944ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		return 0;
10954ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	}
10964ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
10974ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	ret = _alloc_get_attr_list(or);
10984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (ret)
10994ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		return ret;
11004ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
11014ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	/* The out-going buffer info update */
11024ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	OSD_DEBUG("out-going\n");
11034ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	cdbh->attrs_list.get_attr_desc_bytes =
11044ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		cpu_to_be32(or->enc_get_attr.total_bytes);
11054ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
11064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	cdbh->attrs_list.get_attr_desc_offset =
11074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		osd_req_encode_offset(or, or->out.total_bytes, &out_padding);
11084ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
11094ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	ret = _req_append_segment(or, out_padding, &or->enc_get_attr,
11104ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh				  or->out.last_seg, &or->out);
11114ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (ret)
11124ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		return ret;
11134ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	or->out.last_seg = &or->enc_get_attr;
11144ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
11154ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	/* The incoming buffer info update */
11164ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	OSD_DEBUG("in-coming\n");
11174ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	cdbh->attrs_list.get_attr_alloc_length =
11184ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		cpu_to_be32(or->get_attr.total_bytes);
11194ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
11204ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	cdbh->attrs_list.get_attr_offset =
11214ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		osd_req_encode_offset(or, or->in.total_bytes, &in_padding);
11224ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
11234ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	ret = _req_append_segment(or, in_padding, &or->get_attr, NULL,
11244ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh				  &or->in);
11254ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (ret)
11264ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		return ret;
11274ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	or->in.last_seg = &or->get_attr;
11284ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
11294ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	return 0;
11304ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh}
11314ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
11324ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshint osd_req_decode_get_attr_list(struct osd_request *or,
11334ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	struct osd_attr *oa, int *nelem, void **iterator)
11344ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{
11354ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	unsigned cur_bytes, returned_bytes;
11364ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	int n;
11374ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	const unsigned sizeof_attr_list = _osd_req_sizeof_alist_header(or);
11384ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	void *cur_p;
11394ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
11404ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (!_osd_req_is_alist_type(or, or->get_attr.buff,
11414ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh				    OSD_ATTR_LIST_SET_RETRIEVE)) {
11424ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		oa->attr_page = 0;
11434ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		oa->attr_id = 0;
11444ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		oa->val_ptr = NULL;
11454ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		oa->len = 0;
11464ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		*iterator = NULL;
11474ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		return 0;
11484ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	}
11494ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
11504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (*iterator) {
11514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		BUG_ON((*iterator < or->get_attr.buff) ||
11524ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		     (or->get_attr.buff + or->get_attr.alloc_size < *iterator));
11534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		cur_p = *iterator;
11544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		cur_bytes = (*iterator - or->get_attr.buff) - sizeof_attr_list;
11554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		returned_bytes = or->get_attr.total_bytes;
11564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	} else { /* first time decode the list header */
11574ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		cur_bytes = sizeof_attr_list;
11584ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		returned_bytes = _osd_req_alist_size(or, or->get_attr.buff) +
11594ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh					sizeof_attr_list;
11604ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
11614ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		cur_p = or->get_attr.buff + sizeof_attr_list;
11624ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
11634ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		if (returned_bytes > or->get_attr.alloc_size) {
11644ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			OSD_DEBUG("target report: space was not big enough! "
11654ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh				  "Allocate=%u Needed=%u\n",
11664ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh				  or->get_attr.alloc_size,
11674ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh				  returned_bytes + sizeof_attr_list);
11684ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
11694ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			returned_bytes =
11704ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh				or->get_attr.alloc_size - sizeof_attr_list;
11714ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		}
11724ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		or->get_attr.total_bytes = returned_bytes;
11734ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	}
11744ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
11754ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	for (n = 0; (n < *nelem) && (cur_bytes < returned_bytes); ++n) {
117671f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		int inc = _osd_req_alist_elem_decode(or, cur_p, oa,
117771f32e31e5638df37904697e2d04182935add85dBoaz Harrosh						 returned_bytes - cur_bytes);
11784ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
117971f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		if (inc < 0) {
11804ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			OSD_ERR("BAD FOOD from target. list not valid!"
11814ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh				"c=%d r=%d n=%d\n",
11824ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh				cur_bytes, returned_bytes, n);
11834ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			oa->val_ptr = NULL;
1184eff21490c91f981126f0ead3c081dde4f425d387Boaz Harrosh			cur_bytes = returned_bytes; /* break the caller loop */
11854ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			break;
11864ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		}
11874ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
118871f32e31e5638df37904697e2d04182935add85dBoaz Harrosh		cur_bytes += inc;
11894ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		cur_p += inc;
11904ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		++oa;
11914ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	}
11924ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
11934ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	*iterator = (returned_bytes - cur_bytes) ? cur_p : NULL;
11944ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	*nelem = n;
11954ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	return returned_bytes - cur_bytes;
11964ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh}
11974ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_decode_get_attr_list);
11984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
11994ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh/*
12004ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * Attributes Page-mode
12014ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh */
12024ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
12034ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshint osd_req_add_get_attr_page(struct osd_request *or,
12044ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	u32 page_id, void *attar_page, unsigned max_page_len,
12054ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	const struct osd_attr *set_one_attr)
12064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{
12074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb);
12084ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
12094ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (or->attributes_mode &&
12104ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	    or->attributes_mode != OSD_CDB_GET_ATTR_PAGE_SET_ONE) {
12114ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		WARN_ON(1);
12124ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		return -EINVAL;
12134ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	}
12144ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	or->attributes_mode = OSD_CDB_GET_ATTR_PAGE_SET_ONE;
12154ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
12164ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	or->get_attr.buff = attar_page;
12174ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	or->get_attr.total_bytes = max_page_len;
12184ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
12194ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	or->set_attr.buff = set_one_attr->val_ptr;
12204ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	or->set_attr.total_bytes = set_one_attr->len;
12214ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
12224ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	cdbh->attrs_page.get_attr_page = cpu_to_be32(page_id);
12234ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	cdbh->attrs_page.get_attr_alloc_length = cpu_to_be32(max_page_len);
12244ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	/* ocdb->attrs_page.get_attr_offset; */
12254ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
12264ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	cdbh->attrs_page.set_attr_page = cpu_to_be32(set_one_attr->attr_page);
12274ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	cdbh->attrs_page.set_attr_id = cpu_to_be32(set_one_attr->attr_id);
12284ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	cdbh->attrs_page.set_attr_length = cpu_to_be32(set_one_attr->len);
12294ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	/* ocdb->attrs_page.set_attr_offset; */
12304ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	return 0;
12314ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh}
12324ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz HarroshEXPORT_SYMBOL(osd_req_add_get_attr_page);
12334ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
12344ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshstatic int _osd_req_finalize_attr_page(struct osd_request *or)
12354ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{
12364ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb);
12374ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	unsigned in_padding, out_padding;
12384ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	int ret;
12394ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
12404ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	/* returned page */
12414ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	cdbh->attrs_page.get_attr_offset =
12424ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		osd_req_encode_offset(or, or->in.total_bytes, &in_padding);
12434ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
12444ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	ret = _req_append_segment(or, in_padding, &or->get_attr, NULL,
12454ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh				  &or->in);
12464ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (ret)
12474ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		return ret;
12484ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
12494ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	/* set one value */
12504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	cdbh->attrs_page.set_attr_offset =
12514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		osd_req_encode_offset(or, or->out.total_bytes, &out_padding);
12524ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
12534ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	ret = _req_append_segment(or, out_padding, &or->enc_get_attr, NULL,
12544ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh				  &or->out);
12554ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	return ret;
12564ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh}
12574ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
1258f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harroshstatic inline void osd_sec_parms_set_out_offset(bool is_v1,
1259f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh	struct osd_security_parameters *sec_parms, osd_cdb_offset offset)
1260f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh{
1261f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh	if (is_v1)
1262f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh		sec_parms->v1.data_out_integrity_check_offset = offset;
1263f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh	else
1264f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh		sec_parms->v2.data_out_integrity_check_offset = offset;
1265f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh}
1266f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh
1267f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harroshstatic inline void osd_sec_parms_set_in_offset(bool is_v1,
1268f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh	struct osd_security_parameters *sec_parms, osd_cdb_offset offset)
1269f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh{
1270f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh	if (is_v1)
1271f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh		sec_parms->v1.data_in_integrity_check_offset = offset;
1272f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh	else
1273f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh		sec_parms->v2.data_in_integrity_check_offset = offset;
1274f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh}
1275f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh
1276345c435dbb0b77b00ffe73801102533e24c647afBoaz Harroshstatic int _osd_req_finalize_data_integrity(struct osd_request *or,
1277546881aea9787ed5c626ac99ab80158ea9ae0515Boaz Harrosh	bool has_in, bool has_out, u64 out_data_bytes, const u8 *cap_key)
1278345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh{
1279345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh	struct osd_security_parameters *sec_parms = _osd_req_sec_params(or);
1280345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh	int ret;
1281345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh
1282345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh	if (!osd_is_sec_alldata(sec_parms))
1283345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh		return 0;
1284345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh
1285345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh	if (has_out) {
1286345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh		struct _osd_req_data_segment seg = {
1287345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh			.buff = &or->out_data_integ,
1288345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh			.total_bytes = sizeof(or->out_data_integ),
1289345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh		};
1290345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh		unsigned pad;
1291345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh
1292546881aea9787ed5c626ac99ab80158ea9ae0515Boaz Harrosh		or->out_data_integ.data_bytes = cpu_to_be64(out_data_bytes);
1293345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh		or->out_data_integ.set_attributes_bytes = cpu_to_be64(
1294345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh			or->set_attr.total_bytes);
1295345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh		or->out_data_integ.get_attributes_bytes = cpu_to_be64(
1296345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh			or->enc_get_attr.total_bytes);
1297345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh
1298f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh		osd_sec_parms_set_out_offset(osd_req_is_ver1(or), sec_parms,
1299f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh			osd_req_encode_offset(or, or->out.total_bytes, &pad));
1300345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh
1301345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh		ret = _req_append_segment(or, pad, &seg, or->out.last_seg,
1302345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh					  &or->out);
1303345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh		if (ret)
1304345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh			return ret;
1305345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh		or->out.last_seg = NULL;
1306345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh
1307345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh		/* they are now all chained to request sign them all together */
1308345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh		osd_sec_sign_data(&or->out_data_integ, or->out.req->bio,
1309345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh				  cap_key);
1310345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh	}
1311345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh
1312345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh	if (has_in) {
1313345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh		struct _osd_req_data_segment seg = {
1314345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh			.buff = &or->in_data_integ,
1315345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh			.total_bytes = sizeof(or->in_data_integ),
1316345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh		};
1317345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh		unsigned pad;
1318345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh
1319f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh		osd_sec_parms_set_in_offset(osd_req_is_ver1(or), sec_parms,
1320f8d3a644bec74fd55dbfb11f95af7bf98fa963dcBoaz Harrosh			osd_req_encode_offset(or, or->in.total_bytes, &pad));
1321345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh
1322345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh		ret = _req_append_segment(or, pad, &seg, or->in.last_seg,
1323345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh					  &or->in);
1324345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh		if (ret)
1325345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh			return ret;
1326345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh
1327345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh		or->in.last_seg = NULL;
1328345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh	}
1329345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh
1330345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh	return 0;
1331345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh}
1332345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh
133302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/*
133402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * osd_finalize_request and helpers
133502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */
1336c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harroshstatic struct request *_make_request(struct request_queue *q, bool has_write,
1337c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh			      struct _osd_io_info *oii, gfp_t flags)
1338c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh{
1339c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh	if (oii->bio)
1340c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh		return blk_make_request(q, oii->bio, flags);
1341c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh	else {
1342c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh		struct request *req;
1343c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh
1344c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh		req = blk_get_request(q, has_write ? WRITE : READ, flags);
1345c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh		if (unlikely(!req))
1346c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh			return ERR_PTR(-ENOMEM);
1347c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh
1348c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh		return req;
1349c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh	}
1350c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh}
135102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
135202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshstatic int _init_blk_request(struct osd_request *or,
135302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	bool has_in, bool has_out)
135402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
135502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	gfp_t flags = or->alloc_flags;
135602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	struct scsi_device *scsi_device = or->osd_dev->scsi_device;
135702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	struct request_queue *q = scsi_device->request_queue;
135802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	struct request *req;
1359c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh	int ret;
136002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
1361c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh	req = _make_request(q, has_out, has_out ? &or->out : &or->in, flags);
1362c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh	if (IS_ERR(req)) {
1363c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh		ret = PTR_ERR(req);
136402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		goto out;
1365c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh	}
136602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
136702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	or->request = req;
136802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	req->cmd_type = REQ_TYPE_BLOCK_PC;
136903306793e686fd895ab8fa095bb9ec33658ea53aBoaz Harrosh	req->cmd_flags |= REQ_QUIET;
137003306793e686fd895ab8fa095bb9ec33658ea53aBoaz Harrosh
137102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	req->timeout = or->timeout;
137202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	req->retries = or->retries;
137302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	req->sense = or->sense;
137402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	req->sense_len = 0;
137502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
137602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	if (has_out) {
137702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		or->out.req = req;
137802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		if (has_in) {
137902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh			/* allocate bidi request */
1380c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh			req = _make_request(q, false, &or->in, flags);
1381c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh			if (IS_ERR(req)) {
138202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh				OSD_DEBUG("blk_get_request for bidi failed\n");
1383c29b70f6ee4f2fa3ef07f55bc9082945861e5391Boaz Harrosh				ret = PTR_ERR(req);
138402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh				goto out;
138502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh			}
138602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh			req->cmd_type = REQ_TYPE_BLOCK_PC;
138702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh			or->in.req = or->request->next_rq = req;
138802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		}
138902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	} else if (has_in)
139002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		or->in.req = req;
139102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
139202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	ret = 0;
139302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshout:
139402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	OSD_DEBUG("or=%p has_in=%d has_out=%d => %d, %p\n",
139502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh			or, has_in, has_out, ret, or->request);
139602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	return ret;
139702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
139802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
139902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshint osd_finalize_request(struct osd_request *or,
140002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	u8 options, const void *cap, const u8 *cap_key)
140102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
140202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	struct osd_cdb_head *cdbh = osd_cdb_head(&or->cdb);
140302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	bool has_in, has_out;
1404546881aea9787ed5c626ac99ab80158ea9ae0515Boaz Harrosh	u64 out_data_bytes = or->out.total_bytes;
140502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	int ret;
140602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
140702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	if (options & OSD_REQ_FUA)
140802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		cdbh->options |= OSD_CDB_FUA;
140902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
141002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	if (options & OSD_REQ_DPO)
141102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		cdbh->options |= OSD_CDB_DPO;
141202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
141302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	if (options & OSD_REQ_BYPASS_TIMESTAMPS)
141402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		cdbh->timestamp_control = OSD_CDB_BYPASS_TIMESTAMPS;
141502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
141602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	osd_set_caps(&or->cdb, cap);
141702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
141802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	has_in = or->in.bio || or->get_attr.total_bytes;
141902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	has_out = or->out.bio || or->set_attr.total_bytes ||
142002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		or->enc_get_attr.total_bytes;
142102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
142202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	ret = _init_blk_request(or, has_in, has_out);
142302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	if (ret) {
142402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		OSD_DEBUG("_init_blk_request failed\n");
142502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		return ret;
142602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	}
142702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
14284ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	or->out.pad_buff = sg_out_pad_buffer;
14294ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	or->in.pad_buff = sg_in_pad_buffer;
14304ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
143102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	if (!or->attributes_mode)
143202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		or->attributes_mode = OSD_CDB_GET_SET_ATTR_LISTS;
143302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	cdbh->command_specific_options |= or->attributes_mode;
14344ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (or->attributes_mode == OSD_CDB_GET_ATTR_PAGE_SET_ONE) {
14354ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		ret = _osd_req_finalize_attr_page(or);
14364ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	} else {
14374ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		/* TODO: I think that for the GET_ATTR command these 2 should
14384ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		 * be reversed to keep them in execution order (for embeded
14394ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		 * targets with low memory footprint)
14404ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		 */
14414ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		ret = _osd_req_finalize_set_attr_list(or);
14424ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		if (ret) {
14434ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			OSD_DEBUG("_osd_req_finalize_set_attr_list failed\n");
14444ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			return ret;
14454ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		}
14464ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
14474ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		ret = _osd_req_finalize_get_attr_list(or);
14484ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		if (ret) {
14494ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			OSD_DEBUG("_osd_req_finalize_get_attr_list failed\n");
14504ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			return ret;
14514ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		}
14524ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	}
145302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
1454546881aea9787ed5c626ac99ab80158ea9ae0515Boaz Harrosh	ret = _osd_req_finalize_data_integrity(or, has_in, has_out,
1455546881aea9787ed5c626ac99ab80158ea9ae0515Boaz Harrosh					       out_data_bytes, cap_key);
1456345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh	if (ret)
1457345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh		return ret;
1458345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh
1459345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh	osd_sec_sign_cdb(&or->cdb, cap_key);
1460345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh
146102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	or->request->cmd = or->cdb.buff;
146202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	or->request->cmd_len = _osd_req_cdb_len(or);
146302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
146402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	return 0;
146502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
146602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_finalize_request);
146702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
1468aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harroshstatic bool _is_osd_security_code(int code)
1469aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh{
1470aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh	return	(code == osd_security_audit_value_frozen) ||
1471aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		(code == osd_security_working_key_frozen) ||
1472aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		(code == osd_nonce_not_unique) ||
1473aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		(code == osd_nonce_timestamp_out_of_range) ||
1474aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		(code == osd_invalid_dataout_buffer_integrity_check_value);
1475aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh}
1476aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh
147798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh#define OSD_SENSE_PRINT1(fmt, a...) \
147898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	do { \
147998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		if (__cur_sense_need_output) \
148098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			OSD_ERR(fmt, ##a); \
148198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	} while (0)
148298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh
148398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh#define OSD_SENSE_PRINT2(fmt, a...) OSD_SENSE_PRINT1("    " fmt, ##a)
148498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh
148598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harroshint osd_req_decode_sense_full(struct osd_request *or,
148698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	struct osd_sense_info *osi, bool silent,
148798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	struct osd_obj_id *bad_obj_list __unused, int max_obj __unused,
148898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	struct osd_attr *bad_attr_list, int max_attr)
148998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh{
149098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	int sense_len, original_sense_len;
149198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	struct osd_sense_info local_osi;
149298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	struct scsi_sense_descriptor_based *ssdb;
149398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	void *cur_descriptor;
149498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh#if (CONFIG_SCSI_OSD_DPRINT_SENSE == 0)
149598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	const bool __cur_sense_need_output = false;
149698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh#else
149798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	bool __cur_sense_need_output = !silent;
149898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh#endif
1499aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh	int ret;
150098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh
15015d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	if (likely(!or->req_errors))
150298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		return 0;
1503aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh
1504aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh	osi = osi ? : &local_osi;
1505aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh	memset(osi, 0, sizeof(*osi));
150698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh
15075d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	ssdb = (typeof(ssdb))or->sense;
15085d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	sense_len = or->sense_len;
150998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	if ((sense_len < (int)sizeof(*ssdb) || !ssdb->sense_key)) {
151098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		OSD_ERR("Block-layer returned error(0x%x) but "
151198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			"sense_len(%u) || key(%d) is empty\n",
15125d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh			or->req_errors, sense_len, ssdb->sense_key);
1513aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		goto analyze;
151498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	}
151598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh
151698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	if ((ssdb->response_code != 0x72) && (ssdb->response_code != 0x73)) {
151798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		OSD_ERR("Unrecognized scsi sense: rcode=%x length=%d\n",
151898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			ssdb->response_code, sense_len);
1519aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		goto analyze;
152098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	}
152198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh
152298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	osi->key = ssdb->sense_key;
152398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	osi->additional_code = be16_to_cpu(ssdb->additional_sense_code);
152498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	original_sense_len = ssdb->additional_sense_length + 8;
152598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh
152698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh#if (CONFIG_SCSI_OSD_DPRINT_SENSE == 1)
152798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	if (__cur_sense_need_output)
152898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		__cur_sense_need_output = (osi->key > scsi_sk_recovered_error);
152998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh#endif
153098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	OSD_SENSE_PRINT1("Main Sense information key=0x%x length(%d, %d) "
1531aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh			"additional_code=0x%x async_error=%d errors=0x%x\n",
153298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			osi->key, original_sense_len, sense_len,
1533aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh			osi->additional_code, or->async_error,
15345d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh			or->req_errors);
153598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh
153698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	if (original_sense_len < sense_len)
153798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		sense_len = original_sense_len;
153898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh
153998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	cur_descriptor = ssdb->ssd;
154098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	sense_len -= sizeof(*ssdb);
154198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	while (sense_len > 0) {
154298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		struct scsi_sense_descriptor *ssd = cur_descriptor;
154398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		int cur_len = ssd->additional_length + 2;
154498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh
154598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		sense_len -= cur_len;
154698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh
154798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		if (sense_len < 0)
154898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			break; /* sense was truncated */
154998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh
155098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		switch (ssd->descriptor_type) {
155198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		case scsi_sense_information:
155298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		case scsi_sense_command_specific_information:
155398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		{
155498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			struct scsi_sense_command_specific_data_descriptor
155598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				*sscd = cur_descriptor;
155698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh
155798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			osi->command_info =
155898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				get_unaligned_be64(&sscd->information) ;
155998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			OSD_SENSE_PRINT2(
156098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				"command_specific_information 0x%llx \n",
156198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				_LLU(osi->command_info));
156298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			break;
156398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		}
156498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		case scsi_sense_key_specific:
156598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		{
156698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			struct scsi_sense_key_specific_data_descriptor
156798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				*ssks = cur_descriptor;
156898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh
156998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			osi->sense_info = get_unaligned_be16(&ssks->value);
157098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			OSD_SENSE_PRINT2(
157198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				"sense_key_specific_information %u"
157298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				"sksv_cd_bpv_bp (0x%x)\n",
157398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				osi->sense_info, ssks->sksv_cd_bpv_bp);
157498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			break;
157598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		}
157698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		case osd_sense_object_identification:
157798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		{ /*FIXME: Keep first not last, Store in array*/
157898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			struct osd_sense_identification_data_descriptor
157998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				*osidd = cur_descriptor;
158098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh
158198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			osi->not_initiated_command_functions =
158298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				le32_to_cpu(osidd->not_initiated_functions);
158398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			osi->completed_command_functions =
158498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				le32_to_cpu(osidd->completed_functions);
158598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			osi->obj.partition = be64_to_cpu(osidd->partition_id);
158698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			osi->obj.id = be64_to_cpu(osidd->object_id);
158798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			OSD_SENSE_PRINT2(
158898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				"object_identification pid=0x%llx oid=0x%llx\n",
158998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				_LLU(osi->obj.partition), _LLU(osi->obj.id));
159098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			OSD_SENSE_PRINT2(
159198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				"not_initiated_bits(%x) "
159298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				"completed_command_bits(%x)\n",
159398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				osi->not_initiated_command_functions,
159498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				osi->completed_command_functions);
159598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			break;
159698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		}
159798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		case osd_sense_response_integrity_check:
159898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		{
159998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			struct osd_sense_response_integrity_check_descriptor
160098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				*osricd = cur_descriptor;
160198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			const unsigned len =
160298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh					  sizeof(osricd->integrity_check_value);
160398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			char key_dump[len*4 + 2]; /* 2nibbles+space+ASCII */
160498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh
160598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			hex_dump_to_buffer(osricd->integrity_check_value, len,
160698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				       32, 1, key_dump, sizeof(key_dump), true);
160798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			OSD_SENSE_PRINT2("response_integrity [%s]\n", key_dump);
160898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		}
160998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		case osd_sense_attribute_identification:
161098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		{
161198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			struct osd_sense_attributes_data_descriptor
161298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				*osadd = cur_descriptor;
161371ecb74b15377a6c0e0e6ea95d4b549580fb4d48Boaz Harrosh			unsigned len = min(cur_len, sense_len);
161498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			struct osd_sense_attr *pattr = osadd->sense_attrs;
161598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh
161671ecb74b15377a6c0e0e6ea95d4b549580fb4d48Boaz Harrosh			while (len >= sizeof(*pattr)) {
161798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				u32 attr_page = be32_to_cpu(pattr->attr_page);
161898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				u32 attr_id = be32_to_cpu(pattr->attr_id);
161998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh
162071ecb74b15377a6c0e0e6ea95d4b549580fb4d48Boaz Harrosh				if (!osi->attr.attr_page) {
162198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh					osi->attr.attr_page = attr_page;
162298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh					osi->attr.attr_id = attr_id;
162398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				}
162498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh
162598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				if (bad_attr_list && max_attr) {
162698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh					bad_attr_list->attr_page = attr_page;
162798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh					bad_attr_list->attr_id = attr_id;
162898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh					bad_attr_list++;
162998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh					max_attr--;
163098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				}
163171ecb74b15377a6c0e0e6ea95d4b549580fb4d48Boaz Harrosh
163271ecb74b15377a6c0e0e6ea95d4b549580fb4d48Boaz Harrosh				len -= sizeof(*pattr);
163398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				OSD_SENSE_PRINT2(
163498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh					"osd_sense_attribute_identification"
163598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh					"attr_page=0x%x attr_id=0x%x\n",
163698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh					attr_page, attr_id);
163798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			}
163898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		}
163998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		/*These are not legal for OSD*/
164098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		case scsi_sense_field_replaceable_unit:
164198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			OSD_SENSE_PRINT2("scsi_sense_field_replaceable_unit\n");
164298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			break;
164398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		case scsi_sense_stream_commands:
164498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			OSD_SENSE_PRINT2("scsi_sense_stream_commands\n");
164598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			break;
164698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		case scsi_sense_block_commands:
164798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			OSD_SENSE_PRINT2("scsi_sense_block_commands\n");
164898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			break;
164998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		case scsi_sense_ata_return:
165098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			OSD_SENSE_PRINT2("scsi_sense_ata_return\n");
165198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			break;
165298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		default:
165398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			if (ssd->descriptor_type <= scsi_sense_Reserved_last)
165498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				OSD_SENSE_PRINT2(
165598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh					"scsi_sense Reserved descriptor (0x%x)",
165698f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh					ssd->descriptor_type);
165798f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh			else
165898f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh				OSD_SENSE_PRINT2(
165998f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh					"scsi_sense Vendor descriptor (0x%x)",
166098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh					ssd->descriptor_type);
166198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		}
166298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh
166398f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh		cur_descriptor += cur_len;
166498f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh	}
166598f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh
1666aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harroshanalyze:
1667aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh	if (!osi->key) {
1668aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		/* scsi sense is Empty, the request was never issued to target
1669aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		 * linux return code might tell us what happened.
1670aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		 */
1671aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		if (or->async_error == -ENOMEM)
1672aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh			osi->osd_err_pri = OSD_ERR_PRI_RESOURCE;
1673aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		else
1674aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh			osi->osd_err_pri = OSD_ERR_PRI_UNREACHABLE;
1675aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		ret = or->async_error;
1676aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh	} else if (osi->key <= scsi_sk_recovered_error) {
1677aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		osi->osd_err_pri = 0;
1678aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		ret = 0;
1679aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh	} else if (osi->additional_code == scsi_invalid_field_in_cdb) {
1680aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		if (osi->cdb_field_offset == OSD_CFO_STARTING_BYTE) {
1681aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh			osi->osd_err_pri = OSD_ERR_PRI_CLEAR_PAGES;
1682aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh			ret = -EFAULT; /* caller should recover from this */
1683aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		} else if (osi->cdb_field_offset == OSD_CFO_OBJECT_ID) {
1684aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh			osi->osd_err_pri = OSD_ERR_PRI_NOT_FOUND;
1685aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh			ret = -ENOENT;
1686aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		} else if (osi->cdb_field_offset == OSD_CFO_PERMISSIONS) {
1687aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh			osi->osd_err_pri = OSD_ERR_PRI_NO_ACCESS;
1688aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh			ret = -EACCES;
1689aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		} else {
1690aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh			osi->osd_err_pri = OSD_ERR_PRI_BAD_CRED;
1691aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh			ret = -EINVAL;
1692aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		}
1693aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh	} else if (osi->additional_code == osd_quota_error) {
1694aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		osi->osd_err_pri = OSD_ERR_PRI_NO_SPACE;
1695aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		ret = -ENOSPC;
1696aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh	} else if (_is_osd_security_code(osi->additional_code)) {
1697aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		osi->osd_err_pri = OSD_ERR_PRI_BAD_CRED;
1698aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		ret = -EINVAL;
1699aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh	} else {
1700aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		osi->osd_err_pri = OSD_ERR_PRI_EIO;
1701aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh		ret = -EIO;
1702aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh	}
1703aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh
17045d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	if (!or->out.residual)
17055d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh		or->out.residual = or->out.total_bytes;
17065d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh	if (!or->in.residual)
17075d0961fd1f25e117f907f3af3aaa870637049252Boaz Harrosh		or->in.residual = or->in.total_bytes;
1708aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh
1709aa9fffbe2c4db4557248c5c626a85bf3c7867044Boaz Harrosh	return ret;
171098f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh}
171198f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz HarroshEXPORT_SYMBOL(osd_req_decode_sense_full);
171298f3aea2bd4b4f9cd7a6a6479ed9410787f756fdBoaz Harrosh
171302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/*
171402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * Implementation of osd_sec.h API
171502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh * TODO: Move to a separate osd_sec.c file at a later stage.
171602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh */
171702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
171802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshenum { OSD_SEC_CAP_V1_ALL_CAPS =
171902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	OSD_SEC_CAP_APPEND | OSD_SEC_CAP_OBJ_MGMT | OSD_SEC_CAP_REMOVE   |
172002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	OSD_SEC_CAP_CREATE | OSD_SEC_CAP_SET_ATTR | OSD_SEC_CAP_GET_ATTR |
172102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	OSD_SEC_CAP_WRITE  | OSD_SEC_CAP_READ     | OSD_SEC_CAP_POL_SEC  |
172202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	OSD_SEC_CAP_GLOBAL | OSD_SEC_CAP_DEV_MGMT
172302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh};
172402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
1725c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harroshenum { OSD_SEC_CAP_V2_ALL_CAPS =
1726c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	OSD_SEC_CAP_V1_ALL_CAPS | OSD_SEC_CAP_QUERY | OSD_SEC_CAP_M_OBJECT
1727c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh};
1728c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh
172902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_sec_init_nosec_doall_caps(void *caps,
173002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	const struct osd_obj_id *obj, bool is_collection, const bool is_v1)
173102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
173202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	struct osd_capability *cap = caps;
173302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	u8 type;
173402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	u8 descriptor_type;
173502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
173602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	if (likely(obj->id)) {
173702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		if (unlikely(is_collection)) {
173802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh			type = OSD_SEC_OBJ_COLLECTION;
173902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh			descriptor_type = is_v1 ? OSD_SEC_OBJ_DESC_OBJ :
174002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh						  OSD_SEC_OBJ_DESC_COL;
174102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		} else {
174202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh			type = OSD_SEC_OBJ_USER;
174302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh			descriptor_type = OSD_SEC_OBJ_DESC_OBJ;
174402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		}
174502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		WARN_ON(!obj->partition);
174602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	} else {
174702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		type = obj->partition ? OSD_SEC_OBJ_PARTITION :
174802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh					OSD_SEC_OBJ_ROOT;
174902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh		descriptor_type = OSD_SEC_OBJ_DESC_PAR;
175002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	}
175102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
175202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	memset(cap, 0, sizeof(*cap));
175302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
175402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	cap->h.format = OSD_SEC_CAP_FORMAT_VER1;
175502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	cap->h.integrity_algorithm__key_version = 0; /* MAKE_BYTE(0, 0); */
175602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	cap->h.security_method = OSD_SEC_NOSEC;
175702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh/*	cap->expiration_time;
175802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	cap->AUDIT[30-10];
175902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	cap->discriminator[42-30];
176002941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	cap->object_created_time; */
176102941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	cap->h.object_type = type;
176202941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	osd_sec_set_caps(&cap->h, OSD_SEC_CAP_V1_ALL_CAPS);
176302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	cap->h.object_descriptor_type = descriptor_type;
176402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	cap->od.obj_desc.policy_access_tag = 0;
176502941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	cap->od.obj_desc.allowed_partition_id = cpu_to_be64(obj->partition);
176602941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh	cap->od.obj_desc.allowed_object_id = cpu_to_be64(obj->id);
176702941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
176802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz HarroshEXPORT_SYMBOL(osd_sec_init_nosec_doall_caps);
176902941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh
1770c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh/* FIXME: Extract version from caps pointer.
1771c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh *        Also Pete's target only supports caps from OSDv1 for now
1772c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh */
177302941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harroshvoid osd_set_caps(struct osd_cdb *cdb, const void *caps)
177402941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh{
1775c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	bool is_ver1 = true;
1776c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	/* NOTE: They start at same address */
1777c6572c983726fe3f3bb5f07e9afe3a9b8e402d1bBoaz Harrosh	memcpy(&cdb->v1.caps, caps, is_ver1 ? OSDv1_CAP_LEN : OSD_CAP_LEN);
177802941a530ef736210b4cf8b24dd34c238d5d5a40Boaz Harrosh}
17794ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
1780345c435dbb0b77b00ffe73801102533e24c647afBoaz Harroshbool osd_is_sec_alldata(struct osd_security_parameters *sec_parms __unused)
1781345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh{
1782345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh	return false;
1783345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh}
1784345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh
1785345c435dbb0b77b00ffe73801102533e24c647afBoaz Harroshvoid osd_sec_sign_cdb(struct osd_cdb *ocdb __unused, const u8 *cap_key __unused)
1786345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh{
1787345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh}
1788345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh
1789345c435dbb0b77b00ffe73801102533e24c647afBoaz Harroshvoid osd_sec_sign_data(void *data_integ __unused,
1790345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh		       struct bio *bio __unused, const u8 *cap_key __unused)
1791345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh{
1792345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh}
1793345c435dbb0b77b00ffe73801102533e24c647afBoaz Harrosh
17944ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh/*
17954ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * Declared in osd_protocol.h
17964ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * 4.12.5 Data-In and Data-Out buffer offsets
17974ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * byte offset = mantissa * (2^(exponent+8))
17984ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * Returns the smallest allowed encoded offset that contains given @offset
17994ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh * The actual encoded offset returned is @offset + *@padding.
18004ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh */
18014ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harroshosd_cdb_offset __osd_encode_offset(
18024ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	u64 offset, unsigned *padding, int min_shift, int max_shift)
18034ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh{
18044ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	u64 try_offset = -1, mod, align;
18054ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	osd_cdb_offset be32_offset;
18064ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	int shift;
18074ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
18084ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	*padding = 0;
18094ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (!offset)
18104ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		return 0;
18114ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
18124ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	for (shift = min_shift; shift < max_shift; ++shift) {
18134ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		try_offset = offset >> shift;
18144ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		if (try_offset < (1 << OSD_OFFSET_MAX_BITS))
18154ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh			break;
18164ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	}
18174ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
18184ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	BUG_ON(shift == max_shift);
18194ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
18204ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	align = 1 << shift;
18214ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	mod = offset & (align - 1);
18224ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	if (mod) {
18234ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		*padding = align - mod;
18244ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		try_offset += 1;
18254ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	}
18264ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
18274ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	try_offset |= ((shift - 8) & 0xf) << 28;
18284ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	be32_offset = cpu_to_be32((u32)try_offset);
18294ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh
18304ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	OSD_DEBUG("offset=%llu mantissa=%llu exp=%d encoded=%x pad=%d\n",
18314ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		 _LLU(offset), _LLU(try_offset & 0x0FFFFFFF), shift,
18324ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh		 be32_offset, *padding);
18334ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh	return be32_offset;
18344ef1a3d70d02663f6bfe901db629e8e608da15b1Boaz Harrosh}
1835