188455ec4SChristoph Hellwig /* 288455ec4SChristoph Hellwig * SCSI Primary Commands (SPC) parsing and emulation. 388455ec4SChristoph Hellwig * 44c76251eSNicholas Bellinger * (c) Copyright 2002-2013 Datera, Inc. 588455ec4SChristoph Hellwig * 688455ec4SChristoph Hellwig * Nicholas A. Bellinger <nab@kernel.org> 788455ec4SChristoph Hellwig * 888455ec4SChristoph Hellwig * This program is free software; you can redistribute it and/or modify 988455ec4SChristoph Hellwig * it under the terms of the GNU General Public License as published by 1088455ec4SChristoph Hellwig * the Free Software Foundation; either version 2 of the License, or 1188455ec4SChristoph Hellwig * (at your option) any later version. 1288455ec4SChristoph Hellwig * 1388455ec4SChristoph Hellwig * This program is distributed in the hope that it will be useful, 1488455ec4SChristoph Hellwig * but WITHOUT ANY WARRANTY; without even the implied warranty of 1588455ec4SChristoph Hellwig * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1688455ec4SChristoph Hellwig * GNU General Public License for more details. 1788455ec4SChristoph Hellwig * 1888455ec4SChristoph Hellwig * You should have received a copy of the GNU General Public License 1988455ec4SChristoph Hellwig * along with this program; if not, write to the Free Software 2088455ec4SChristoph Hellwig * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 2188455ec4SChristoph Hellwig */ 2288455ec4SChristoph Hellwig 2388455ec4SChristoph Hellwig #include <linux/kernel.h> 2488455ec4SChristoph Hellwig #include <linux/module.h> 2588455ec4SChristoph Hellwig #include <asm/unaligned.h> 2688455ec4SChristoph Hellwig 2788455ec4SChristoph Hellwig #include <scsi/scsi.h> 2888455ec4SChristoph Hellwig #include <scsi/scsi_tcq.h> 2988455ec4SChristoph Hellwig 3088455ec4SChristoph Hellwig #include <target/target_core_base.h> 3188455ec4SChristoph Hellwig #include <target/target_core_backend.h> 3288455ec4SChristoph Hellwig #include <target/target_core_fabric.h> 3388455ec4SChristoph Hellwig 3488455ec4SChristoph Hellwig #include "target_core_internal.h" 35eba2ca45SNicholas Bellinger #include "target_core_alua.h" 3688455ec4SChristoph Hellwig #include "target_core_pr.h" 3788455ec4SChristoph Hellwig #include "target_core_ua.h" 3804b1b795SNicholas Bellinger #include "target_core_xcopy.h" 3988455ec4SChristoph Hellwig 401fd032eeSChristoph Hellwig static void spc_fill_alua_data(struct se_port *port, unsigned char *buf) 411fd032eeSChristoph Hellwig { 421fd032eeSChristoph Hellwig struct t10_alua_tg_pt_gp *tg_pt_gp; 431fd032eeSChristoph Hellwig struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; 441fd032eeSChristoph Hellwig 451fd032eeSChristoph Hellwig /* 461fd032eeSChristoph Hellwig * Set SCCS for MAINTENANCE_IN + REPORT_TARGET_PORT_GROUPS. 471fd032eeSChristoph Hellwig */ 481fd032eeSChristoph Hellwig buf[5] = 0x80; 491fd032eeSChristoph Hellwig 501fd032eeSChristoph Hellwig /* 511fd032eeSChristoph Hellwig * Set TPGS field for explict and/or implict ALUA access type 521fd032eeSChristoph Hellwig * and opteration. 531fd032eeSChristoph Hellwig * 541fd032eeSChristoph Hellwig * See spc4r17 section 6.4.2 Table 135 551fd032eeSChristoph Hellwig */ 561fd032eeSChristoph Hellwig if (!port) 571fd032eeSChristoph Hellwig return; 581fd032eeSChristoph Hellwig tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; 591fd032eeSChristoph Hellwig if (!tg_pt_gp_mem) 601fd032eeSChristoph Hellwig return; 611fd032eeSChristoph Hellwig 621fd032eeSChristoph Hellwig spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); 631fd032eeSChristoph Hellwig tg_pt_gp = tg_pt_gp_mem->tg_pt_gp; 641fd032eeSChristoph Hellwig if (tg_pt_gp) 651fd032eeSChristoph Hellwig buf[5] |= tg_pt_gp->tg_pt_gp_alua_access_type; 661fd032eeSChristoph Hellwig spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); 671fd032eeSChristoph Hellwig } 681fd032eeSChristoph Hellwig 690dfa1c5dSHannes Reinecke sense_reason_t 700dfa1c5dSHannes Reinecke spc_emulate_inquiry_std(struct se_cmd *cmd, unsigned char *buf) 711fd032eeSChristoph Hellwig { 721fd032eeSChristoph Hellwig struct se_lun *lun = cmd->se_lun; 731fd032eeSChristoph Hellwig struct se_device *dev = cmd->se_dev; 741fd032eeSChristoph Hellwig 751fd032eeSChristoph Hellwig /* Set RMB (removable media) for tape devices */ 761fd032eeSChristoph Hellwig if (dev->transport->get_device_type(dev) == TYPE_TAPE) 771fd032eeSChristoph Hellwig buf[1] = 0x80; 781fd032eeSChristoph Hellwig 7948c2567dSChristoph Hellwig buf[2] = 0x05; /* SPC-3 */ 801fd032eeSChristoph Hellwig 811fd032eeSChristoph Hellwig /* 821fd032eeSChristoph Hellwig * NORMACA and HISUP = 0, RESPONSE DATA FORMAT = 2 831fd032eeSChristoph Hellwig * 841fd032eeSChristoph Hellwig * SPC4 says: 851fd032eeSChristoph Hellwig * A RESPONSE DATA FORMAT field set to 2h indicates that the 861fd032eeSChristoph Hellwig * standard INQUIRY data is in the format defined in this 871fd032eeSChristoph Hellwig * standard. Response data format values less than 2h are 881fd032eeSChristoph Hellwig * obsolete. Response data format values greater than 2h are 891fd032eeSChristoph Hellwig * reserved. 901fd032eeSChristoph Hellwig */ 911fd032eeSChristoph Hellwig buf[3] = 2; 921fd032eeSChristoph Hellwig 931fd032eeSChristoph Hellwig /* 941fd032eeSChristoph Hellwig * Enable SCCS and TPGS fields for Emulated ALUA 951fd032eeSChristoph Hellwig */ 961fd032eeSChristoph Hellwig spc_fill_alua_data(lun->lun_sep, buf); 971fd032eeSChristoph Hellwig 98d397a445SNicholas Bellinger /* 99d397a445SNicholas Bellinger * Set Third-Party Copy (3PC) bit to indicate support for EXTENDED_COPY 100d397a445SNicholas Bellinger */ 101d397a445SNicholas Bellinger if (dev->dev_attrib.emulate_3pc) 102d397a445SNicholas Bellinger buf[5] |= 0x8; 103d397a445SNicholas Bellinger 1041fd032eeSChristoph Hellwig buf[7] = 0x2; /* CmdQue=1 */ 1051fd032eeSChristoph Hellwig 106ee60bddbSNicholas Bellinger memcpy(&buf[8], "LIO-ORG ", 8); 107ee60bddbSNicholas Bellinger memset(&buf[16], 0x20, 16); 108ee60bddbSNicholas Bellinger memcpy(&buf[16], dev->t10_wwn.model, 109ee60bddbSNicholas Bellinger min_t(size_t, strlen(dev->t10_wwn.model), 16)); 110ee60bddbSNicholas Bellinger memcpy(&buf[32], dev->t10_wwn.revision, 111ee60bddbSNicholas Bellinger min_t(size_t, strlen(dev->t10_wwn.revision), 4)); 1121fd032eeSChristoph Hellwig buf[4] = 31; /* Set additional length to 31 */ 1131fd032eeSChristoph Hellwig 1141fd032eeSChristoph Hellwig return 0; 1151fd032eeSChristoph Hellwig } 1160dfa1c5dSHannes Reinecke EXPORT_SYMBOL(spc_emulate_inquiry_std); 1171fd032eeSChristoph Hellwig 1181fd032eeSChristoph Hellwig /* unit serial number */ 119de103c93SChristoph Hellwig static sense_reason_t 120de103c93SChristoph Hellwig spc_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf) 1211fd032eeSChristoph Hellwig { 1221fd032eeSChristoph Hellwig struct se_device *dev = cmd->se_dev; 1231fd032eeSChristoph Hellwig u16 len = 0; 1241fd032eeSChristoph Hellwig 1250fd97ccfSChristoph Hellwig if (dev->dev_flags & DF_EMULATED_VPD_UNIT_SERIAL) { 1261fd032eeSChristoph Hellwig u32 unit_serial_len; 1271fd032eeSChristoph Hellwig 1280fd97ccfSChristoph Hellwig unit_serial_len = strlen(dev->t10_wwn.unit_serial); 1291fd032eeSChristoph Hellwig unit_serial_len++; /* For NULL Terminator */ 1301fd032eeSChristoph Hellwig 1310fd97ccfSChristoph Hellwig len += sprintf(&buf[4], "%s", dev->t10_wwn.unit_serial); 1321fd032eeSChristoph Hellwig len++; /* Extra Byte for NULL Terminator */ 1331fd032eeSChristoph Hellwig buf[3] = len; 1341fd032eeSChristoph Hellwig } 1351fd032eeSChristoph Hellwig return 0; 1361fd032eeSChristoph Hellwig } 1371fd032eeSChristoph Hellwig 13868366026SNicholas Bellinger void spc_parse_naa_6h_vendor_specific(struct se_device *dev, 1391fd032eeSChristoph Hellwig unsigned char *buf) 1401fd032eeSChristoph Hellwig { 1410fd97ccfSChristoph Hellwig unsigned char *p = &dev->t10_wwn.unit_serial[0]; 1421fd032eeSChristoph Hellwig int cnt; 1431fd032eeSChristoph Hellwig bool next = true; 1441fd032eeSChristoph Hellwig 1451fd032eeSChristoph Hellwig /* 1461fd032eeSChristoph Hellwig * Generate up to 36 bits of VENDOR SPECIFIC IDENTIFIER starting on 1471fd032eeSChristoph Hellwig * byte 3 bit 3-0 for NAA IEEE Registered Extended DESIGNATOR field 1481fd032eeSChristoph Hellwig * format, followed by 64 bits of VENDOR SPECIFIC IDENTIFIER EXTENSION 1491fd032eeSChristoph Hellwig * to complete the payload. These are based from VPD=0x80 PRODUCT SERIAL 1501fd032eeSChristoph Hellwig * NUMBER set via vpd_unit_serial in target_core_configfs.c to ensure 1511fd032eeSChristoph Hellwig * per device uniqeness. 1521fd032eeSChristoph Hellwig */ 1531fd032eeSChristoph Hellwig for (cnt = 0; *p && cnt < 13; p++) { 1541fd032eeSChristoph Hellwig int val = hex_to_bin(*p); 1551fd032eeSChristoph Hellwig 1561fd032eeSChristoph Hellwig if (val < 0) 1571fd032eeSChristoph Hellwig continue; 1581fd032eeSChristoph Hellwig 1591fd032eeSChristoph Hellwig if (next) { 1601fd032eeSChristoph Hellwig next = false; 1611fd032eeSChristoph Hellwig buf[cnt++] |= val; 1621fd032eeSChristoph Hellwig } else { 1631fd032eeSChristoph Hellwig next = true; 1641fd032eeSChristoph Hellwig buf[cnt] = val << 4; 1651fd032eeSChristoph Hellwig } 1661fd032eeSChristoph Hellwig } 1671fd032eeSChristoph Hellwig } 1681fd032eeSChristoph Hellwig 1691fd032eeSChristoph Hellwig /* 1701fd032eeSChristoph Hellwig * Device identification VPD, for a complete list of 1711fd032eeSChristoph Hellwig * DESIGNATOR TYPEs see spc4r17 Table 459. 1721fd032eeSChristoph Hellwig */ 1730dfa1c5dSHannes Reinecke sense_reason_t 174de103c93SChristoph Hellwig spc_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf) 1751fd032eeSChristoph Hellwig { 1761fd032eeSChristoph Hellwig struct se_device *dev = cmd->se_dev; 1771fd032eeSChristoph Hellwig struct se_lun *lun = cmd->se_lun; 1781fd032eeSChristoph Hellwig struct se_port *port = NULL; 1791fd032eeSChristoph Hellwig struct se_portal_group *tpg = NULL; 1801fd032eeSChristoph Hellwig struct t10_alua_lu_gp_member *lu_gp_mem; 1811fd032eeSChristoph Hellwig struct t10_alua_tg_pt_gp *tg_pt_gp; 1821fd032eeSChristoph Hellwig struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; 1830fd97ccfSChristoph Hellwig unsigned char *prod = &dev->t10_wwn.model[0]; 1841fd032eeSChristoph Hellwig u32 prod_len; 1851fd032eeSChristoph Hellwig u32 unit_serial_len, off = 0; 1861fd032eeSChristoph Hellwig u16 len = 0, id_len; 1871fd032eeSChristoph Hellwig 1881fd032eeSChristoph Hellwig off = 4; 1891fd032eeSChristoph Hellwig 1901fd032eeSChristoph Hellwig /* 1911fd032eeSChristoph Hellwig * NAA IEEE Registered Extended Assigned designator format, see 1921fd032eeSChristoph Hellwig * spc4r17 section 7.7.3.6.5 1931fd032eeSChristoph Hellwig * 1941fd032eeSChristoph Hellwig * We depend upon a target_core_mod/ConfigFS provided 1951fd032eeSChristoph Hellwig * /sys/kernel/config/target/core/$HBA/$DEV/wwn/vpd_unit_serial 1961fd032eeSChristoph Hellwig * value in order to return the NAA id. 1971fd032eeSChristoph Hellwig */ 1980fd97ccfSChristoph Hellwig if (!(dev->dev_flags & DF_EMULATED_VPD_UNIT_SERIAL)) 1991fd032eeSChristoph Hellwig goto check_t10_vend_desc; 2001fd032eeSChristoph Hellwig 2011fd032eeSChristoph Hellwig /* CODE SET == Binary */ 2021fd032eeSChristoph Hellwig buf[off++] = 0x1; 2031fd032eeSChristoph Hellwig 2041fd032eeSChristoph Hellwig /* Set ASSOCIATION == addressed logical unit: 0)b */ 2051fd032eeSChristoph Hellwig buf[off] = 0x00; 2061fd032eeSChristoph Hellwig 2071fd032eeSChristoph Hellwig /* Identifier/Designator type == NAA identifier */ 2081fd032eeSChristoph Hellwig buf[off++] |= 0x3; 2091fd032eeSChristoph Hellwig off++; 2101fd032eeSChristoph Hellwig 2111fd032eeSChristoph Hellwig /* Identifier/Designator length */ 2121fd032eeSChristoph Hellwig buf[off++] = 0x10; 2131fd032eeSChristoph Hellwig 2141fd032eeSChristoph Hellwig /* 2151fd032eeSChristoph Hellwig * Start NAA IEEE Registered Extended Identifier/Designator 2161fd032eeSChristoph Hellwig */ 2171fd032eeSChristoph Hellwig buf[off++] = (0x6 << 4); 2181fd032eeSChristoph Hellwig 2191fd032eeSChristoph Hellwig /* 2201fd032eeSChristoph Hellwig * Use OpenFabrics IEEE Company ID: 00 14 05 2211fd032eeSChristoph Hellwig */ 2221fd032eeSChristoph Hellwig buf[off++] = 0x01; 2231fd032eeSChristoph Hellwig buf[off++] = 0x40; 2241fd032eeSChristoph Hellwig buf[off] = (0x5 << 4); 2251fd032eeSChristoph Hellwig 2261fd032eeSChristoph Hellwig /* 2271fd032eeSChristoph Hellwig * Return ConfigFS Unit Serial Number information for 2281fd032eeSChristoph Hellwig * VENDOR_SPECIFIC_IDENTIFIER and 2291fd032eeSChristoph Hellwig * VENDOR_SPECIFIC_IDENTIFIER_EXTENTION 2301fd032eeSChristoph Hellwig */ 2311fd032eeSChristoph Hellwig spc_parse_naa_6h_vendor_specific(dev, &buf[off]); 2321fd032eeSChristoph Hellwig 2331fd032eeSChristoph Hellwig len = 20; 2341fd032eeSChristoph Hellwig off = (len + 4); 2351fd032eeSChristoph Hellwig 2361fd032eeSChristoph Hellwig check_t10_vend_desc: 2371fd032eeSChristoph Hellwig /* 2381fd032eeSChristoph Hellwig * T10 Vendor Identifier Page, see spc4r17 section 7.7.3.4 2391fd032eeSChristoph Hellwig */ 2401fd032eeSChristoph Hellwig id_len = 8; /* For Vendor field */ 2411fd032eeSChristoph Hellwig prod_len = 4; /* For VPD Header */ 2421fd032eeSChristoph Hellwig prod_len += 8; /* For Vendor field */ 2431fd032eeSChristoph Hellwig prod_len += strlen(prod); 2441fd032eeSChristoph Hellwig prod_len++; /* For : */ 2451fd032eeSChristoph Hellwig 2460fd97ccfSChristoph Hellwig if (dev->dev_flags & DF_EMULATED_VPD_UNIT_SERIAL) { 2470fd97ccfSChristoph Hellwig unit_serial_len = strlen(&dev->t10_wwn.unit_serial[0]); 2481fd032eeSChristoph Hellwig unit_serial_len++; /* For NULL Terminator */ 2491fd032eeSChristoph Hellwig 2501fd032eeSChristoph Hellwig id_len += sprintf(&buf[off+12], "%s:%s", prod, 2510fd97ccfSChristoph Hellwig &dev->t10_wwn.unit_serial[0]); 2521fd032eeSChristoph Hellwig } 2531fd032eeSChristoph Hellwig buf[off] = 0x2; /* ASCII */ 2541fd032eeSChristoph Hellwig buf[off+1] = 0x1; /* T10 Vendor ID */ 2551fd032eeSChristoph Hellwig buf[off+2] = 0x0; 2561fd032eeSChristoph Hellwig memcpy(&buf[off+4], "LIO-ORG", 8); 2571fd032eeSChristoph Hellwig /* Extra Byte for NULL Terminator */ 2581fd032eeSChristoph Hellwig id_len++; 2591fd032eeSChristoph Hellwig /* Identifier Length */ 2601fd032eeSChristoph Hellwig buf[off+3] = id_len; 2611fd032eeSChristoph Hellwig /* Header size for Designation descriptor */ 2621fd032eeSChristoph Hellwig len += (id_len + 4); 2631fd032eeSChristoph Hellwig off += (id_len + 4); 2641fd032eeSChristoph Hellwig /* 2651fd032eeSChristoph Hellwig * struct se_port is only set for INQUIRY VPD=1 through $FABRIC_MOD 2661fd032eeSChristoph Hellwig */ 2671fd032eeSChristoph Hellwig port = lun->lun_sep; 2681fd032eeSChristoph Hellwig if (port) { 2691fd032eeSChristoph Hellwig struct t10_alua_lu_gp *lu_gp; 2701fd032eeSChristoph Hellwig u32 padding, scsi_name_len; 2711fd032eeSChristoph Hellwig u16 lu_gp_id = 0; 2721fd032eeSChristoph Hellwig u16 tg_pt_gp_id = 0; 2731fd032eeSChristoph Hellwig u16 tpgt; 2741fd032eeSChristoph Hellwig 2751fd032eeSChristoph Hellwig tpg = port->sep_tpg; 2761fd032eeSChristoph Hellwig /* 2771fd032eeSChristoph Hellwig * Relative target port identifer, see spc4r17 2781fd032eeSChristoph Hellwig * section 7.7.3.7 2791fd032eeSChristoph Hellwig * 2801fd032eeSChristoph Hellwig * Get the PROTOCOL IDENTIFIER as defined by spc4r17 2811fd032eeSChristoph Hellwig * section 7.5.1 Table 362 2821fd032eeSChristoph Hellwig */ 2831fd032eeSChristoph Hellwig buf[off] = 2841fd032eeSChristoph Hellwig (tpg->se_tpg_tfo->get_fabric_proto_ident(tpg) << 4); 2851fd032eeSChristoph Hellwig buf[off++] |= 0x1; /* CODE SET == Binary */ 2861fd032eeSChristoph Hellwig buf[off] = 0x80; /* Set PIV=1 */ 2871fd032eeSChristoph Hellwig /* Set ASSOCIATION == target port: 01b */ 2881fd032eeSChristoph Hellwig buf[off] |= 0x10; 2891fd032eeSChristoph Hellwig /* DESIGNATOR TYPE == Relative target port identifer */ 2901fd032eeSChristoph Hellwig buf[off++] |= 0x4; 2911fd032eeSChristoph Hellwig off++; /* Skip over Reserved */ 2921fd032eeSChristoph Hellwig buf[off++] = 4; /* DESIGNATOR LENGTH */ 2931fd032eeSChristoph Hellwig /* Skip over Obsolete field in RTPI payload 2941fd032eeSChristoph Hellwig * in Table 472 */ 2951fd032eeSChristoph Hellwig off += 2; 2961fd032eeSChristoph Hellwig buf[off++] = ((port->sep_rtpi >> 8) & 0xff); 2971fd032eeSChristoph Hellwig buf[off++] = (port->sep_rtpi & 0xff); 2981fd032eeSChristoph Hellwig len += 8; /* Header size + Designation descriptor */ 2991fd032eeSChristoph Hellwig /* 3001fd032eeSChristoph Hellwig * Target port group identifier, see spc4r17 3011fd032eeSChristoph Hellwig * section 7.7.3.8 3021fd032eeSChristoph Hellwig * 3031fd032eeSChristoph Hellwig * Get the PROTOCOL IDENTIFIER as defined by spc4r17 3041fd032eeSChristoph Hellwig * section 7.5.1 Table 362 3051fd032eeSChristoph Hellwig */ 3061fd032eeSChristoph Hellwig tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; 3071fd032eeSChristoph Hellwig if (!tg_pt_gp_mem) 3081fd032eeSChristoph Hellwig goto check_lu_gp; 3091fd032eeSChristoph Hellwig 3101fd032eeSChristoph Hellwig spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); 3111fd032eeSChristoph Hellwig tg_pt_gp = tg_pt_gp_mem->tg_pt_gp; 3121fd032eeSChristoph Hellwig if (!tg_pt_gp) { 3131fd032eeSChristoph Hellwig spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); 3141fd032eeSChristoph Hellwig goto check_lu_gp; 3151fd032eeSChristoph Hellwig } 3161fd032eeSChristoph Hellwig tg_pt_gp_id = tg_pt_gp->tg_pt_gp_id; 3171fd032eeSChristoph Hellwig spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); 3181fd032eeSChristoph Hellwig 3191fd032eeSChristoph Hellwig buf[off] = 3201fd032eeSChristoph Hellwig (tpg->se_tpg_tfo->get_fabric_proto_ident(tpg) << 4); 3211fd032eeSChristoph Hellwig buf[off++] |= 0x1; /* CODE SET == Binary */ 3221fd032eeSChristoph Hellwig buf[off] = 0x80; /* Set PIV=1 */ 3231fd032eeSChristoph Hellwig /* Set ASSOCIATION == target port: 01b */ 3241fd032eeSChristoph Hellwig buf[off] |= 0x10; 3251fd032eeSChristoph Hellwig /* DESIGNATOR TYPE == Target port group identifier */ 3261fd032eeSChristoph Hellwig buf[off++] |= 0x5; 3271fd032eeSChristoph Hellwig off++; /* Skip over Reserved */ 3281fd032eeSChristoph Hellwig buf[off++] = 4; /* DESIGNATOR LENGTH */ 3291fd032eeSChristoph Hellwig off += 2; /* Skip over Reserved Field */ 3301fd032eeSChristoph Hellwig buf[off++] = ((tg_pt_gp_id >> 8) & 0xff); 3311fd032eeSChristoph Hellwig buf[off++] = (tg_pt_gp_id & 0xff); 3321fd032eeSChristoph Hellwig len += 8; /* Header size + Designation descriptor */ 3331fd032eeSChristoph Hellwig /* 3341fd032eeSChristoph Hellwig * Logical Unit Group identifier, see spc4r17 3351fd032eeSChristoph Hellwig * section 7.7.3.8 3361fd032eeSChristoph Hellwig */ 3371fd032eeSChristoph Hellwig check_lu_gp: 3381fd032eeSChristoph Hellwig lu_gp_mem = dev->dev_alua_lu_gp_mem; 3391fd032eeSChristoph Hellwig if (!lu_gp_mem) 3401fd032eeSChristoph Hellwig goto check_scsi_name; 3411fd032eeSChristoph Hellwig 3421fd032eeSChristoph Hellwig spin_lock(&lu_gp_mem->lu_gp_mem_lock); 3431fd032eeSChristoph Hellwig lu_gp = lu_gp_mem->lu_gp; 3441fd032eeSChristoph Hellwig if (!lu_gp) { 3451fd032eeSChristoph Hellwig spin_unlock(&lu_gp_mem->lu_gp_mem_lock); 3461fd032eeSChristoph Hellwig goto check_scsi_name; 3471fd032eeSChristoph Hellwig } 3481fd032eeSChristoph Hellwig lu_gp_id = lu_gp->lu_gp_id; 3491fd032eeSChristoph Hellwig spin_unlock(&lu_gp_mem->lu_gp_mem_lock); 3501fd032eeSChristoph Hellwig 3511fd032eeSChristoph Hellwig buf[off++] |= 0x1; /* CODE SET == Binary */ 3521fd032eeSChristoph Hellwig /* DESIGNATOR TYPE == Logical Unit Group identifier */ 3531fd032eeSChristoph Hellwig buf[off++] |= 0x6; 3541fd032eeSChristoph Hellwig off++; /* Skip over Reserved */ 3551fd032eeSChristoph Hellwig buf[off++] = 4; /* DESIGNATOR LENGTH */ 3561fd032eeSChristoph Hellwig off += 2; /* Skip over Reserved Field */ 3571fd032eeSChristoph Hellwig buf[off++] = ((lu_gp_id >> 8) & 0xff); 3581fd032eeSChristoph Hellwig buf[off++] = (lu_gp_id & 0xff); 3591fd032eeSChristoph Hellwig len += 8; /* Header size + Designation descriptor */ 3601fd032eeSChristoph Hellwig /* 3611fd032eeSChristoph Hellwig * SCSI name string designator, see spc4r17 3621fd032eeSChristoph Hellwig * section 7.7.3.11 3631fd032eeSChristoph Hellwig * 3641fd032eeSChristoph Hellwig * Get the PROTOCOL IDENTIFIER as defined by spc4r17 3651fd032eeSChristoph Hellwig * section 7.5.1 Table 362 3661fd032eeSChristoph Hellwig */ 3671fd032eeSChristoph Hellwig check_scsi_name: 3681fd032eeSChristoph Hellwig scsi_name_len = strlen(tpg->se_tpg_tfo->tpg_get_wwn(tpg)); 3691fd032eeSChristoph Hellwig /* UTF-8 ",t,0x<16-bit TPGT>" + NULL Terminator */ 3701fd032eeSChristoph Hellwig scsi_name_len += 10; 3711fd032eeSChristoph Hellwig /* Check for 4-byte padding */ 3721fd032eeSChristoph Hellwig padding = ((-scsi_name_len) & 3); 3731fd032eeSChristoph Hellwig if (padding != 0) 3741fd032eeSChristoph Hellwig scsi_name_len += padding; 3751fd032eeSChristoph Hellwig /* Header size + Designation descriptor */ 3761fd032eeSChristoph Hellwig scsi_name_len += 4; 3771fd032eeSChristoph Hellwig 3781fd032eeSChristoph Hellwig buf[off] = 3791fd032eeSChristoph Hellwig (tpg->se_tpg_tfo->get_fabric_proto_ident(tpg) << 4); 3801fd032eeSChristoph Hellwig buf[off++] |= 0x3; /* CODE SET == UTF-8 */ 3811fd032eeSChristoph Hellwig buf[off] = 0x80; /* Set PIV=1 */ 3821fd032eeSChristoph Hellwig /* Set ASSOCIATION == target port: 01b */ 3831fd032eeSChristoph Hellwig buf[off] |= 0x10; 3841fd032eeSChristoph Hellwig /* DESIGNATOR TYPE == SCSI name string */ 3851fd032eeSChristoph Hellwig buf[off++] |= 0x8; 3861fd032eeSChristoph Hellwig off += 2; /* Skip over Reserved and length */ 3871fd032eeSChristoph Hellwig /* 3881fd032eeSChristoph Hellwig * SCSI name string identifer containing, $FABRIC_MOD 3891fd032eeSChristoph Hellwig * dependent information. For LIO-Target and iSCSI 3901fd032eeSChristoph Hellwig * Target Port, this means "<iSCSI name>,t,0x<TPGT> in 3911fd032eeSChristoph Hellwig * UTF-8 encoding. 3921fd032eeSChristoph Hellwig */ 3931fd032eeSChristoph Hellwig tpgt = tpg->se_tpg_tfo->tpg_get_tag(tpg); 3941fd032eeSChristoph Hellwig scsi_name_len = sprintf(&buf[off], "%s,t,0x%04x", 3951fd032eeSChristoph Hellwig tpg->se_tpg_tfo->tpg_get_wwn(tpg), tpgt); 3961fd032eeSChristoph Hellwig scsi_name_len += 1 /* Include NULL terminator */; 3971fd032eeSChristoph Hellwig /* 3981fd032eeSChristoph Hellwig * The null-terminated, null-padded (see 4.4.2) SCSI 3991fd032eeSChristoph Hellwig * NAME STRING field contains a UTF-8 format string. 4001fd032eeSChristoph Hellwig * The number of bytes in the SCSI NAME STRING field 4011fd032eeSChristoph Hellwig * (i.e., the value in the DESIGNATOR LENGTH field) 4021fd032eeSChristoph Hellwig * shall be no larger than 256 and shall be a multiple 4031fd032eeSChristoph Hellwig * of four. 4041fd032eeSChristoph Hellwig */ 4051fd032eeSChristoph Hellwig if (padding) 4061fd032eeSChristoph Hellwig scsi_name_len += padding; 4071fd032eeSChristoph Hellwig 4081fd032eeSChristoph Hellwig buf[off-1] = scsi_name_len; 4091fd032eeSChristoph Hellwig off += scsi_name_len; 4101fd032eeSChristoph Hellwig /* Header size + Designation descriptor */ 4111fd032eeSChristoph Hellwig len += (scsi_name_len + 4); 4121fd032eeSChristoph Hellwig } 4131fd032eeSChristoph Hellwig buf[2] = ((len >> 8) & 0xff); 4141fd032eeSChristoph Hellwig buf[3] = (len & 0xff); /* Page Length for VPD 0x83 */ 4151fd032eeSChristoph Hellwig return 0; 4161fd032eeSChristoph Hellwig } 4170dfa1c5dSHannes Reinecke EXPORT_SYMBOL(spc_emulate_evpd_83); 4181fd032eeSChristoph Hellwig 419d0c8b259SNicholas Bellinger static bool 420d0c8b259SNicholas Bellinger spc_check_dev_wce(struct se_device *dev) 421d0c8b259SNicholas Bellinger { 422d0c8b259SNicholas Bellinger bool wce = false; 423d0c8b259SNicholas Bellinger 424d0c8b259SNicholas Bellinger if (dev->transport->get_write_cache) 425d0c8b259SNicholas Bellinger wce = dev->transport->get_write_cache(dev); 426d0c8b259SNicholas Bellinger else if (dev->dev_attrib.emulate_write_cache > 0) 427d0c8b259SNicholas Bellinger wce = true; 428d0c8b259SNicholas Bellinger 429d0c8b259SNicholas Bellinger return wce; 430d0c8b259SNicholas Bellinger } 431d0c8b259SNicholas Bellinger 4321fd032eeSChristoph Hellwig /* Extended INQUIRY Data VPD Page */ 433de103c93SChristoph Hellwig static sense_reason_t 434de103c93SChristoph Hellwig spc_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf) 4351fd032eeSChristoph Hellwig { 436d0c8b259SNicholas Bellinger struct se_device *dev = cmd->se_dev; 437d0c8b259SNicholas Bellinger 4381fd032eeSChristoph Hellwig buf[3] = 0x3c; 4391fd032eeSChristoph Hellwig /* Set HEADSUP, ORDSUP, SIMPSUP */ 4401fd032eeSChristoph Hellwig buf[5] = 0x07; 4411fd032eeSChristoph Hellwig 4421fd032eeSChristoph Hellwig /* If WriteCache emulation is enabled, set V_SUP */ 443d0c8b259SNicholas Bellinger if (spc_check_dev_wce(dev)) 4441fd032eeSChristoph Hellwig buf[6] = 0x01; 4451fd032eeSChristoph Hellwig return 0; 4461fd032eeSChristoph Hellwig } 4471fd032eeSChristoph Hellwig 4481fd032eeSChristoph Hellwig /* Block Limits VPD page */ 449de103c93SChristoph Hellwig static sense_reason_t 450de103c93SChristoph Hellwig spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) 4511fd032eeSChristoph Hellwig { 4521fd032eeSChristoph Hellwig struct se_device *dev = cmd->se_dev; 4531fd032eeSChristoph Hellwig u32 max_sectors; 4541fd032eeSChristoph Hellwig int have_tp = 0; 4557f7caf6aSAndy Grover int opt, min; 4561fd032eeSChristoph Hellwig 4571fd032eeSChristoph Hellwig /* 4581fd032eeSChristoph Hellwig * Following spc3r22 section 6.5.3 Block Limits VPD page, when 4591fd032eeSChristoph Hellwig * emulate_tpu=1 or emulate_tpws=1 we will be expect a 4601fd032eeSChristoph Hellwig * different page length for Thin Provisioning. 4611fd032eeSChristoph Hellwig */ 4620fd97ccfSChristoph Hellwig if (dev->dev_attrib.emulate_tpu || dev->dev_attrib.emulate_tpws) 4631fd032eeSChristoph Hellwig have_tp = 1; 4641fd032eeSChristoph Hellwig 4651fd032eeSChristoph Hellwig buf[0] = dev->transport->get_device_type(dev); 4661fd032eeSChristoph Hellwig buf[3] = have_tp ? 0x3c : 0x10; 4671fd032eeSChristoph Hellwig 4681fd032eeSChristoph Hellwig /* Set WSNZ to 1 */ 4691fd032eeSChristoph Hellwig buf[4] = 0x01; 4700123a9ecSNicholas Bellinger /* 4710123a9ecSNicholas Bellinger * Set MAXIMUM COMPARE AND WRITE LENGTH 4720123a9ecSNicholas Bellinger */ 4730123a9ecSNicholas Bellinger if (dev->dev_attrib.emulate_caw) 4740123a9ecSNicholas Bellinger buf[5] = 0x01; 4751fd032eeSChristoph Hellwig 4761fd032eeSChristoph Hellwig /* 4771fd032eeSChristoph Hellwig * Set OPTIMAL TRANSFER LENGTH GRANULARITY 4781fd032eeSChristoph Hellwig */ 4797f7caf6aSAndy Grover if (dev->transport->get_io_min && (min = dev->transport->get_io_min(dev))) 4807f7caf6aSAndy Grover put_unaligned_be16(min / dev->dev_attrib.block_size, &buf[6]); 4817f7caf6aSAndy Grover else 4821fd032eeSChristoph Hellwig put_unaligned_be16(1, &buf[6]); 4831fd032eeSChristoph Hellwig 4841fd032eeSChristoph Hellwig /* 4851fd032eeSChristoph Hellwig * Set MAXIMUM TRANSFER LENGTH 4861fd032eeSChristoph Hellwig */ 4870fd97ccfSChristoph Hellwig max_sectors = min(dev->dev_attrib.fabric_max_sectors, 4880fd97ccfSChristoph Hellwig dev->dev_attrib.hw_max_sectors); 4891fd032eeSChristoph Hellwig put_unaligned_be32(max_sectors, &buf[8]); 4901fd032eeSChristoph Hellwig 4911fd032eeSChristoph Hellwig /* 4921fd032eeSChristoph Hellwig * Set OPTIMAL TRANSFER LENGTH 4931fd032eeSChristoph Hellwig */ 4947f7caf6aSAndy Grover if (dev->transport->get_io_opt && (opt = dev->transport->get_io_opt(dev))) 4957f7caf6aSAndy Grover put_unaligned_be32(opt / dev->dev_attrib.block_size, &buf[12]); 4967f7caf6aSAndy Grover else 4970fd97ccfSChristoph Hellwig put_unaligned_be32(dev->dev_attrib.optimal_sectors, &buf[12]); 4981fd032eeSChristoph Hellwig 4991fd032eeSChristoph Hellwig /* 5001fd032eeSChristoph Hellwig * Exit now if we don't support TP. 5011fd032eeSChristoph Hellwig */ 5021fd032eeSChristoph Hellwig if (!have_tp) 503773cbaf7SNicholas Bellinger goto max_write_same; 5041fd032eeSChristoph Hellwig 5051fd032eeSChristoph Hellwig /* 5061fd032eeSChristoph Hellwig * Set MAXIMUM UNMAP LBA COUNT 5071fd032eeSChristoph Hellwig */ 5080fd97ccfSChristoph Hellwig put_unaligned_be32(dev->dev_attrib.max_unmap_lba_count, &buf[20]); 5091fd032eeSChristoph Hellwig 5101fd032eeSChristoph Hellwig /* 5111fd032eeSChristoph Hellwig * Set MAXIMUM UNMAP BLOCK DESCRIPTOR COUNT 5121fd032eeSChristoph Hellwig */ 5130fd97ccfSChristoph Hellwig put_unaligned_be32(dev->dev_attrib.max_unmap_block_desc_count, 5141fd032eeSChristoph Hellwig &buf[24]); 5151fd032eeSChristoph Hellwig 5161fd032eeSChristoph Hellwig /* 5171fd032eeSChristoph Hellwig * Set OPTIMAL UNMAP GRANULARITY 5181fd032eeSChristoph Hellwig */ 5190fd97ccfSChristoph Hellwig put_unaligned_be32(dev->dev_attrib.unmap_granularity, &buf[28]); 5201fd032eeSChristoph Hellwig 5211fd032eeSChristoph Hellwig /* 5221fd032eeSChristoph Hellwig * UNMAP GRANULARITY ALIGNMENT 5231fd032eeSChristoph Hellwig */ 5240fd97ccfSChristoph Hellwig put_unaligned_be32(dev->dev_attrib.unmap_granularity_alignment, 5251fd032eeSChristoph Hellwig &buf[32]); 5260fd97ccfSChristoph Hellwig if (dev->dev_attrib.unmap_granularity_alignment != 0) 5271fd032eeSChristoph Hellwig buf[32] |= 0x80; /* Set the UGAVALID bit */ 5281fd032eeSChristoph Hellwig 529773cbaf7SNicholas Bellinger /* 530773cbaf7SNicholas Bellinger * MAXIMUM WRITE SAME LENGTH 531773cbaf7SNicholas Bellinger */ 532773cbaf7SNicholas Bellinger max_write_same: 533773cbaf7SNicholas Bellinger put_unaligned_be64(dev->dev_attrib.max_write_same_len, &buf[36]); 534773cbaf7SNicholas Bellinger 5351fd032eeSChristoph Hellwig return 0; 5361fd032eeSChristoph Hellwig } 5371fd032eeSChristoph Hellwig 5381fd032eeSChristoph Hellwig /* Block Device Characteristics VPD page */ 539de103c93SChristoph Hellwig static sense_reason_t 540de103c93SChristoph Hellwig spc_emulate_evpd_b1(struct se_cmd *cmd, unsigned char *buf) 5411fd032eeSChristoph Hellwig { 5421fd032eeSChristoph Hellwig struct se_device *dev = cmd->se_dev; 5431fd032eeSChristoph Hellwig 5441fd032eeSChristoph Hellwig buf[0] = dev->transport->get_device_type(dev); 5451fd032eeSChristoph Hellwig buf[3] = 0x3c; 5460fd97ccfSChristoph Hellwig buf[5] = dev->dev_attrib.is_nonrot ? 1 : 0; 5471fd032eeSChristoph Hellwig 5481fd032eeSChristoph Hellwig return 0; 5491fd032eeSChristoph Hellwig } 5501fd032eeSChristoph Hellwig 5511fd032eeSChristoph Hellwig /* Thin Provisioning VPD */ 552de103c93SChristoph Hellwig static sense_reason_t 553de103c93SChristoph Hellwig spc_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf) 5541fd032eeSChristoph Hellwig { 5551fd032eeSChristoph Hellwig struct se_device *dev = cmd->se_dev; 5561fd032eeSChristoph Hellwig 5571fd032eeSChristoph Hellwig /* 5581fd032eeSChristoph Hellwig * From spc3r22 section 6.5.4 Thin Provisioning VPD page: 5591fd032eeSChristoph Hellwig * 5601fd032eeSChristoph Hellwig * The PAGE LENGTH field is defined in SPC-4. If the DP bit is set to 5611fd032eeSChristoph Hellwig * zero, then the page length shall be set to 0004h. If the DP bit 5621fd032eeSChristoph Hellwig * is set to one, then the page length shall be set to the value 5631fd032eeSChristoph Hellwig * defined in table 162. 5641fd032eeSChristoph Hellwig */ 5651fd032eeSChristoph Hellwig buf[0] = dev->transport->get_device_type(dev); 5661fd032eeSChristoph Hellwig 5671fd032eeSChristoph Hellwig /* 5681fd032eeSChristoph Hellwig * Set Hardcoded length mentioned above for DP=0 5691fd032eeSChristoph Hellwig */ 5701fd032eeSChristoph Hellwig put_unaligned_be16(0x0004, &buf[2]); 5711fd032eeSChristoph Hellwig 5721fd032eeSChristoph Hellwig /* 5731fd032eeSChristoph Hellwig * The THRESHOLD EXPONENT field indicates the threshold set size in 5741fd032eeSChristoph Hellwig * LBAs as a power of 2 (i.e., the threshold set size is equal to 5751fd032eeSChristoph Hellwig * 2(threshold exponent)). 5761fd032eeSChristoph Hellwig * 5771fd032eeSChristoph Hellwig * Note that this is currently set to 0x00 as mkp says it will be 5781fd032eeSChristoph Hellwig * changing again. We can enable this once it has settled in T10 5791fd032eeSChristoph Hellwig * and is actually used by Linux/SCSI ML code. 5801fd032eeSChristoph Hellwig */ 5811fd032eeSChristoph Hellwig buf[4] = 0x00; 5821fd032eeSChristoph Hellwig 5831fd032eeSChristoph Hellwig /* 5841fd032eeSChristoph Hellwig * A TPU bit set to one indicates that the device server supports 5851fd032eeSChristoph Hellwig * the UNMAP command (see 5.25). A TPU bit set to zero indicates 5861fd032eeSChristoph Hellwig * that the device server does not support the UNMAP command. 5871fd032eeSChristoph Hellwig */ 5880fd97ccfSChristoph Hellwig if (dev->dev_attrib.emulate_tpu != 0) 5891fd032eeSChristoph Hellwig buf[5] = 0x80; 5901fd032eeSChristoph Hellwig 5911fd032eeSChristoph Hellwig /* 5921fd032eeSChristoph Hellwig * A TPWS bit set to one indicates that the device server supports 5931fd032eeSChristoph Hellwig * the use of the WRITE SAME (16) command (see 5.42) to unmap LBAs. 5941fd032eeSChristoph Hellwig * A TPWS bit set to zero indicates that the device server does not 5951fd032eeSChristoph Hellwig * support the use of the WRITE SAME (16) command to unmap LBAs. 5961fd032eeSChristoph Hellwig */ 5970fd97ccfSChristoph Hellwig if (dev->dev_attrib.emulate_tpws != 0) 5981fd032eeSChristoph Hellwig buf[5] |= 0x40; 5991fd032eeSChristoph Hellwig 6001fd032eeSChristoph Hellwig return 0; 6011fd032eeSChristoph Hellwig } 6021fd032eeSChristoph Hellwig 603de103c93SChristoph Hellwig static sense_reason_t 604de103c93SChristoph Hellwig spc_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf); 6051fd032eeSChristoph Hellwig 6061fd032eeSChristoph Hellwig static struct { 6071fd032eeSChristoph Hellwig uint8_t page; 608de103c93SChristoph Hellwig sense_reason_t (*emulate)(struct se_cmd *, unsigned char *); 6091fd032eeSChristoph Hellwig } evpd_handlers[] = { 6101fd032eeSChristoph Hellwig { .page = 0x00, .emulate = spc_emulate_evpd_00 }, 6111fd032eeSChristoph Hellwig { .page = 0x80, .emulate = spc_emulate_evpd_80 }, 6121fd032eeSChristoph Hellwig { .page = 0x83, .emulate = spc_emulate_evpd_83 }, 6131fd032eeSChristoph Hellwig { .page = 0x86, .emulate = spc_emulate_evpd_86 }, 6141fd032eeSChristoph Hellwig { .page = 0xb0, .emulate = spc_emulate_evpd_b0 }, 6151fd032eeSChristoph Hellwig { .page = 0xb1, .emulate = spc_emulate_evpd_b1 }, 6161fd032eeSChristoph Hellwig { .page = 0xb2, .emulate = spc_emulate_evpd_b2 }, 6171fd032eeSChristoph Hellwig }; 6181fd032eeSChristoph Hellwig 6191fd032eeSChristoph Hellwig /* supported vital product data pages */ 620de103c93SChristoph Hellwig static sense_reason_t 621de103c93SChristoph Hellwig spc_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf) 6221fd032eeSChristoph Hellwig { 6231fd032eeSChristoph Hellwig int p; 6241fd032eeSChristoph Hellwig 6251fd032eeSChristoph Hellwig /* 6261fd032eeSChristoph Hellwig * Only report the INQUIRY EVPD=1 pages after a valid NAA 6271fd032eeSChristoph Hellwig * Registered Extended LUN WWN has been set via ConfigFS 6281fd032eeSChristoph Hellwig * during device creation/restart. 6291fd032eeSChristoph Hellwig */ 6300fd97ccfSChristoph Hellwig if (cmd->se_dev->dev_flags & DF_EMULATED_VPD_UNIT_SERIAL) { 6311fd032eeSChristoph Hellwig buf[3] = ARRAY_SIZE(evpd_handlers); 6321fd032eeSChristoph Hellwig for (p = 0; p < ARRAY_SIZE(evpd_handlers); ++p) 6331fd032eeSChristoph Hellwig buf[p + 4] = evpd_handlers[p].page; 6341fd032eeSChristoph Hellwig } 6351fd032eeSChristoph Hellwig 6361fd032eeSChristoph Hellwig return 0; 6371fd032eeSChristoph Hellwig } 6381fd032eeSChristoph Hellwig 639de103c93SChristoph Hellwig static sense_reason_t 640de103c93SChristoph Hellwig spc_emulate_inquiry(struct se_cmd *cmd) 6411fd032eeSChristoph Hellwig { 6421fd032eeSChristoph Hellwig struct se_device *dev = cmd->se_dev; 6431fd032eeSChristoph Hellwig struct se_portal_group *tpg = cmd->se_lun->lun_sep->sep_tpg; 644ffe7b0e9SPaolo Bonzini unsigned char *rbuf; 6451fd032eeSChristoph Hellwig unsigned char *cdb = cmd->t_task_cdb; 646ffe7b0e9SPaolo Bonzini unsigned char buf[SE_INQUIRY_BUF]; 647de103c93SChristoph Hellwig sense_reason_t ret; 648de103c93SChristoph Hellwig int p; 6491fd032eeSChristoph Hellwig 650dea5f099SNicholas Bellinger memset(buf, 0, SE_INQUIRY_BUF); 651dea5f099SNicholas Bellinger 6521fd032eeSChristoph Hellwig if (dev == tpg->tpg_virt_lun0.lun_se_dev) 6531fd032eeSChristoph Hellwig buf[0] = 0x3f; /* Not connected */ 6541fd032eeSChristoph Hellwig else 6551fd032eeSChristoph Hellwig buf[0] = dev->transport->get_device_type(dev); 6561fd032eeSChristoph Hellwig 6571fd032eeSChristoph Hellwig if (!(cdb[1] & 0x1)) { 6581fd032eeSChristoph Hellwig if (cdb[2]) { 6591fd032eeSChristoph Hellwig pr_err("INQUIRY with EVPD==0 but PAGE CODE=%02x\n", 6601fd032eeSChristoph Hellwig cdb[2]); 661de103c93SChristoph Hellwig ret = TCM_INVALID_CDB_FIELD; 6621fd032eeSChristoph Hellwig goto out; 6631fd032eeSChristoph Hellwig } 6641fd032eeSChristoph Hellwig 6651fd032eeSChristoph Hellwig ret = spc_emulate_inquiry_std(cmd, buf); 6661fd032eeSChristoph Hellwig goto out; 6671fd032eeSChristoph Hellwig } 6681fd032eeSChristoph Hellwig 6691fd032eeSChristoph Hellwig for (p = 0; p < ARRAY_SIZE(evpd_handlers); ++p) { 6701fd032eeSChristoph Hellwig if (cdb[2] == evpd_handlers[p].page) { 6711fd032eeSChristoph Hellwig buf[1] = cdb[2]; 6721fd032eeSChristoph Hellwig ret = evpd_handlers[p].emulate(cmd, buf); 6731fd032eeSChristoph Hellwig goto out; 6741fd032eeSChristoph Hellwig } 6751fd032eeSChristoph Hellwig } 6761fd032eeSChristoph Hellwig 6771fd032eeSChristoph Hellwig pr_err("Unknown VPD Code: 0x%02x\n", cdb[2]); 678de103c93SChristoph Hellwig ret = TCM_INVALID_CDB_FIELD; 6791fd032eeSChristoph Hellwig 6801fd032eeSChristoph Hellwig out: 681ffe7b0e9SPaolo Bonzini rbuf = transport_kmap_data_sg(cmd); 68249df9fc9SNicholas Bellinger if (rbuf) { 683ffe7b0e9SPaolo Bonzini memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); 6841fd032eeSChristoph Hellwig transport_kunmap_data_sg(cmd); 68549df9fc9SNicholas Bellinger } 6861fd032eeSChristoph Hellwig 6871fd032eeSChristoph Hellwig if (!ret) 6881fd032eeSChristoph Hellwig target_complete_cmd(cmd, GOOD); 6891fd032eeSChristoph Hellwig return ret; 6901fd032eeSChristoph Hellwig } 6911fd032eeSChristoph Hellwig 692d4b2b867SRoland Dreier static int spc_modesense_rwrecovery(struct se_device *dev, u8 pc, u8 *p) 6931fd032eeSChristoph Hellwig { 6941fd032eeSChristoph Hellwig p[0] = 0x01; 6951fd032eeSChristoph Hellwig p[1] = 0x0a; 6961fd032eeSChristoph Hellwig 697d4b2b867SRoland Dreier /* No changeable values for now */ 698d4b2b867SRoland Dreier if (pc == 1) 699d4b2b867SRoland Dreier goto out; 700d4b2b867SRoland Dreier 701d4b2b867SRoland Dreier out: 7021fd032eeSChristoph Hellwig return 12; 7031fd032eeSChristoph Hellwig } 7041fd032eeSChristoph Hellwig 705d4b2b867SRoland Dreier static int spc_modesense_control(struct se_device *dev, u8 pc, u8 *p) 7061fd032eeSChristoph Hellwig { 7071fd032eeSChristoph Hellwig p[0] = 0x0a; 7081fd032eeSChristoph Hellwig p[1] = 0x0a; 709d4b2b867SRoland Dreier 710d4b2b867SRoland Dreier /* No changeable values for now */ 711d4b2b867SRoland Dreier if (pc == 1) 712d4b2b867SRoland Dreier goto out; 713d4b2b867SRoland Dreier 7141fd032eeSChristoph Hellwig p[2] = 2; 7151fd032eeSChristoph Hellwig /* 7161fd032eeSChristoph Hellwig * From spc4r23, 7.4.7 Control mode page 7171fd032eeSChristoph Hellwig * 7181fd032eeSChristoph Hellwig * The QUEUE ALGORITHM MODIFIER field (see table 368) specifies 7191fd032eeSChristoph Hellwig * restrictions on the algorithm used for reordering commands 7201fd032eeSChristoph Hellwig * having the SIMPLE task attribute (see SAM-4). 7211fd032eeSChristoph Hellwig * 7221fd032eeSChristoph Hellwig * Table 368 -- QUEUE ALGORITHM MODIFIER field 7231fd032eeSChristoph Hellwig * Code Description 7241fd032eeSChristoph Hellwig * 0h Restricted reordering 7251fd032eeSChristoph Hellwig * 1h Unrestricted reordering allowed 7261fd032eeSChristoph Hellwig * 2h to 7h Reserved 7271fd032eeSChristoph Hellwig * 8h to Fh Vendor specific 7281fd032eeSChristoph Hellwig * 7291fd032eeSChristoph Hellwig * A value of zero in the QUEUE ALGORITHM MODIFIER field specifies that 7301fd032eeSChristoph Hellwig * the device server shall order the processing sequence of commands 7311fd032eeSChristoph Hellwig * having the SIMPLE task attribute such that data integrity is maintained 7321fd032eeSChristoph Hellwig * for that I_T nexus (i.e., if the transmission of new SCSI transport protocol 7331fd032eeSChristoph Hellwig * requests is halted at any time, the final value of all data observable 7341fd032eeSChristoph Hellwig * on the medium shall be the same as if all the commands had been processed 7351fd032eeSChristoph Hellwig * with the ORDERED task attribute). 7361fd032eeSChristoph Hellwig * 7371fd032eeSChristoph Hellwig * A value of one in the QUEUE ALGORITHM MODIFIER field specifies that the 7381fd032eeSChristoph Hellwig * device server may reorder the processing sequence of commands having the 7391fd032eeSChristoph Hellwig * SIMPLE task attribute in any manner. Any data integrity exposures related to 7401fd032eeSChristoph Hellwig * command sequence order shall be explicitly handled by the application client 7411fd032eeSChristoph Hellwig * through the selection of appropriate ommands and task attributes. 7421fd032eeSChristoph Hellwig */ 7430fd97ccfSChristoph Hellwig p[3] = (dev->dev_attrib.emulate_rest_reord == 1) ? 0x00 : 0x10; 7441fd032eeSChristoph Hellwig /* 7451fd032eeSChristoph Hellwig * From spc4r17, section 7.4.6 Control mode Page 7461fd032eeSChristoph Hellwig * 7471fd032eeSChristoph Hellwig * Unit Attention interlocks control (UN_INTLCK_CTRL) to code 00b 7481fd032eeSChristoph Hellwig * 7491fd032eeSChristoph Hellwig * 00b: The logical unit shall clear any unit attention condition 7501fd032eeSChristoph Hellwig * reported in the same I_T_L_Q nexus transaction as a CHECK CONDITION 7511fd032eeSChristoph Hellwig * status and shall not establish a unit attention condition when a com- 7521fd032eeSChristoph Hellwig * mand is completed with BUSY, TASK SET FULL, or RESERVATION CONFLICT 7531fd032eeSChristoph Hellwig * status. 7541fd032eeSChristoph Hellwig * 7551fd032eeSChristoph Hellwig * 10b: The logical unit shall not clear any unit attention condition 7561fd032eeSChristoph Hellwig * reported in the same I_T_L_Q nexus transaction as a CHECK CONDITION 7571fd032eeSChristoph Hellwig * status and shall not establish a unit attention condition when 7581fd032eeSChristoph Hellwig * a command is completed with BUSY, TASK SET FULL, or RESERVATION 7591fd032eeSChristoph Hellwig * CONFLICT status. 7601fd032eeSChristoph Hellwig * 7611fd032eeSChristoph Hellwig * 11b a The logical unit shall not clear any unit attention condition 7621fd032eeSChristoph Hellwig * reported in the same I_T_L_Q nexus transaction as a CHECK CONDITION 7631fd032eeSChristoph Hellwig * status and shall establish a unit attention condition for the 7641fd032eeSChristoph Hellwig * initiator port associated with the I_T nexus on which the BUSY, 7651fd032eeSChristoph Hellwig * TASK SET FULL, or RESERVATION CONFLICT status is being returned. 7661fd032eeSChristoph Hellwig * Depending on the status, the additional sense code shall be set to 7671fd032eeSChristoph Hellwig * PREVIOUS BUSY STATUS, PREVIOUS TASK SET FULL STATUS, or PREVIOUS 7681fd032eeSChristoph Hellwig * RESERVATION CONFLICT STATUS. Until it is cleared by a REQUEST SENSE 7691fd032eeSChristoph Hellwig * command, a unit attention condition shall be established only once 7701fd032eeSChristoph Hellwig * for a BUSY, TASK SET FULL, or RESERVATION CONFLICT status regardless 7711fd032eeSChristoph Hellwig * to the number of commands completed with one of those status codes. 7721fd032eeSChristoph Hellwig */ 7730fd97ccfSChristoph Hellwig p[4] = (dev->dev_attrib.emulate_ua_intlck_ctrl == 2) ? 0x30 : 7740fd97ccfSChristoph Hellwig (dev->dev_attrib.emulate_ua_intlck_ctrl == 1) ? 0x20 : 0x00; 7751fd032eeSChristoph Hellwig /* 7761fd032eeSChristoph Hellwig * From spc4r17, section 7.4.6 Control mode Page 7771fd032eeSChristoph Hellwig * 7781fd032eeSChristoph Hellwig * Task Aborted Status (TAS) bit set to zero. 7791fd032eeSChristoph Hellwig * 7801fd032eeSChristoph Hellwig * A task aborted status (TAS) bit set to zero specifies that aborted 7811fd032eeSChristoph Hellwig * tasks shall be terminated by the device server without any response 7821fd032eeSChristoph Hellwig * to the application client. A TAS bit set to one specifies that tasks 7831fd032eeSChristoph Hellwig * aborted by the actions of an I_T nexus other than the I_T nexus on 7841fd032eeSChristoph Hellwig * which the command was received shall be completed with TASK ABORTED 7851fd032eeSChristoph Hellwig * status (see SAM-4). 7861fd032eeSChristoph Hellwig */ 7870fd97ccfSChristoph Hellwig p[5] = (dev->dev_attrib.emulate_tas) ? 0x40 : 0x00; 7881fd032eeSChristoph Hellwig p[8] = 0xff; 7891fd032eeSChristoph Hellwig p[9] = 0xff; 7901fd032eeSChristoph Hellwig p[11] = 30; 7911fd032eeSChristoph Hellwig 792d4b2b867SRoland Dreier out: 7931fd032eeSChristoph Hellwig return 12; 7941fd032eeSChristoph Hellwig } 7951fd032eeSChristoph Hellwig 796d4b2b867SRoland Dreier static int spc_modesense_caching(struct se_device *dev, u8 pc, u8 *p) 7971fd032eeSChristoph Hellwig { 7981fd032eeSChristoph Hellwig p[0] = 0x08; 7991fd032eeSChristoph Hellwig p[1] = 0x12; 800d4b2b867SRoland Dreier 801d4b2b867SRoland Dreier /* No changeable values for now */ 802d4b2b867SRoland Dreier if (pc == 1) 803d4b2b867SRoland Dreier goto out; 804d4b2b867SRoland Dreier 805d0c8b259SNicholas Bellinger if (spc_check_dev_wce(dev)) 8061fd032eeSChristoph Hellwig p[2] = 0x04; /* Write Cache Enable */ 8071fd032eeSChristoph Hellwig p[12] = 0x20; /* Disabled Read Ahead */ 8081fd032eeSChristoph Hellwig 809d4b2b867SRoland Dreier out: 8101fd032eeSChristoph Hellwig return 20; 8111fd032eeSChristoph Hellwig } 8121fd032eeSChristoph Hellwig 8130f6d64ceSRoland Dreier static int spc_modesense_informational_exceptions(struct se_device *dev, u8 pc, unsigned char *p) 8140f6d64ceSRoland Dreier { 8150f6d64ceSRoland Dreier p[0] = 0x1c; 8160f6d64ceSRoland Dreier p[1] = 0x0a; 8170f6d64ceSRoland Dreier 8180f6d64ceSRoland Dreier /* No changeable values for now */ 8190f6d64ceSRoland Dreier if (pc == 1) 8200f6d64ceSRoland Dreier goto out; 8210f6d64ceSRoland Dreier 8220f6d64ceSRoland Dreier out: 8230f6d64ceSRoland Dreier return 12; 8240f6d64ceSRoland Dreier } 8250f6d64ceSRoland Dreier 826d4b2b867SRoland Dreier static struct { 827d4b2b867SRoland Dreier uint8_t page; 828d4b2b867SRoland Dreier uint8_t subpage; 829d4b2b867SRoland Dreier int (*emulate)(struct se_device *, u8, unsigned char *); 830d4b2b867SRoland Dreier } modesense_handlers[] = { 831d4b2b867SRoland Dreier { .page = 0x01, .subpage = 0x00, .emulate = spc_modesense_rwrecovery }, 832d4b2b867SRoland Dreier { .page = 0x08, .subpage = 0x00, .emulate = spc_modesense_caching }, 833d4b2b867SRoland Dreier { .page = 0x0a, .subpage = 0x00, .emulate = spc_modesense_control }, 8340f6d64ceSRoland Dreier { .page = 0x1c, .subpage = 0x00, .emulate = spc_modesense_informational_exceptions }, 835d4b2b867SRoland Dreier }; 836d4b2b867SRoland Dreier 8371fd032eeSChristoph Hellwig static void spc_modesense_write_protect(unsigned char *buf, int type) 8381fd032eeSChristoph Hellwig { 8391fd032eeSChristoph Hellwig /* 8401fd032eeSChristoph Hellwig * I believe that the WP bit (bit 7) in the mode header is the same for 8411fd032eeSChristoph Hellwig * all device types.. 8421fd032eeSChristoph Hellwig */ 8431fd032eeSChristoph Hellwig switch (type) { 8441fd032eeSChristoph Hellwig case TYPE_DISK: 8451fd032eeSChristoph Hellwig case TYPE_TAPE: 8461fd032eeSChristoph Hellwig default: 8471fd032eeSChristoph Hellwig buf[0] |= 0x80; /* WP bit */ 8481fd032eeSChristoph Hellwig break; 8491fd032eeSChristoph Hellwig } 8501fd032eeSChristoph Hellwig } 8511fd032eeSChristoph Hellwig 8521fd032eeSChristoph Hellwig static void spc_modesense_dpofua(unsigned char *buf, int type) 8531fd032eeSChristoph Hellwig { 8541fd032eeSChristoph Hellwig switch (type) { 8551fd032eeSChristoph Hellwig case TYPE_DISK: 8561fd032eeSChristoph Hellwig buf[0] |= 0x10; /* DPOFUA bit */ 8571fd032eeSChristoph Hellwig break; 8581fd032eeSChristoph Hellwig default: 8591fd032eeSChristoph Hellwig break; 8601fd032eeSChristoph Hellwig } 8611fd032eeSChristoph Hellwig } 8621fd032eeSChristoph Hellwig 863d4b2b867SRoland Dreier static int spc_modesense_blockdesc(unsigned char *buf, u64 blocks, u32 block_size) 864d4b2b867SRoland Dreier { 865d4b2b867SRoland Dreier *buf++ = 8; 866d4b2b867SRoland Dreier put_unaligned_be32(min(blocks, 0xffffffffull), buf); 867d4b2b867SRoland Dreier buf += 4; 868d4b2b867SRoland Dreier put_unaligned_be32(block_size, buf); 869d4b2b867SRoland Dreier return 9; 870d4b2b867SRoland Dreier } 871d4b2b867SRoland Dreier 872d4b2b867SRoland Dreier static int spc_modesense_long_blockdesc(unsigned char *buf, u64 blocks, u32 block_size) 873d4b2b867SRoland Dreier { 874d4b2b867SRoland Dreier if (blocks <= 0xffffffff) 875d4b2b867SRoland Dreier return spc_modesense_blockdesc(buf + 3, blocks, block_size) + 3; 876d4b2b867SRoland Dreier 877d4b2b867SRoland Dreier *buf++ = 1; /* LONGLBA */ 878d4b2b867SRoland Dreier buf += 2; 879d4b2b867SRoland Dreier *buf++ = 16; 880d4b2b867SRoland Dreier put_unaligned_be64(blocks, buf); 881d4b2b867SRoland Dreier buf += 12; 882d4b2b867SRoland Dreier put_unaligned_be32(block_size, buf); 883d4b2b867SRoland Dreier 884d4b2b867SRoland Dreier return 17; 885d4b2b867SRoland Dreier } 886d4b2b867SRoland Dreier 887de103c93SChristoph Hellwig static sense_reason_t spc_emulate_modesense(struct se_cmd *cmd) 8881fd032eeSChristoph Hellwig { 8891fd032eeSChristoph Hellwig struct se_device *dev = cmd->se_dev; 8901fd032eeSChristoph Hellwig char *cdb = cmd->t_task_cdb; 891cab9609bSNicholas Bellinger unsigned char buf[SE_MODE_PAGE_BUF], *rbuf; 8921fd032eeSChristoph Hellwig int type = dev->transport->get_device_type(dev); 8931fd032eeSChristoph Hellwig int ten = (cmd->t_task_cdb[0] == MODE_SENSE_10); 894d4b2b867SRoland Dreier bool dbd = !!(cdb[1] & 0x08); 895d4b2b867SRoland Dreier bool llba = ten ? !!(cdb[1] & 0x10) : false; 896d4b2b867SRoland Dreier u8 pc = cdb[2] >> 6; 897d4b2b867SRoland Dreier u8 page = cdb[2] & 0x3f; 898d4b2b867SRoland Dreier u8 subpage = cdb[3]; 8991fd032eeSChristoph Hellwig int length = 0; 900d4b2b867SRoland Dreier int ret; 901d4b2b867SRoland Dreier int i; 9021fd032eeSChristoph Hellwig 903cab9609bSNicholas Bellinger memset(buf, 0, SE_MODE_PAGE_BUF); 904cab9609bSNicholas Bellinger 905fecae40aSNicholas Bellinger /* 906fecae40aSNicholas Bellinger * Skip over MODE DATA LENGTH + MEDIUM TYPE fields to byte 3 for 907fecae40aSNicholas Bellinger * MODE_SENSE_10 and byte 2 for MODE_SENSE (6). 908fecae40aSNicholas Bellinger */ 909fecae40aSNicholas Bellinger length = ten ? 3 : 2; 910d4b2b867SRoland Dreier 911d4b2b867SRoland Dreier /* DEVICE-SPECIFIC PARAMETER */ 912d4b2b867SRoland Dreier if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) || 913d4b2b867SRoland Dreier (cmd->se_deve && 914d4b2b867SRoland Dreier (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY))) 915d4b2b867SRoland Dreier spc_modesense_write_protect(&buf[length], type); 916d4b2b867SRoland Dreier 917d0c8b259SNicholas Bellinger if ((spc_check_dev_wce(dev)) && 918d4b2b867SRoland Dreier (dev->dev_attrib.emulate_fua_write > 0)) 919d4b2b867SRoland Dreier spc_modesense_dpofua(&buf[length], type); 920d4b2b867SRoland Dreier 921d4b2b867SRoland Dreier ++length; 922d4b2b867SRoland Dreier 923d4b2b867SRoland Dreier /* BLOCK DESCRIPTOR */ 924d4b2b867SRoland Dreier 925d4b2b867SRoland Dreier /* 926d4b2b867SRoland Dreier * For now we only include a block descriptor for disk (SBC) 927d4b2b867SRoland Dreier * devices; other command sets use a slightly different format. 928d4b2b867SRoland Dreier */ 929d4b2b867SRoland Dreier if (!dbd && type == TYPE_DISK) { 930d4b2b867SRoland Dreier u64 blocks = dev->transport->get_blocks(dev); 931d4b2b867SRoland Dreier u32 block_size = dev->dev_attrib.block_size; 9321fd032eeSChristoph Hellwig 9331fd032eeSChristoph Hellwig if (ten) { 934d4b2b867SRoland Dreier if (llba) { 935d4b2b867SRoland Dreier length += spc_modesense_long_blockdesc(&buf[length], 936d4b2b867SRoland Dreier blocks, block_size); 9371fd032eeSChristoph Hellwig } else { 938d4b2b867SRoland Dreier length += 3; 939d4b2b867SRoland Dreier length += spc_modesense_blockdesc(&buf[length], 940d4b2b867SRoland Dreier blocks, block_size); 941d4b2b867SRoland Dreier } 942d4b2b867SRoland Dreier } else { 943d4b2b867SRoland Dreier length += spc_modesense_blockdesc(&buf[length], blocks, 944d4b2b867SRoland Dreier block_size); 945d4b2b867SRoland Dreier } 946d4b2b867SRoland Dreier } else { 947d4b2b867SRoland Dreier if (ten) 948d4b2b867SRoland Dreier length += 4; 949d4b2b867SRoland Dreier else 950d4b2b867SRoland Dreier length += 1; 9511fd032eeSChristoph Hellwig } 9521fd032eeSChristoph Hellwig 953d4b2b867SRoland Dreier if (page == 0x3f) { 954d4b2b867SRoland Dreier if (subpage != 0x00 && subpage != 0xff) { 955de103c93SChristoph Hellwig pr_warn("MODE_SENSE: Invalid subpage code: 0x%02x\n", subpage); 956de103c93SChristoph Hellwig return TCM_INVALID_CDB_FIELD; 957d4b2b867SRoland Dreier } 958d4b2b867SRoland Dreier 959d4b2b867SRoland Dreier for (i = 0; i < ARRAY_SIZE(modesense_handlers); ++i) { 960d4b2b867SRoland Dreier /* 961d4b2b867SRoland Dreier * Tricky way to say all subpage 00h for 962d4b2b867SRoland Dreier * subpage==0, all subpages for subpage==0xff 963d4b2b867SRoland Dreier * (and we just checked above that those are 964d4b2b867SRoland Dreier * the only two possibilities). 965d4b2b867SRoland Dreier */ 966d4b2b867SRoland Dreier if ((modesense_handlers[i].subpage & ~subpage) == 0) { 967d4b2b867SRoland Dreier ret = modesense_handlers[i].emulate(dev, pc, &buf[length]); 968d4b2b867SRoland Dreier if (!ten && length + ret >= 255) 969d4b2b867SRoland Dreier break; 970d4b2b867SRoland Dreier length += ret; 971d4b2b867SRoland Dreier } 972d4b2b867SRoland Dreier } 973d4b2b867SRoland Dreier 974d4b2b867SRoland Dreier goto set_length; 975d4b2b867SRoland Dreier } 976d4b2b867SRoland Dreier 977d4b2b867SRoland Dreier for (i = 0; i < ARRAY_SIZE(modesense_handlers); ++i) 978d4b2b867SRoland Dreier if (modesense_handlers[i].page == page && 979d4b2b867SRoland Dreier modesense_handlers[i].subpage == subpage) { 980d4b2b867SRoland Dreier length += modesense_handlers[i].emulate(dev, pc, &buf[length]); 981d4b2b867SRoland Dreier goto set_length; 982d4b2b867SRoland Dreier } 983d4b2b867SRoland Dreier 984d4b2b867SRoland Dreier /* 985d4b2b867SRoland Dreier * We don't intend to implement: 986d4b2b867SRoland Dreier * - obsolete page 03h "format parameters" (checked by Solaris) 987d4b2b867SRoland Dreier */ 988d4b2b867SRoland Dreier if (page != 0x03) 989d4b2b867SRoland Dreier pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n", 990d4b2b867SRoland Dreier page, subpage); 991d4b2b867SRoland Dreier 992de103c93SChristoph Hellwig return TCM_UNKNOWN_MODE_PAGE; 993d4b2b867SRoland Dreier 994d4b2b867SRoland Dreier set_length: 995d4b2b867SRoland Dreier if (ten) 996d4b2b867SRoland Dreier put_unaligned_be16(length - 2, buf); 997d4b2b867SRoland Dreier else 998d4b2b867SRoland Dreier buf[0] = length - 1; 999d4b2b867SRoland Dreier 1000cab9609bSNicholas Bellinger rbuf = transport_kmap_data_sg(cmd); 1001cab9609bSNicholas Bellinger if (rbuf) { 1002cab9609bSNicholas Bellinger memcpy(rbuf, buf, min_t(u32, SE_MODE_PAGE_BUF, cmd->data_length)); 1003cab9609bSNicholas Bellinger transport_kunmap_data_sg(cmd); 1004d4b2b867SRoland Dreier } 1005d4b2b867SRoland Dreier 10061fd032eeSChristoph Hellwig target_complete_cmd(cmd, GOOD); 10071fd032eeSChristoph Hellwig return 0; 10081fd032eeSChristoph Hellwig } 10091fd032eeSChristoph Hellwig 1010de103c93SChristoph Hellwig static sense_reason_t spc_emulate_modeselect(struct se_cmd *cmd) 10113a3c5e4aSRoland Dreier { 10123a3c5e4aSRoland Dreier struct se_device *dev = cmd->se_dev; 10133a3c5e4aSRoland Dreier char *cdb = cmd->t_task_cdb; 10143a3c5e4aSRoland Dreier bool ten = cdb[0] == MODE_SELECT_10; 10153a3c5e4aSRoland Dreier int off = ten ? 8 : 4; 10163a3c5e4aSRoland Dreier bool pf = !!(cdb[1] & 0x10); 10173a3c5e4aSRoland Dreier u8 page, subpage; 10183a3c5e4aSRoland Dreier unsigned char *buf; 10193a3c5e4aSRoland Dreier unsigned char tbuf[SE_MODE_PAGE_BUF]; 10203a3c5e4aSRoland Dreier int length; 10213a3c5e4aSRoland Dreier int ret = 0; 10223a3c5e4aSRoland Dreier int i; 10233a3c5e4aSRoland Dreier 102471f41fe1SRoland Dreier if (!cmd->data_length) { 102571f41fe1SRoland Dreier target_complete_cmd(cmd, GOOD); 102671f41fe1SRoland Dreier return 0; 102771f41fe1SRoland Dreier } 102871f41fe1SRoland Dreier 102971f41fe1SRoland Dreier if (cmd->data_length < off + 2) 103071f41fe1SRoland Dreier return TCM_PARAMETER_LIST_LENGTH_ERROR; 103171f41fe1SRoland Dreier 10323a3c5e4aSRoland Dreier buf = transport_kmap_data_sg(cmd); 1033de103c93SChristoph Hellwig if (!buf) 1034de103c93SChristoph Hellwig return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 10353a3c5e4aSRoland Dreier 10363a3c5e4aSRoland Dreier if (!pf) { 1037de103c93SChristoph Hellwig ret = TCM_INVALID_CDB_FIELD; 10383a3c5e4aSRoland Dreier goto out; 10393a3c5e4aSRoland Dreier } 10403a3c5e4aSRoland Dreier 10413a3c5e4aSRoland Dreier page = buf[off] & 0x3f; 10423a3c5e4aSRoland Dreier subpage = buf[off] & 0x40 ? buf[off + 1] : 0; 10433a3c5e4aSRoland Dreier 10443a3c5e4aSRoland Dreier for (i = 0; i < ARRAY_SIZE(modesense_handlers); ++i) 10453a3c5e4aSRoland Dreier if (modesense_handlers[i].page == page && 10463a3c5e4aSRoland Dreier modesense_handlers[i].subpage == subpage) { 10473a3c5e4aSRoland Dreier memset(tbuf, 0, SE_MODE_PAGE_BUF); 10483a3c5e4aSRoland Dreier length = modesense_handlers[i].emulate(dev, 0, tbuf); 10493a3c5e4aSRoland Dreier goto check_contents; 10503a3c5e4aSRoland Dreier } 10513a3c5e4aSRoland Dreier 1052de103c93SChristoph Hellwig ret = TCM_UNKNOWN_MODE_PAGE; 10533a3c5e4aSRoland Dreier goto out; 10543a3c5e4aSRoland Dreier 10553a3c5e4aSRoland Dreier check_contents: 105671f41fe1SRoland Dreier if (cmd->data_length < off + length) { 105771f41fe1SRoland Dreier ret = TCM_PARAMETER_LIST_LENGTH_ERROR; 105871f41fe1SRoland Dreier goto out; 105971f41fe1SRoland Dreier } 106071f41fe1SRoland Dreier 1061de103c93SChristoph Hellwig if (memcmp(buf + off, tbuf, length)) 1062de103c93SChristoph Hellwig ret = TCM_INVALID_PARAMETER_LIST; 10633a3c5e4aSRoland Dreier 10643a3c5e4aSRoland Dreier out: 10653a3c5e4aSRoland Dreier transport_kunmap_data_sg(cmd); 10663a3c5e4aSRoland Dreier 10673a3c5e4aSRoland Dreier if (!ret) 10683a3c5e4aSRoland Dreier target_complete_cmd(cmd, GOOD); 10693a3c5e4aSRoland Dreier return ret; 10703a3c5e4aSRoland Dreier } 10713a3c5e4aSRoland Dreier 1072de103c93SChristoph Hellwig static sense_reason_t spc_emulate_request_sense(struct se_cmd *cmd) 10731fd032eeSChristoph Hellwig { 10741fd032eeSChristoph Hellwig unsigned char *cdb = cmd->t_task_cdb; 107532a8811fSPaolo Bonzini unsigned char *rbuf; 10761fd032eeSChristoph Hellwig u8 ua_asc = 0, ua_ascq = 0; 107732a8811fSPaolo Bonzini unsigned char buf[SE_SENSE_BUF]; 107832a8811fSPaolo Bonzini 107932a8811fSPaolo Bonzini memset(buf, 0, SE_SENSE_BUF); 10801fd032eeSChristoph Hellwig 10811fd032eeSChristoph Hellwig if (cdb[1] & 0x01) { 10821fd032eeSChristoph Hellwig pr_err("REQUEST_SENSE description emulation not" 10831fd032eeSChristoph Hellwig " supported\n"); 1084de103c93SChristoph Hellwig return TCM_INVALID_CDB_FIELD; 10851fd032eeSChristoph Hellwig } 10861fd032eeSChristoph Hellwig 108732a8811fSPaolo Bonzini rbuf = transport_kmap_data_sg(cmd); 1088de103c93SChristoph Hellwig if (!rbuf) 1089de103c93SChristoph Hellwig return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 1090de103c93SChristoph Hellwig 1091de103c93SChristoph Hellwig if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) { 10921fd032eeSChristoph Hellwig /* 10931fd032eeSChristoph Hellwig * CURRENT ERROR, UNIT ATTENTION 10941fd032eeSChristoph Hellwig */ 10951fd032eeSChristoph Hellwig buf[0] = 0x70; 10961fd032eeSChristoph Hellwig buf[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION; 10971fd032eeSChristoph Hellwig 10981fd032eeSChristoph Hellwig /* 10991fd032eeSChristoph Hellwig * The Additional Sense Code (ASC) from the UNIT ATTENTION 11001fd032eeSChristoph Hellwig */ 11011fd032eeSChristoph Hellwig buf[SPC_ASC_KEY_OFFSET] = ua_asc; 11021fd032eeSChristoph Hellwig buf[SPC_ASCQ_KEY_OFFSET] = ua_ascq; 11031fd032eeSChristoph Hellwig buf[7] = 0x0A; 11041fd032eeSChristoph Hellwig } else { 11051fd032eeSChristoph Hellwig /* 11061fd032eeSChristoph Hellwig * CURRENT ERROR, NO SENSE 11071fd032eeSChristoph Hellwig */ 11081fd032eeSChristoph Hellwig buf[0] = 0x70; 11091fd032eeSChristoph Hellwig buf[SPC_SENSE_KEY_OFFSET] = NO_SENSE; 11101fd032eeSChristoph Hellwig 11111fd032eeSChristoph Hellwig /* 11121fd032eeSChristoph Hellwig * NO ADDITIONAL SENSE INFORMATION 11131fd032eeSChristoph Hellwig */ 11141fd032eeSChristoph Hellwig buf[SPC_ASC_KEY_OFFSET] = 0x00; 11151fd032eeSChristoph Hellwig buf[7] = 0x0A; 11161fd032eeSChristoph Hellwig } 11171fd032eeSChristoph Hellwig 111832a8811fSPaolo Bonzini memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); 11191fd032eeSChristoph Hellwig transport_kunmap_data_sg(cmd); 112032a8811fSPaolo Bonzini 11211fd032eeSChristoph Hellwig target_complete_cmd(cmd, GOOD); 11221fd032eeSChristoph Hellwig return 0; 11231fd032eeSChristoph Hellwig } 11241fd032eeSChristoph Hellwig 1125de103c93SChristoph Hellwig sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd) 1126d1b1f805SChristoph Hellwig { 1127d1b1f805SChristoph Hellwig struct se_dev_entry *deve; 1128d1b1f805SChristoph Hellwig struct se_session *sess = cmd->se_sess; 1129d1b1f805SChristoph Hellwig unsigned char *buf; 1130d1b1f805SChristoph Hellwig u32 lun_count = 0, offset = 8, i; 1131d1b1f805SChristoph Hellwig 1132d1b1f805SChristoph Hellwig if (cmd->data_length < 16) { 1133d1b1f805SChristoph Hellwig pr_warn("REPORT LUNS allocation length %u too small\n", 1134d1b1f805SChristoph Hellwig cmd->data_length); 1135de103c93SChristoph Hellwig return TCM_INVALID_CDB_FIELD; 1136d1b1f805SChristoph Hellwig } 1137d1b1f805SChristoph Hellwig 1138d1b1f805SChristoph Hellwig buf = transport_kmap_data_sg(cmd); 1139d1b1f805SChristoph Hellwig if (!buf) 1140de103c93SChristoph Hellwig return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 1141d1b1f805SChristoph Hellwig 1142d1b1f805SChristoph Hellwig /* 1143d1b1f805SChristoph Hellwig * If no struct se_session pointer is present, this struct se_cmd is 1144d1b1f805SChristoph Hellwig * coming via a target_core_mod PASSTHROUGH op, and not through 1145d1b1f805SChristoph Hellwig * a $FABRIC_MOD. In that case, report LUN=0 only. 1146d1b1f805SChristoph Hellwig */ 1147d1b1f805SChristoph Hellwig if (!sess) { 1148d1b1f805SChristoph Hellwig int_to_scsilun(0, (struct scsi_lun *)&buf[offset]); 1149d1b1f805SChristoph Hellwig lun_count = 1; 1150d1b1f805SChristoph Hellwig goto done; 1151d1b1f805SChristoph Hellwig } 1152d1b1f805SChristoph Hellwig 1153d1b1f805SChristoph Hellwig spin_lock_irq(&sess->se_node_acl->device_list_lock); 1154d1b1f805SChristoph Hellwig for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { 1155d1b1f805SChristoph Hellwig deve = sess->se_node_acl->device_list[i]; 1156d1b1f805SChristoph Hellwig if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS)) 1157d1b1f805SChristoph Hellwig continue; 1158d1b1f805SChristoph Hellwig /* 1159d1b1f805SChristoph Hellwig * We determine the correct LUN LIST LENGTH even once we 1160d1b1f805SChristoph Hellwig * have reached the initial allocation length. 1161d1b1f805SChristoph Hellwig * See SPC2-R20 7.19. 1162d1b1f805SChristoph Hellwig */ 1163d1b1f805SChristoph Hellwig lun_count++; 1164d1b1f805SChristoph Hellwig if ((offset + 8) > cmd->data_length) 1165d1b1f805SChristoph Hellwig continue; 1166d1b1f805SChristoph Hellwig 1167d1b1f805SChristoph Hellwig int_to_scsilun(deve->mapped_lun, (struct scsi_lun *)&buf[offset]); 1168d1b1f805SChristoph Hellwig offset += 8; 1169d1b1f805SChristoph Hellwig } 1170d1b1f805SChristoph Hellwig spin_unlock_irq(&sess->se_node_acl->device_list_lock); 1171d1b1f805SChristoph Hellwig 1172d1b1f805SChristoph Hellwig /* 1173d1b1f805SChristoph Hellwig * See SPC3 r07, page 159. 1174d1b1f805SChristoph Hellwig */ 1175d1b1f805SChristoph Hellwig done: 1176d1b1f805SChristoph Hellwig lun_count *= 8; 1177d1b1f805SChristoph Hellwig buf[0] = ((lun_count >> 24) & 0xff); 1178d1b1f805SChristoph Hellwig buf[1] = ((lun_count >> 16) & 0xff); 1179d1b1f805SChristoph Hellwig buf[2] = ((lun_count >> 8) & 0xff); 1180d1b1f805SChristoph Hellwig buf[3] = (lun_count & 0xff); 1181d1b1f805SChristoph Hellwig transport_kunmap_data_sg(cmd); 1182d1b1f805SChristoph Hellwig 1183d1b1f805SChristoph Hellwig target_complete_cmd(cmd, GOOD); 1184d1b1f805SChristoph Hellwig return 0; 1185d1b1f805SChristoph Hellwig } 11868de530a5SChristoph Hellwig EXPORT_SYMBOL(spc_emulate_report_luns); 1187d1b1f805SChristoph Hellwig 1188de103c93SChristoph Hellwig static sense_reason_t 1189de103c93SChristoph Hellwig spc_emulate_testunitready(struct se_cmd *cmd) 11901fd032eeSChristoph Hellwig { 11911fd032eeSChristoph Hellwig target_complete_cmd(cmd, GOOD); 11921fd032eeSChristoph Hellwig return 0; 11931fd032eeSChristoph Hellwig } 11941fd032eeSChristoph Hellwig 1195de103c93SChristoph Hellwig sense_reason_t 1196de103c93SChristoph Hellwig spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) 119788455ec4SChristoph Hellwig { 1198eba2ca45SNicholas Bellinger struct se_device *dev = cmd->se_dev; 119988455ec4SChristoph Hellwig unsigned char *cdb = cmd->t_task_cdb; 120088455ec4SChristoph Hellwig 120188455ec4SChristoph Hellwig switch (cdb[0]) { 120288455ec4SChristoph Hellwig case MODE_SELECT: 120388455ec4SChristoph Hellwig *size = cdb[4]; 12043a3c5e4aSRoland Dreier cmd->execute_cmd = spc_emulate_modeselect; 120588455ec4SChristoph Hellwig break; 120688455ec4SChristoph Hellwig case MODE_SELECT_10: 120788455ec4SChristoph Hellwig *size = (cdb[7] << 8) + cdb[8]; 12083a3c5e4aSRoland Dreier cmd->execute_cmd = spc_emulate_modeselect; 120988455ec4SChristoph Hellwig break; 121088455ec4SChristoph Hellwig case MODE_SENSE: 121188455ec4SChristoph Hellwig *size = cdb[4]; 12121fd032eeSChristoph Hellwig cmd->execute_cmd = spc_emulate_modesense; 121388455ec4SChristoph Hellwig break; 121488455ec4SChristoph Hellwig case MODE_SENSE_10: 121588455ec4SChristoph Hellwig *size = (cdb[7] << 8) + cdb[8]; 12161fd032eeSChristoph Hellwig cmd->execute_cmd = spc_emulate_modesense; 121788455ec4SChristoph Hellwig break; 121888455ec4SChristoph Hellwig case LOG_SELECT: 121988455ec4SChristoph Hellwig case LOG_SENSE: 122088455ec4SChristoph Hellwig *size = (cdb[7] << 8) + cdb[8]; 122188455ec4SChristoph Hellwig break; 122288455ec4SChristoph Hellwig case PERSISTENT_RESERVE_IN: 122388455ec4SChristoph Hellwig *size = (cdb[7] << 8) + cdb[8]; 1224d977f437SChristoph Hellwig cmd->execute_cmd = target_scsi3_emulate_pr_in; 122588455ec4SChristoph Hellwig break; 122688455ec4SChristoph Hellwig case PERSISTENT_RESERVE_OUT: 122788455ec4SChristoph Hellwig *size = (cdb[7] << 8) + cdb[8]; 1228d977f437SChristoph Hellwig cmd->execute_cmd = target_scsi3_emulate_pr_out; 122988455ec4SChristoph Hellwig break; 123088455ec4SChristoph Hellwig case RELEASE: 123188455ec4SChristoph Hellwig case RELEASE_10: 123288455ec4SChristoph Hellwig if (cdb[0] == RELEASE_10) 123388455ec4SChristoph Hellwig *size = (cdb[7] << 8) | cdb[8]; 123488455ec4SChristoph Hellwig else 123588455ec4SChristoph Hellwig *size = cmd->data_length; 123688455ec4SChristoph Hellwig 123788455ec4SChristoph Hellwig cmd->execute_cmd = target_scsi2_reservation_release; 123888455ec4SChristoph Hellwig break; 123988455ec4SChristoph Hellwig case RESERVE: 124088455ec4SChristoph Hellwig case RESERVE_10: 124188455ec4SChristoph Hellwig /* 124288455ec4SChristoph Hellwig * The SPC-2 RESERVE does not contain a size in the SCSI CDB. 124388455ec4SChristoph Hellwig * Assume the passthrough or $FABRIC_MOD will tell us about it. 124488455ec4SChristoph Hellwig */ 124588455ec4SChristoph Hellwig if (cdb[0] == RESERVE_10) 124688455ec4SChristoph Hellwig *size = (cdb[7] << 8) | cdb[8]; 124788455ec4SChristoph Hellwig else 124888455ec4SChristoph Hellwig *size = cmd->data_length; 124988455ec4SChristoph Hellwig 125088455ec4SChristoph Hellwig cmd->execute_cmd = target_scsi2_reservation_reserve; 125188455ec4SChristoph Hellwig break; 125288455ec4SChristoph Hellwig case REQUEST_SENSE: 125388455ec4SChristoph Hellwig *size = cdb[4]; 12541fd032eeSChristoph Hellwig cmd->execute_cmd = spc_emulate_request_sense; 125588455ec4SChristoph Hellwig break; 125688455ec4SChristoph Hellwig case INQUIRY: 125788455ec4SChristoph Hellwig *size = (cdb[3] << 8) + cdb[4]; 125888455ec4SChristoph Hellwig 125988455ec4SChristoph Hellwig /* 126088455ec4SChristoph Hellwig * Do implict HEAD_OF_QUEUE processing for INQUIRY. 126188455ec4SChristoph Hellwig * See spc4r17 section 5.3 126288455ec4SChristoph Hellwig */ 126388455ec4SChristoph Hellwig cmd->sam_task_attr = MSG_HEAD_TAG; 12641fd032eeSChristoph Hellwig cmd->execute_cmd = spc_emulate_inquiry; 126588455ec4SChristoph Hellwig break; 126688455ec4SChristoph Hellwig case SECURITY_PROTOCOL_IN: 126788455ec4SChristoph Hellwig case SECURITY_PROTOCOL_OUT: 126888455ec4SChristoph Hellwig *size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; 126988455ec4SChristoph Hellwig break; 127088455ec4SChristoph Hellwig case EXTENDED_COPY: 127104b1b795SNicholas Bellinger *size = get_unaligned_be32(&cdb[10]); 127204b1b795SNicholas Bellinger cmd->execute_cmd = target_do_xcopy; 127304b1b795SNicholas Bellinger break; 127488455ec4SChristoph Hellwig case RECEIVE_COPY_RESULTS: 127504b1b795SNicholas Bellinger *size = get_unaligned_be32(&cdb[10]); 127604b1b795SNicholas Bellinger cmd->execute_cmd = target_do_receive_copy_results; 127704b1b795SNicholas Bellinger break; 127804b1b795SNicholas Bellinger case READ_ATTRIBUTE: 127988455ec4SChristoph Hellwig case WRITE_ATTRIBUTE: 128088455ec4SChristoph Hellwig *size = (cdb[10] << 24) | (cdb[11] << 16) | 128188455ec4SChristoph Hellwig (cdb[12] << 8) | cdb[13]; 128288455ec4SChristoph Hellwig break; 128388455ec4SChristoph Hellwig case RECEIVE_DIAGNOSTIC: 128488455ec4SChristoph Hellwig case SEND_DIAGNOSTIC: 128588455ec4SChristoph Hellwig *size = (cdb[3] << 8) | cdb[4]; 128688455ec4SChristoph Hellwig break; 128788455ec4SChristoph Hellwig case WRITE_BUFFER: 128888455ec4SChristoph Hellwig *size = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8]; 128988455ec4SChristoph Hellwig break; 129088455ec4SChristoph Hellwig case REPORT_LUNS: 1291d1b1f805SChristoph Hellwig cmd->execute_cmd = spc_emulate_report_luns; 129288455ec4SChristoph Hellwig *size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; 129388455ec4SChristoph Hellwig /* 129488455ec4SChristoph Hellwig * Do implict HEAD_OF_QUEUE processing for REPORT_LUNS 129588455ec4SChristoph Hellwig * See spc4r17 section 5.3 129688455ec4SChristoph Hellwig */ 129788455ec4SChristoph Hellwig cmd->sam_task_attr = MSG_HEAD_TAG; 129888455ec4SChristoph Hellwig break; 129988455ec4SChristoph Hellwig case TEST_UNIT_READY: 13001fd032eeSChristoph Hellwig cmd->execute_cmd = spc_emulate_testunitready; 1301d6e0175cSChristoph Hellwig *size = 0; 130288455ec4SChristoph Hellwig break; 1303eba2ca45SNicholas Bellinger case MAINTENANCE_IN: 1304eba2ca45SNicholas Bellinger if (dev->transport->get_device_type(dev) != TYPE_ROM) { 1305eba2ca45SNicholas Bellinger /* 1306eba2ca45SNicholas Bellinger * MAINTENANCE_IN from SCC-2 1307eba2ca45SNicholas Bellinger * Check for emulated MI_REPORT_TARGET_PGS 1308eba2ca45SNicholas Bellinger */ 1309c87fbd56SChristoph Hellwig if ((cdb[1] & 0x1f) == MI_REPORT_TARGET_PGS) { 1310eba2ca45SNicholas Bellinger cmd->execute_cmd = 1311eba2ca45SNicholas Bellinger target_emulate_report_target_port_groups; 1312eba2ca45SNicholas Bellinger } 1313eba2ca45SNicholas Bellinger *size = get_unaligned_be32(&cdb[6]); 1314eba2ca45SNicholas Bellinger } else { 1315eba2ca45SNicholas Bellinger /* 1316eba2ca45SNicholas Bellinger * GPCMD_SEND_KEY from multi media commands 1317eba2ca45SNicholas Bellinger */ 1318eba2ca45SNicholas Bellinger *size = get_unaligned_be16(&cdb[8]); 1319eba2ca45SNicholas Bellinger } 1320eba2ca45SNicholas Bellinger break; 1321eba2ca45SNicholas Bellinger case MAINTENANCE_OUT: 1322eba2ca45SNicholas Bellinger if (dev->transport->get_device_type(dev) != TYPE_ROM) { 1323eba2ca45SNicholas Bellinger /* 1324eba2ca45SNicholas Bellinger * MAINTENANCE_OUT from SCC-2 1325eba2ca45SNicholas Bellinger * Check for emulated MO_SET_TARGET_PGS. 1326eba2ca45SNicholas Bellinger */ 1327c87fbd56SChristoph Hellwig if (cdb[1] == MO_SET_TARGET_PGS) { 1328eba2ca45SNicholas Bellinger cmd->execute_cmd = 1329eba2ca45SNicholas Bellinger target_emulate_set_target_port_groups; 1330eba2ca45SNicholas Bellinger } 1331eba2ca45SNicholas Bellinger *size = get_unaligned_be32(&cdb[6]); 1332eba2ca45SNicholas Bellinger } else { 1333eba2ca45SNicholas Bellinger /* 1334eba2ca45SNicholas Bellinger * GPCMD_SEND_KEY from multi media commands 1335eba2ca45SNicholas Bellinger */ 1336eba2ca45SNicholas Bellinger *size = get_unaligned_be16(&cdb[8]); 1337eba2ca45SNicholas Bellinger } 1338eba2ca45SNicholas Bellinger break; 133988455ec4SChristoph Hellwig default: 134088455ec4SChristoph Hellwig pr_warn("TARGET_CORE[%s]: Unsupported SCSI Opcode" 134188455ec4SChristoph Hellwig " 0x%02x, sending CHECK_CONDITION.\n", 134288455ec4SChristoph Hellwig cmd->se_tfo->get_fabric_name(), cdb[0]); 1343de103c93SChristoph Hellwig return TCM_UNSUPPORTED_SCSI_OPCODE; 134488455ec4SChristoph Hellwig } 134588455ec4SChristoph Hellwig 134688455ec4SChristoph Hellwig return 0; 134788455ec4SChristoph Hellwig } 134888455ec4SChristoph Hellwig EXPORT_SYMBOL(spc_parse_cdb); 1349