188455ec4SChristoph Hellwig /* 288455ec4SChristoph Hellwig * SCSI Primary Commands (SPC) parsing and emulation. 388455ec4SChristoph Hellwig * 488455ec4SChristoph Hellwig * Copyright (c) 2002, 2003, 2004, 2005 PyX Technologies, Inc. 588455ec4SChristoph Hellwig * Copyright (c) 2005, 2006, 2007 SBE, Inc. 688455ec4SChristoph Hellwig * Copyright (c) 2007-2010 Rising Tide Systems 788455ec4SChristoph Hellwig * Copyright (c) 2008-2010 Linux-iSCSI.org 888455ec4SChristoph Hellwig * 988455ec4SChristoph Hellwig * Nicholas A. Bellinger <nab@kernel.org> 1088455ec4SChristoph Hellwig * 1188455ec4SChristoph Hellwig * This program is free software; you can redistribute it and/or modify 1288455ec4SChristoph Hellwig * it under the terms of the GNU General Public License as published by 1388455ec4SChristoph Hellwig * the Free Software Foundation; either version 2 of the License, or 1488455ec4SChristoph Hellwig * (at your option) any later version. 1588455ec4SChristoph Hellwig * 1688455ec4SChristoph Hellwig * This program is distributed in the hope that it will be useful, 1788455ec4SChristoph Hellwig * but WITHOUT ANY WARRANTY; without even the implied warranty of 1888455ec4SChristoph Hellwig * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1988455ec4SChristoph Hellwig * GNU General Public License for more details. 2088455ec4SChristoph Hellwig * 2188455ec4SChristoph Hellwig * You should have received a copy of the GNU General Public License 2288455ec4SChristoph Hellwig * along with this program; if not, write to the Free Software 2388455ec4SChristoph Hellwig * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 2488455ec4SChristoph Hellwig */ 2588455ec4SChristoph Hellwig 2688455ec4SChristoph Hellwig #include <linux/kernel.h> 2788455ec4SChristoph Hellwig #include <linux/module.h> 2888455ec4SChristoph Hellwig #include <asm/unaligned.h> 2988455ec4SChristoph Hellwig 3088455ec4SChristoph Hellwig #include <scsi/scsi.h> 3188455ec4SChristoph Hellwig #include <scsi/scsi_tcq.h> 3288455ec4SChristoph Hellwig 3388455ec4SChristoph Hellwig #include <target/target_core_base.h> 3488455ec4SChristoph Hellwig #include <target/target_core_backend.h> 3588455ec4SChristoph Hellwig #include <target/target_core_fabric.h> 3688455ec4SChristoph Hellwig 3788455ec4SChristoph Hellwig #include "target_core_internal.h" 38eba2ca45SNicholas Bellinger #include "target_core_alua.h" 3988455ec4SChristoph Hellwig #include "target_core_pr.h" 4088455ec4SChristoph Hellwig #include "target_core_ua.h" 4188455ec4SChristoph Hellwig 4288455ec4SChristoph Hellwig 431fd032eeSChristoph Hellwig static void spc_fill_alua_data(struct se_port *port, unsigned char *buf) 441fd032eeSChristoph Hellwig { 451fd032eeSChristoph Hellwig struct t10_alua_tg_pt_gp *tg_pt_gp; 461fd032eeSChristoph Hellwig struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; 471fd032eeSChristoph Hellwig 481fd032eeSChristoph Hellwig /* 491fd032eeSChristoph Hellwig * Set SCCS for MAINTENANCE_IN + REPORT_TARGET_PORT_GROUPS. 501fd032eeSChristoph Hellwig */ 511fd032eeSChristoph Hellwig buf[5] = 0x80; 521fd032eeSChristoph Hellwig 531fd032eeSChristoph Hellwig /* 541fd032eeSChristoph Hellwig * Set TPGS field for explict and/or implict ALUA access type 551fd032eeSChristoph Hellwig * and opteration. 561fd032eeSChristoph Hellwig * 571fd032eeSChristoph Hellwig * See spc4r17 section 6.4.2 Table 135 581fd032eeSChristoph Hellwig */ 591fd032eeSChristoph Hellwig if (!port) 601fd032eeSChristoph Hellwig return; 611fd032eeSChristoph Hellwig tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; 621fd032eeSChristoph Hellwig if (!tg_pt_gp_mem) 631fd032eeSChristoph Hellwig return; 641fd032eeSChristoph Hellwig 651fd032eeSChristoph Hellwig spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); 661fd032eeSChristoph Hellwig tg_pt_gp = tg_pt_gp_mem->tg_pt_gp; 671fd032eeSChristoph Hellwig if (tg_pt_gp) 681fd032eeSChristoph Hellwig buf[5] |= tg_pt_gp->tg_pt_gp_alua_access_type; 691fd032eeSChristoph Hellwig spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); 701fd032eeSChristoph Hellwig } 711fd032eeSChristoph Hellwig 721fd032eeSChristoph Hellwig static int spc_emulate_inquiry_std(struct se_cmd *cmd, char *buf) 731fd032eeSChristoph Hellwig { 741fd032eeSChristoph Hellwig struct se_lun *lun = cmd->se_lun; 751fd032eeSChristoph Hellwig struct se_device *dev = cmd->se_dev; 761fd032eeSChristoph Hellwig 771fd032eeSChristoph Hellwig /* Set RMB (removable media) for tape devices */ 781fd032eeSChristoph Hellwig if (dev->transport->get_device_type(dev) == TYPE_TAPE) 791fd032eeSChristoph Hellwig buf[1] = 0x80; 801fd032eeSChristoph Hellwig 8148c2567dSChristoph Hellwig buf[2] = 0x05; /* SPC-3 */ 821fd032eeSChristoph Hellwig 831fd032eeSChristoph Hellwig /* 841fd032eeSChristoph Hellwig * NORMACA and HISUP = 0, RESPONSE DATA FORMAT = 2 851fd032eeSChristoph Hellwig * 861fd032eeSChristoph Hellwig * SPC4 says: 871fd032eeSChristoph Hellwig * A RESPONSE DATA FORMAT field set to 2h indicates that the 881fd032eeSChristoph Hellwig * standard INQUIRY data is in the format defined in this 891fd032eeSChristoph Hellwig * standard. Response data format values less than 2h are 901fd032eeSChristoph Hellwig * obsolete. Response data format values greater than 2h are 911fd032eeSChristoph Hellwig * reserved. 921fd032eeSChristoph Hellwig */ 931fd032eeSChristoph Hellwig buf[3] = 2; 941fd032eeSChristoph Hellwig 951fd032eeSChristoph Hellwig /* 961fd032eeSChristoph Hellwig * Enable SCCS and TPGS fields for Emulated ALUA 971fd032eeSChristoph Hellwig */ 981fd032eeSChristoph Hellwig spc_fill_alua_data(lun->lun_sep, buf); 991fd032eeSChristoph Hellwig 1001fd032eeSChristoph Hellwig buf[7] = 0x2; /* CmdQue=1 */ 1011fd032eeSChristoph Hellwig 1021fd032eeSChristoph Hellwig snprintf(&buf[8], 8, "LIO-ORG"); 1030fd97ccfSChristoph Hellwig snprintf(&buf[16], 16, "%s", dev->t10_wwn.model); 1040fd97ccfSChristoph Hellwig snprintf(&buf[32], 4, "%s", dev->t10_wwn.revision); 1051fd032eeSChristoph Hellwig buf[4] = 31; /* Set additional length to 31 */ 1061fd032eeSChristoph Hellwig 1071fd032eeSChristoph Hellwig return 0; 1081fd032eeSChristoph Hellwig } 1091fd032eeSChristoph Hellwig 1101fd032eeSChristoph Hellwig /* unit serial number */ 1111fd032eeSChristoph Hellwig static int spc_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf) 1121fd032eeSChristoph Hellwig { 1131fd032eeSChristoph Hellwig struct se_device *dev = cmd->se_dev; 1141fd032eeSChristoph Hellwig u16 len = 0; 1151fd032eeSChristoph Hellwig 1160fd97ccfSChristoph Hellwig if (dev->dev_flags & DF_EMULATED_VPD_UNIT_SERIAL) { 1171fd032eeSChristoph Hellwig u32 unit_serial_len; 1181fd032eeSChristoph Hellwig 1190fd97ccfSChristoph Hellwig unit_serial_len = strlen(dev->t10_wwn.unit_serial); 1201fd032eeSChristoph Hellwig unit_serial_len++; /* For NULL Terminator */ 1211fd032eeSChristoph Hellwig 1220fd97ccfSChristoph Hellwig len += sprintf(&buf[4], "%s", dev->t10_wwn.unit_serial); 1231fd032eeSChristoph Hellwig len++; /* Extra Byte for NULL Terminator */ 1241fd032eeSChristoph Hellwig buf[3] = len; 1251fd032eeSChristoph Hellwig } 1261fd032eeSChristoph Hellwig return 0; 1271fd032eeSChristoph Hellwig } 1281fd032eeSChristoph Hellwig 1291fd032eeSChristoph Hellwig static void spc_parse_naa_6h_vendor_specific(struct se_device *dev, 1301fd032eeSChristoph Hellwig unsigned char *buf) 1311fd032eeSChristoph Hellwig { 1320fd97ccfSChristoph Hellwig unsigned char *p = &dev->t10_wwn.unit_serial[0]; 1331fd032eeSChristoph Hellwig int cnt; 1341fd032eeSChristoph Hellwig bool next = true; 1351fd032eeSChristoph Hellwig 1361fd032eeSChristoph Hellwig /* 1371fd032eeSChristoph Hellwig * Generate up to 36 bits of VENDOR SPECIFIC IDENTIFIER starting on 1381fd032eeSChristoph Hellwig * byte 3 bit 3-0 for NAA IEEE Registered Extended DESIGNATOR field 1391fd032eeSChristoph Hellwig * format, followed by 64 bits of VENDOR SPECIFIC IDENTIFIER EXTENSION 1401fd032eeSChristoph Hellwig * to complete the payload. These are based from VPD=0x80 PRODUCT SERIAL 1411fd032eeSChristoph Hellwig * NUMBER set via vpd_unit_serial in target_core_configfs.c to ensure 1421fd032eeSChristoph Hellwig * per device uniqeness. 1431fd032eeSChristoph Hellwig */ 1441fd032eeSChristoph Hellwig for (cnt = 0; *p && cnt < 13; p++) { 1451fd032eeSChristoph Hellwig int val = hex_to_bin(*p); 1461fd032eeSChristoph Hellwig 1471fd032eeSChristoph Hellwig if (val < 0) 1481fd032eeSChristoph Hellwig continue; 1491fd032eeSChristoph Hellwig 1501fd032eeSChristoph Hellwig if (next) { 1511fd032eeSChristoph Hellwig next = false; 1521fd032eeSChristoph Hellwig buf[cnt++] |= val; 1531fd032eeSChristoph Hellwig } else { 1541fd032eeSChristoph Hellwig next = true; 1551fd032eeSChristoph Hellwig buf[cnt] = val << 4; 1561fd032eeSChristoph Hellwig } 1571fd032eeSChristoph Hellwig } 1581fd032eeSChristoph Hellwig } 1591fd032eeSChristoph Hellwig 1601fd032eeSChristoph Hellwig /* 1611fd032eeSChristoph Hellwig * Device identification VPD, for a complete list of 1621fd032eeSChristoph Hellwig * DESIGNATOR TYPEs see spc4r17 Table 459. 1631fd032eeSChristoph Hellwig */ 1641fd032eeSChristoph Hellwig static int spc_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf) 1651fd032eeSChristoph Hellwig { 1661fd032eeSChristoph Hellwig struct se_device *dev = cmd->se_dev; 1671fd032eeSChristoph Hellwig struct se_lun *lun = cmd->se_lun; 1681fd032eeSChristoph Hellwig struct se_port *port = NULL; 1691fd032eeSChristoph Hellwig struct se_portal_group *tpg = NULL; 1701fd032eeSChristoph Hellwig struct t10_alua_lu_gp_member *lu_gp_mem; 1711fd032eeSChristoph Hellwig struct t10_alua_tg_pt_gp *tg_pt_gp; 1721fd032eeSChristoph Hellwig struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; 1730fd97ccfSChristoph Hellwig unsigned char *prod = &dev->t10_wwn.model[0]; 1741fd032eeSChristoph Hellwig u32 prod_len; 1751fd032eeSChristoph Hellwig u32 unit_serial_len, off = 0; 1761fd032eeSChristoph Hellwig u16 len = 0, id_len; 1771fd032eeSChristoph Hellwig 1781fd032eeSChristoph Hellwig off = 4; 1791fd032eeSChristoph Hellwig 1801fd032eeSChristoph Hellwig /* 1811fd032eeSChristoph Hellwig * NAA IEEE Registered Extended Assigned designator format, see 1821fd032eeSChristoph Hellwig * spc4r17 section 7.7.3.6.5 1831fd032eeSChristoph Hellwig * 1841fd032eeSChristoph Hellwig * We depend upon a target_core_mod/ConfigFS provided 1851fd032eeSChristoph Hellwig * /sys/kernel/config/target/core/$HBA/$DEV/wwn/vpd_unit_serial 1861fd032eeSChristoph Hellwig * value in order to return the NAA id. 1871fd032eeSChristoph Hellwig */ 1880fd97ccfSChristoph Hellwig if (!(dev->dev_flags & DF_EMULATED_VPD_UNIT_SERIAL)) 1891fd032eeSChristoph Hellwig goto check_t10_vend_desc; 1901fd032eeSChristoph Hellwig 1911fd032eeSChristoph Hellwig /* CODE SET == Binary */ 1921fd032eeSChristoph Hellwig buf[off++] = 0x1; 1931fd032eeSChristoph Hellwig 1941fd032eeSChristoph Hellwig /* Set ASSOCIATION == addressed logical unit: 0)b */ 1951fd032eeSChristoph Hellwig buf[off] = 0x00; 1961fd032eeSChristoph Hellwig 1971fd032eeSChristoph Hellwig /* Identifier/Designator type == NAA identifier */ 1981fd032eeSChristoph Hellwig buf[off++] |= 0x3; 1991fd032eeSChristoph Hellwig off++; 2001fd032eeSChristoph Hellwig 2011fd032eeSChristoph Hellwig /* Identifier/Designator length */ 2021fd032eeSChristoph Hellwig buf[off++] = 0x10; 2031fd032eeSChristoph Hellwig 2041fd032eeSChristoph Hellwig /* 2051fd032eeSChristoph Hellwig * Start NAA IEEE Registered Extended Identifier/Designator 2061fd032eeSChristoph Hellwig */ 2071fd032eeSChristoph Hellwig buf[off++] = (0x6 << 4); 2081fd032eeSChristoph Hellwig 2091fd032eeSChristoph Hellwig /* 2101fd032eeSChristoph Hellwig * Use OpenFabrics IEEE Company ID: 00 14 05 2111fd032eeSChristoph Hellwig */ 2121fd032eeSChristoph Hellwig buf[off++] = 0x01; 2131fd032eeSChristoph Hellwig buf[off++] = 0x40; 2141fd032eeSChristoph Hellwig buf[off] = (0x5 << 4); 2151fd032eeSChristoph Hellwig 2161fd032eeSChristoph Hellwig /* 2171fd032eeSChristoph Hellwig * Return ConfigFS Unit Serial Number information for 2181fd032eeSChristoph Hellwig * VENDOR_SPECIFIC_IDENTIFIER and 2191fd032eeSChristoph Hellwig * VENDOR_SPECIFIC_IDENTIFIER_EXTENTION 2201fd032eeSChristoph Hellwig */ 2211fd032eeSChristoph Hellwig spc_parse_naa_6h_vendor_specific(dev, &buf[off]); 2221fd032eeSChristoph Hellwig 2231fd032eeSChristoph Hellwig len = 20; 2241fd032eeSChristoph Hellwig off = (len + 4); 2251fd032eeSChristoph Hellwig 2261fd032eeSChristoph Hellwig check_t10_vend_desc: 2271fd032eeSChristoph Hellwig /* 2281fd032eeSChristoph Hellwig * T10 Vendor Identifier Page, see spc4r17 section 7.7.3.4 2291fd032eeSChristoph Hellwig */ 2301fd032eeSChristoph Hellwig id_len = 8; /* For Vendor field */ 2311fd032eeSChristoph Hellwig prod_len = 4; /* For VPD Header */ 2321fd032eeSChristoph Hellwig prod_len += 8; /* For Vendor field */ 2331fd032eeSChristoph Hellwig prod_len += strlen(prod); 2341fd032eeSChristoph Hellwig prod_len++; /* For : */ 2351fd032eeSChristoph Hellwig 2360fd97ccfSChristoph Hellwig if (dev->dev_flags & DF_EMULATED_VPD_UNIT_SERIAL) { 2370fd97ccfSChristoph Hellwig unit_serial_len = strlen(&dev->t10_wwn.unit_serial[0]); 2381fd032eeSChristoph Hellwig unit_serial_len++; /* For NULL Terminator */ 2391fd032eeSChristoph Hellwig 2401fd032eeSChristoph Hellwig id_len += sprintf(&buf[off+12], "%s:%s", prod, 2410fd97ccfSChristoph Hellwig &dev->t10_wwn.unit_serial[0]); 2421fd032eeSChristoph Hellwig } 2431fd032eeSChristoph Hellwig buf[off] = 0x2; /* ASCII */ 2441fd032eeSChristoph Hellwig buf[off+1] = 0x1; /* T10 Vendor ID */ 2451fd032eeSChristoph Hellwig buf[off+2] = 0x0; 2461fd032eeSChristoph Hellwig memcpy(&buf[off+4], "LIO-ORG", 8); 2471fd032eeSChristoph Hellwig /* Extra Byte for NULL Terminator */ 2481fd032eeSChristoph Hellwig id_len++; 2491fd032eeSChristoph Hellwig /* Identifier Length */ 2501fd032eeSChristoph Hellwig buf[off+3] = id_len; 2511fd032eeSChristoph Hellwig /* Header size for Designation descriptor */ 2521fd032eeSChristoph Hellwig len += (id_len + 4); 2531fd032eeSChristoph Hellwig off += (id_len + 4); 2541fd032eeSChristoph Hellwig /* 2551fd032eeSChristoph Hellwig * struct se_port is only set for INQUIRY VPD=1 through $FABRIC_MOD 2561fd032eeSChristoph Hellwig */ 2571fd032eeSChristoph Hellwig port = lun->lun_sep; 2581fd032eeSChristoph Hellwig if (port) { 2591fd032eeSChristoph Hellwig struct t10_alua_lu_gp *lu_gp; 2601fd032eeSChristoph Hellwig u32 padding, scsi_name_len; 2611fd032eeSChristoph Hellwig u16 lu_gp_id = 0; 2621fd032eeSChristoph Hellwig u16 tg_pt_gp_id = 0; 2631fd032eeSChristoph Hellwig u16 tpgt; 2641fd032eeSChristoph Hellwig 2651fd032eeSChristoph Hellwig tpg = port->sep_tpg; 2661fd032eeSChristoph Hellwig /* 2671fd032eeSChristoph Hellwig * Relative target port identifer, see spc4r17 2681fd032eeSChristoph Hellwig * section 7.7.3.7 2691fd032eeSChristoph Hellwig * 2701fd032eeSChristoph Hellwig * Get the PROTOCOL IDENTIFIER as defined by spc4r17 2711fd032eeSChristoph Hellwig * section 7.5.1 Table 362 2721fd032eeSChristoph Hellwig */ 2731fd032eeSChristoph Hellwig buf[off] = 2741fd032eeSChristoph Hellwig (tpg->se_tpg_tfo->get_fabric_proto_ident(tpg) << 4); 2751fd032eeSChristoph Hellwig buf[off++] |= 0x1; /* CODE SET == Binary */ 2761fd032eeSChristoph Hellwig buf[off] = 0x80; /* Set PIV=1 */ 2771fd032eeSChristoph Hellwig /* Set ASSOCIATION == target port: 01b */ 2781fd032eeSChristoph Hellwig buf[off] |= 0x10; 2791fd032eeSChristoph Hellwig /* DESIGNATOR TYPE == Relative target port identifer */ 2801fd032eeSChristoph Hellwig buf[off++] |= 0x4; 2811fd032eeSChristoph Hellwig off++; /* Skip over Reserved */ 2821fd032eeSChristoph Hellwig buf[off++] = 4; /* DESIGNATOR LENGTH */ 2831fd032eeSChristoph Hellwig /* Skip over Obsolete field in RTPI payload 2841fd032eeSChristoph Hellwig * in Table 472 */ 2851fd032eeSChristoph Hellwig off += 2; 2861fd032eeSChristoph Hellwig buf[off++] = ((port->sep_rtpi >> 8) & 0xff); 2871fd032eeSChristoph Hellwig buf[off++] = (port->sep_rtpi & 0xff); 2881fd032eeSChristoph Hellwig len += 8; /* Header size + Designation descriptor */ 2891fd032eeSChristoph Hellwig /* 2901fd032eeSChristoph Hellwig * Target port group identifier, see spc4r17 2911fd032eeSChristoph Hellwig * section 7.7.3.8 2921fd032eeSChristoph Hellwig * 2931fd032eeSChristoph Hellwig * Get the PROTOCOL IDENTIFIER as defined by spc4r17 2941fd032eeSChristoph Hellwig * section 7.5.1 Table 362 2951fd032eeSChristoph Hellwig */ 2961fd032eeSChristoph Hellwig tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem; 2971fd032eeSChristoph Hellwig if (!tg_pt_gp_mem) 2981fd032eeSChristoph Hellwig goto check_lu_gp; 2991fd032eeSChristoph Hellwig 3001fd032eeSChristoph Hellwig spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); 3011fd032eeSChristoph Hellwig tg_pt_gp = tg_pt_gp_mem->tg_pt_gp; 3021fd032eeSChristoph Hellwig if (!tg_pt_gp) { 3031fd032eeSChristoph Hellwig spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); 3041fd032eeSChristoph Hellwig goto check_lu_gp; 3051fd032eeSChristoph Hellwig } 3061fd032eeSChristoph Hellwig tg_pt_gp_id = tg_pt_gp->tg_pt_gp_id; 3071fd032eeSChristoph Hellwig spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); 3081fd032eeSChristoph Hellwig 3091fd032eeSChristoph Hellwig buf[off] = 3101fd032eeSChristoph Hellwig (tpg->se_tpg_tfo->get_fabric_proto_ident(tpg) << 4); 3111fd032eeSChristoph Hellwig buf[off++] |= 0x1; /* CODE SET == Binary */ 3121fd032eeSChristoph Hellwig buf[off] = 0x80; /* Set PIV=1 */ 3131fd032eeSChristoph Hellwig /* Set ASSOCIATION == target port: 01b */ 3141fd032eeSChristoph Hellwig buf[off] |= 0x10; 3151fd032eeSChristoph Hellwig /* DESIGNATOR TYPE == Target port group identifier */ 3161fd032eeSChristoph Hellwig buf[off++] |= 0x5; 3171fd032eeSChristoph Hellwig off++; /* Skip over Reserved */ 3181fd032eeSChristoph Hellwig buf[off++] = 4; /* DESIGNATOR LENGTH */ 3191fd032eeSChristoph Hellwig off += 2; /* Skip over Reserved Field */ 3201fd032eeSChristoph Hellwig buf[off++] = ((tg_pt_gp_id >> 8) & 0xff); 3211fd032eeSChristoph Hellwig buf[off++] = (tg_pt_gp_id & 0xff); 3221fd032eeSChristoph Hellwig len += 8; /* Header size + Designation descriptor */ 3231fd032eeSChristoph Hellwig /* 3241fd032eeSChristoph Hellwig * Logical Unit Group identifier, see spc4r17 3251fd032eeSChristoph Hellwig * section 7.7.3.8 3261fd032eeSChristoph Hellwig */ 3271fd032eeSChristoph Hellwig check_lu_gp: 3281fd032eeSChristoph Hellwig lu_gp_mem = dev->dev_alua_lu_gp_mem; 3291fd032eeSChristoph Hellwig if (!lu_gp_mem) 3301fd032eeSChristoph Hellwig goto check_scsi_name; 3311fd032eeSChristoph Hellwig 3321fd032eeSChristoph Hellwig spin_lock(&lu_gp_mem->lu_gp_mem_lock); 3331fd032eeSChristoph Hellwig lu_gp = lu_gp_mem->lu_gp; 3341fd032eeSChristoph Hellwig if (!lu_gp) { 3351fd032eeSChristoph Hellwig spin_unlock(&lu_gp_mem->lu_gp_mem_lock); 3361fd032eeSChristoph Hellwig goto check_scsi_name; 3371fd032eeSChristoph Hellwig } 3381fd032eeSChristoph Hellwig lu_gp_id = lu_gp->lu_gp_id; 3391fd032eeSChristoph Hellwig spin_unlock(&lu_gp_mem->lu_gp_mem_lock); 3401fd032eeSChristoph Hellwig 3411fd032eeSChristoph Hellwig buf[off++] |= 0x1; /* CODE SET == Binary */ 3421fd032eeSChristoph Hellwig /* DESIGNATOR TYPE == Logical Unit Group identifier */ 3431fd032eeSChristoph Hellwig buf[off++] |= 0x6; 3441fd032eeSChristoph Hellwig off++; /* Skip over Reserved */ 3451fd032eeSChristoph Hellwig buf[off++] = 4; /* DESIGNATOR LENGTH */ 3461fd032eeSChristoph Hellwig off += 2; /* Skip over Reserved Field */ 3471fd032eeSChristoph Hellwig buf[off++] = ((lu_gp_id >> 8) & 0xff); 3481fd032eeSChristoph Hellwig buf[off++] = (lu_gp_id & 0xff); 3491fd032eeSChristoph Hellwig len += 8; /* Header size + Designation descriptor */ 3501fd032eeSChristoph Hellwig /* 3511fd032eeSChristoph Hellwig * SCSI name string designator, see spc4r17 3521fd032eeSChristoph Hellwig * section 7.7.3.11 3531fd032eeSChristoph Hellwig * 3541fd032eeSChristoph Hellwig * Get the PROTOCOL IDENTIFIER as defined by spc4r17 3551fd032eeSChristoph Hellwig * section 7.5.1 Table 362 3561fd032eeSChristoph Hellwig */ 3571fd032eeSChristoph Hellwig check_scsi_name: 3581fd032eeSChristoph Hellwig scsi_name_len = strlen(tpg->se_tpg_tfo->tpg_get_wwn(tpg)); 3591fd032eeSChristoph Hellwig /* UTF-8 ",t,0x<16-bit TPGT>" + NULL Terminator */ 3601fd032eeSChristoph Hellwig scsi_name_len += 10; 3611fd032eeSChristoph Hellwig /* Check for 4-byte padding */ 3621fd032eeSChristoph Hellwig padding = ((-scsi_name_len) & 3); 3631fd032eeSChristoph Hellwig if (padding != 0) 3641fd032eeSChristoph Hellwig scsi_name_len += padding; 3651fd032eeSChristoph Hellwig /* Header size + Designation descriptor */ 3661fd032eeSChristoph Hellwig scsi_name_len += 4; 3671fd032eeSChristoph Hellwig 3681fd032eeSChristoph Hellwig buf[off] = 3691fd032eeSChristoph Hellwig (tpg->se_tpg_tfo->get_fabric_proto_ident(tpg) << 4); 3701fd032eeSChristoph Hellwig buf[off++] |= 0x3; /* CODE SET == UTF-8 */ 3711fd032eeSChristoph Hellwig buf[off] = 0x80; /* Set PIV=1 */ 3721fd032eeSChristoph Hellwig /* Set ASSOCIATION == target port: 01b */ 3731fd032eeSChristoph Hellwig buf[off] |= 0x10; 3741fd032eeSChristoph Hellwig /* DESIGNATOR TYPE == SCSI name string */ 3751fd032eeSChristoph Hellwig buf[off++] |= 0x8; 3761fd032eeSChristoph Hellwig off += 2; /* Skip over Reserved and length */ 3771fd032eeSChristoph Hellwig /* 3781fd032eeSChristoph Hellwig * SCSI name string identifer containing, $FABRIC_MOD 3791fd032eeSChristoph Hellwig * dependent information. For LIO-Target and iSCSI 3801fd032eeSChristoph Hellwig * Target Port, this means "<iSCSI name>,t,0x<TPGT> in 3811fd032eeSChristoph Hellwig * UTF-8 encoding. 3821fd032eeSChristoph Hellwig */ 3831fd032eeSChristoph Hellwig tpgt = tpg->se_tpg_tfo->tpg_get_tag(tpg); 3841fd032eeSChristoph Hellwig scsi_name_len = sprintf(&buf[off], "%s,t,0x%04x", 3851fd032eeSChristoph Hellwig tpg->se_tpg_tfo->tpg_get_wwn(tpg), tpgt); 3861fd032eeSChristoph Hellwig scsi_name_len += 1 /* Include NULL terminator */; 3871fd032eeSChristoph Hellwig /* 3881fd032eeSChristoph Hellwig * The null-terminated, null-padded (see 4.4.2) SCSI 3891fd032eeSChristoph Hellwig * NAME STRING field contains a UTF-8 format string. 3901fd032eeSChristoph Hellwig * The number of bytes in the SCSI NAME STRING field 3911fd032eeSChristoph Hellwig * (i.e., the value in the DESIGNATOR LENGTH field) 3921fd032eeSChristoph Hellwig * shall be no larger than 256 and shall be a multiple 3931fd032eeSChristoph Hellwig * of four. 3941fd032eeSChristoph Hellwig */ 3951fd032eeSChristoph Hellwig if (padding) 3961fd032eeSChristoph Hellwig scsi_name_len += padding; 3971fd032eeSChristoph Hellwig 3981fd032eeSChristoph Hellwig buf[off-1] = scsi_name_len; 3991fd032eeSChristoph Hellwig off += scsi_name_len; 4001fd032eeSChristoph Hellwig /* Header size + Designation descriptor */ 4011fd032eeSChristoph Hellwig len += (scsi_name_len + 4); 4021fd032eeSChristoph Hellwig } 4031fd032eeSChristoph Hellwig buf[2] = ((len >> 8) & 0xff); 4041fd032eeSChristoph Hellwig buf[3] = (len & 0xff); /* Page Length for VPD 0x83 */ 4051fd032eeSChristoph Hellwig return 0; 4061fd032eeSChristoph Hellwig } 4071fd032eeSChristoph Hellwig 4081fd032eeSChristoph Hellwig /* Extended INQUIRY Data VPD Page */ 4091fd032eeSChristoph Hellwig static int spc_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf) 4101fd032eeSChristoph Hellwig { 4111fd032eeSChristoph Hellwig buf[3] = 0x3c; 4121fd032eeSChristoph Hellwig /* Set HEADSUP, ORDSUP, SIMPSUP */ 4131fd032eeSChristoph Hellwig buf[5] = 0x07; 4141fd032eeSChristoph Hellwig 4151fd032eeSChristoph Hellwig /* If WriteCache emulation is enabled, set V_SUP */ 4160fd97ccfSChristoph Hellwig if (cmd->se_dev->dev_attrib.emulate_write_cache > 0) 4171fd032eeSChristoph Hellwig buf[6] = 0x01; 4181fd032eeSChristoph Hellwig return 0; 4191fd032eeSChristoph Hellwig } 4201fd032eeSChristoph Hellwig 4211fd032eeSChristoph Hellwig /* Block Limits VPD page */ 4221fd032eeSChristoph Hellwig static int spc_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) 4231fd032eeSChristoph Hellwig { 4241fd032eeSChristoph Hellwig struct se_device *dev = cmd->se_dev; 4251fd032eeSChristoph Hellwig u32 max_sectors; 4261fd032eeSChristoph Hellwig int have_tp = 0; 4271fd032eeSChristoph Hellwig 4281fd032eeSChristoph Hellwig /* 4291fd032eeSChristoph Hellwig * Following spc3r22 section 6.5.3 Block Limits VPD page, when 4301fd032eeSChristoph Hellwig * emulate_tpu=1 or emulate_tpws=1 we will be expect a 4311fd032eeSChristoph Hellwig * different page length for Thin Provisioning. 4321fd032eeSChristoph Hellwig */ 4330fd97ccfSChristoph Hellwig if (dev->dev_attrib.emulate_tpu || dev->dev_attrib.emulate_tpws) 4341fd032eeSChristoph Hellwig have_tp = 1; 4351fd032eeSChristoph Hellwig 4361fd032eeSChristoph Hellwig buf[0] = dev->transport->get_device_type(dev); 4371fd032eeSChristoph Hellwig buf[3] = have_tp ? 0x3c : 0x10; 4381fd032eeSChristoph Hellwig 4391fd032eeSChristoph Hellwig /* Set WSNZ to 1 */ 4401fd032eeSChristoph Hellwig buf[4] = 0x01; 4411fd032eeSChristoph Hellwig 4421fd032eeSChristoph Hellwig /* 4431fd032eeSChristoph Hellwig * Set OPTIMAL TRANSFER LENGTH GRANULARITY 4441fd032eeSChristoph Hellwig */ 4451fd032eeSChristoph Hellwig put_unaligned_be16(1, &buf[6]); 4461fd032eeSChristoph Hellwig 4471fd032eeSChristoph Hellwig /* 4481fd032eeSChristoph Hellwig * Set MAXIMUM TRANSFER LENGTH 4491fd032eeSChristoph Hellwig */ 4500fd97ccfSChristoph Hellwig max_sectors = min(dev->dev_attrib.fabric_max_sectors, 4510fd97ccfSChristoph Hellwig dev->dev_attrib.hw_max_sectors); 4521fd032eeSChristoph Hellwig put_unaligned_be32(max_sectors, &buf[8]); 4531fd032eeSChristoph Hellwig 4541fd032eeSChristoph Hellwig /* 4551fd032eeSChristoph Hellwig * Set OPTIMAL TRANSFER LENGTH 4561fd032eeSChristoph Hellwig */ 4570fd97ccfSChristoph Hellwig put_unaligned_be32(dev->dev_attrib.optimal_sectors, &buf[12]); 4581fd032eeSChristoph Hellwig 4591fd032eeSChristoph Hellwig /* 4601fd032eeSChristoph Hellwig * Exit now if we don't support TP. 4611fd032eeSChristoph Hellwig */ 4621fd032eeSChristoph Hellwig if (!have_tp) 4631fd032eeSChristoph Hellwig return 0; 4641fd032eeSChristoph Hellwig 4651fd032eeSChristoph Hellwig /* 4661fd032eeSChristoph Hellwig * Set MAXIMUM UNMAP LBA COUNT 4671fd032eeSChristoph Hellwig */ 4680fd97ccfSChristoph Hellwig put_unaligned_be32(dev->dev_attrib.max_unmap_lba_count, &buf[20]); 4691fd032eeSChristoph Hellwig 4701fd032eeSChristoph Hellwig /* 4711fd032eeSChristoph Hellwig * Set MAXIMUM UNMAP BLOCK DESCRIPTOR COUNT 4721fd032eeSChristoph Hellwig */ 4730fd97ccfSChristoph Hellwig put_unaligned_be32(dev->dev_attrib.max_unmap_block_desc_count, 4741fd032eeSChristoph Hellwig &buf[24]); 4751fd032eeSChristoph Hellwig 4761fd032eeSChristoph Hellwig /* 4771fd032eeSChristoph Hellwig * Set OPTIMAL UNMAP GRANULARITY 4781fd032eeSChristoph Hellwig */ 4790fd97ccfSChristoph Hellwig put_unaligned_be32(dev->dev_attrib.unmap_granularity, &buf[28]); 4801fd032eeSChristoph Hellwig 4811fd032eeSChristoph Hellwig /* 4821fd032eeSChristoph Hellwig * UNMAP GRANULARITY ALIGNMENT 4831fd032eeSChristoph Hellwig */ 4840fd97ccfSChristoph Hellwig put_unaligned_be32(dev->dev_attrib.unmap_granularity_alignment, 4851fd032eeSChristoph Hellwig &buf[32]); 4860fd97ccfSChristoph Hellwig if (dev->dev_attrib.unmap_granularity_alignment != 0) 4871fd032eeSChristoph Hellwig buf[32] |= 0x80; /* Set the UGAVALID bit */ 4881fd032eeSChristoph Hellwig 4891fd032eeSChristoph Hellwig return 0; 4901fd032eeSChristoph Hellwig } 4911fd032eeSChristoph Hellwig 4921fd032eeSChristoph Hellwig /* Block Device Characteristics VPD page */ 4931fd032eeSChristoph Hellwig static int spc_emulate_evpd_b1(struct se_cmd *cmd, unsigned char *buf) 4941fd032eeSChristoph Hellwig { 4951fd032eeSChristoph Hellwig struct se_device *dev = cmd->se_dev; 4961fd032eeSChristoph Hellwig 4971fd032eeSChristoph Hellwig buf[0] = dev->transport->get_device_type(dev); 4981fd032eeSChristoph Hellwig buf[3] = 0x3c; 4990fd97ccfSChristoph Hellwig buf[5] = dev->dev_attrib.is_nonrot ? 1 : 0; 5001fd032eeSChristoph Hellwig 5011fd032eeSChristoph Hellwig return 0; 5021fd032eeSChristoph Hellwig } 5031fd032eeSChristoph Hellwig 5041fd032eeSChristoph Hellwig /* Thin Provisioning VPD */ 5051fd032eeSChristoph Hellwig static int spc_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf) 5061fd032eeSChristoph Hellwig { 5071fd032eeSChristoph Hellwig struct se_device *dev = cmd->se_dev; 5081fd032eeSChristoph Hellwig 5091fd032eeSChristoph Hellwig /* 5101fd032eeSChristoph Hellwig * From spc3r22 section 6.5.4 Thin Provisioning VPD page: 5111fd032eeSChristoph Hellwig * 5121fd032eeSChristoph Hellwig * The PAGE LENGTH field is defined in SPC-4. If the DP bit is set to 5131fd032eeSChristoph Hellwig * zero, then the page length shall be set to 0004h. If the DP bit 5141fd032eeSChristoph Hellwig * is set to one, then the page length shall be set to the value 5151fd032eeSChristoph Hellwig * defined in table 162. 5161fd032eeSChristoph Hellwig */ 5171fd032eeSChristoph Hellwig buf[0] = dev->transport->get_device_type(dev); 5181fd032eeSChristoph Hellwig 5191fd032eeSChristoph Hellwig /* 5201fd032eeSChristoph Hellwig * Set Hardcoded length mentioned above for DP=0 5211fd032eeSChristoph Hellwig */ 5221fd032eeSChristoph Hellwig put_unaligned_be16(0x0004, &buf[2]); 5231fd032eeSChristoph Hellwig 5241fd032eeSChristoph Hellwig /* 5251fd032eeSChristoph Hellwig * The THRESHOLD EXPONENT field indicates the threshold set size in 5261fd032eeSChristoph Hellwig * LBAs as a power of 2 (i.e., the threshold set size is equal to 5271fd032eeSChristoph Hellwig * 2(threshold exponent)). 5281fd032eeSChristoph Hellwig * 5291fd032eeSChristoph Hellwig * Note that this is currently set to 0x00 as mkp says it will be 5301fd032eeSChristoph Hellwig * changing again. We can enable this once it has settled in T10 5311fd032eeSChristoph Hellwig * and is actually used by Linux/SCSI ML code. 5321fd032eeSChristoph Hellwig */ 5331fd032eeSChristoph Hellwig buf[4] = 0x00; 5341fd032eeSChristoph Hellwig 5351fd032eeSChristoph Hellwig /* 5361fd032eeSChristoph Hellwig * A TPU bit set to one indicates that the device server supports 5371fd032eeSChristoph Hellwig * the UNMAP command (see 5.25). A TPU bit set to zero indicates 5381fd032eeSChristoph Hellwig * that the device server does not support the UNMAP command. 5391fd032eeSChristoph Hellwig */ 5400fd97ccfSChristoph Hellwig if (dev->dev_attrib.emulate_tpu != 0) 5411fd032eeSChristoph Hellwig buf[5] = 0x80; 5421fd032eeSChristoph Hellwig 5431fd032eeSChristoph Hellwig /* 5441fd032eeSChristoph Hellwig * A TPWS bit set to one indicates that the device server supports 5451fd032eeSChristoph Hellwig * the use of the WRITE SAME (16) command (see 5.42) to unmap LBAs. 5461fd032eeSChristoph Hellwig * A TPWS bit set to zero indicates that the device server does not 5471fd032eeSChristoph Hellwig * support the use of the WRITE SAME (16) command to unmap LBAs. 5481fd032eeSChristoph Hellwig */ 5490fd97ccfSChristoph Hellwig if (dev->dev_attrib.emulate_tpws != 0) 5501fd032eeSChristoph Hellwig buf[5] |= 0x40; 5511fd032eeSChristoph Hellwig 5521fd032eeSChristoph Hellwig return 0; 5531fd032eeSChristoph Hellwig } 5541fd032eeSChristoph Hellwig 5551fd032eeSChristoph Hellwig static int spc_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf); 5561fd032eeSChristoph Hellwig 5571fd032eeSChristoph Hellwig static struct { 5581fd032eeSChristoph Hellwig uint8_t page; 5591fd032eeSChristoph Hellwig int (*emulate)(struct se_cmd *, unsigned char *); 5601fd032eeSChristoph Hellwig } evpd_handlers[] = { 5611fd032eeSChristoph Hellwig { .page = 0x00, .emulate = spc_emulate_evpd_00 }, 5621fd032eeSChristoph Hellwig { .page = 0x80, .emulate = spc_emulate_evpd_80 }, 5631fd032eeSChristoph Hellwig { .page = 0x83, .emulate = spc_emulate_evpd_83 }, 5641fd032eeSChristoph Hellwig { .page = 0x86, .emulate = spc_emulate_evpd_86 }, 5651fd032eeSChristoph Hellwig { .page = 0xb0, .emulate = spc_emulate_evpd_b0 }, 5661fd032eeSChristoph Hellwig { .page = 0xb1, .emulate = spc_emulate_evpd_b1 }, 5671fd032eeSChristoph Hellwig { .page = 0xb2, .emulate = spc_emulate_evpd_b2 }, 5681fd032eeSChristoph Hellwig }; 5691fd032eeSChristoph Hellwig 5701fd032eeSChristoph Hellwig /* supported vital product data pages */ 5711fd032eeSChristoph Hellwig static int spc_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf) 5721fd032eeSChristoph Hellwig { 5731fd032eeSChristoph Hellwig int p; 5741fd032eeSChristoph Hellwig 5751fd032eeSChristoph Hellwig /* 5761fd032eeSChristoph Hellwig * Only report the INQUIRY EVPD=1 pages after a valid NAA 5771fd032eeSChristoph Hellwig * Registered Extended LUN WWN has been set via ConfigFS 5781fd032eeSChristoph Hellwig * during device creation/restart. 5791fd032eeSChristoph Hellwig */ 5800fd97ccfSChristoph Hellwig if (cmd->se_dev->dev_flags & DF_EMULATED_VPD_UNIT_SERIAL) { 5811fd032eeSChristoph Hellwig buf[3] = ARRAY_SIZE(evpd_handlers); 5821fd032eeSChristoph Hellwig for (p = 0; p < ARRAY_SIZE(evpd_handlers); ++p) 5831fd032eeSChristoph Hellwig buf[p + 4] = evpd_handlers[p].page; 5841fd032eeSChristoph Hellwig } 5851fd032eeSChristoph Hellwig 5861fd032eeSChristoph Hellwig return 0; 5871fd032eeSChristoph Hellwig } 5881fd032eeSChristoph Hellwig 5891fd032eeSChristoph Hellwig static int spc_emulate_inquiry(struct se_cmd *cmd) 5901fd032eeSChristoph Hellwig { 5911fd032eeSChristoph Hellwig struct se_device *dev = cmd->se_dev; 5921fd032eeSChristoph Hellwig struct se_portal_group *tpg = cmd->se_lun->lun_sep->sep_tpg; 593ffe7b0e9SPaolo Bonzini unsigned char *rbuf; 5941fd032eeSChristoph Hellwig unsigned char *cdb = cmd->t_task_cdb; 595ffe7b0e9SPaolo Bonzini unsigned char buf[SE_INQUIRY_BUF]; 5961fd032eeSChristoph Hellwig int p, ret; 5971fd032eeSChristoph Hellwig 598dea5f099SNicholas Bellinger memset(buf, 0, SE_INQUIRY_BUF); 599dea5f099SNicholas Bellinger 6001fd032eeSChristoph Hellwig if (dev == tpg->tpg_virt_lun0.lun_se_dev) 6011fd032eeSChristoph Hellwig buf[0] = 0x3f; /* Not connected */ 6021fd032eeSChristoph Hellwig else 6031fd032eeSChristoph Hellwig buf[0] = dev->transport->get_device_type(dev); 6041fd032eeSChristoph Hellwig 6051fd032eeSChristoph Hellwig if (!(cdb[1] & 0x1)) { 6061fd032eeSChristoph Hellwig if (cdb[2]) { 6071fd032eeSChristoph Hellwig pr_err("INQUIRY with EVPD==0 but PAGE CODE=%02x\n", 6081fd032eeSChristoph Hellwig cdb[2]); 6091fd032eeSChristoph Hellwig cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; 6101fd032eeSChristoph Hellwig ret = -EINVAL; 6111fd032eeSChristoph Hellwig goto out; 6121fd032eeSChristoph Hellwig } 6131fd032eeSChristoph Hellwig 6141fd032eeSChristoph Hellwig ret = spc_emulate_inquiry_std(cmd, buf); 6151fd032eeSChristoph Hellwig goto out; 6161fd032eeSChristoph Hellwig } 6171fd032eeSChristoph Hellwig 6181fd032eeSChristoph Hellwig for (p = 0; p < ARRAY_SIZE(evpd_handlers); ++p) { 6191fd032eeSChristoph Hellwig if (cdb[2] == evpd_handlers[p].page) { 6201fd032eeSChristoph Hellwig buf[1] = cdb[2]; 6211fd032eeSChristoph Hellwig ret = evpd_handlers[p].emulate(cmd, buf); 6221fd032eeSChristoph Hellwig goto out; 6231fd032eeSChristoph Hellwig } 6241fd032eeSChristoph Hellwig } 6251fd032eeSChristoph Hellwig 6261fd032eeSChristoph Hellwig pr_err("Unknown VPD Code: 0x%02x\n", cdb[2]); 6271fd032eeSChristoph Hellwig cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; 6281fd032eeSChristoph Hellwig ret = -EINVAL; 6291fd032eeSChristoph Hellwig 6301fd032eeSChristoph Hellwig out: 631ffe7b0e9SPaolo Bonzini rbuf = transport_kmap_data_sg(cmd); 632ffe7b0e9SPaolo Bonzini if (rbuf) { 633ffe7b0e9SPaolo Bonzini memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); 6341fd032eeSChristoph Hellwig transport_kunmap_data_sg(cmd); 635ffe7b0e9SPaolo Bonzini } 6361fd032eeSChristoph Hellwig 6371fd032eeSChristoph Hellwig if (!ret) 6381fd032eeSChristoph Hellwig target_complete_cmd(cmd, GOOD); 6391fd032eeSChristoph Hellwig return ret; 6401fd032eeSChristoph Hellwig } 6411fd032eeSChristoph Hellwig 642d4b2b867SRoland Dreier static int spc_modesense_rwrecovery(struct se_device *dev, u8 pc, u8 *p) 6431fd032eeSChristoph Hellwig { 6441fd032eeSChristoph Hellwig p[0] = 0x01; 6451fd032eeSChristoph Hellwig p[1] = 0x0a; 6461fd032eeSChristoph Hellwig 647d4b2b867SRoland Dreier /* No changeable values for now */ 648d4b2b867SRoland Dreier if (pc == 1) 649d4b2b867SRoland Dreier goto out; 650d4b2b867SRoland Dreier 651d4b2b867SRoland Dreier out: 6521fd032eeSChristoph Hellwig return 12; 6531fd032eeSChristoph Hellwig } 6541fd032eeSChristoph Hellwig 655d4b2b867SRoland Dreier static int spc_modesense_control(struct se_device *dev, u8 pc, u8 *p) 6561fd032eeSChristoph Hellwig { 6571fd032eeSChristoph Hellwig p[0] = 0x0a; 6581fd032eeSChristoph Hellwig p[1] = 0x0a; 659d4b2b867SRoland Dreier 660d4b2b867SRoland Dreier /* No changeable values for now */ 661d4b2b867SRoland Dreier if (pc == 1) 662d4b2b867SRoland Dreier goto out; 663d4b2b867SRoland Dreier 6641fd032eeSChristoph Hellwig p[2] = 2; 6651fd032eeSChristoph Hellwig /* 6661fd032eeSChristoph Hellwig * From spc4r23, 7.4.7 Control mode page 6671fd032eeSChristoph Hellwig * 6681fd032eeSChristoph Hellwig * The QUEUE ALGORITHM MODIFIER field (see table 368) specifies 6691fd032eeSChristoph Hellwig * restrictions on the algorithm used for reordering commands 6701fd032eeSChristoph Hellwig * having the SIMPLE task attribute (see SAM-4). 6711fd032eeSChristoph Hellwig * 6721fd032eeSChristoph Hellwig * Table 368 -- QUEUE ALGORITHM MODIFIER field 6731fd032eeSChristoph Hellwig * Code Description 6741fd032eeSChristoph Hellwig * 0h Restricted reordering 6751fd032eeSChristoph Hellwig * 1h Unrestricted reordering allowed 6761fd032eeSChristoph Hellwig * 2h to 7h Reserved 6771fd032eeSChristoph Hellwig * 8h to Fh Vendor specific 6781fd032eeSChristoph Hellwig * 6791fd032eeSChristoph Hellwig * A value of zero in the QUEUE ALGORITHM MODIFIER field specifies that 6801fd032eeSChristoph Hellwig * the device server shall order the processing sequence of commands 6811fd032eeSChristoph Hellwig * having the SIMPLE task attribute such that data integrity is maintained 6821fd032eeSChristoph Hellwig * for that I_T nexus (i.e., if the transmission of new SCSI transport protocol 6831fd032eeSChristoph Hellwig * requests is halted at any time, the final value of all data observable 6841fd032eeSChristoph Hellwig * on the medium shall be the same as if all the commands had been processed 6851fd032eeSChristoph Hellwig * with the ORDERED task attribute). 6861fd032eeSChristoph Hellwig * 6871fd032eeSChristoph Hellwig * A value of one in the QUEUE ALGORITHM MODIFIER field specifies that the 6881fd032eeSChristoph Hellwig * device server may reorder the processing sequence of commands having the 6891fd032eeSChristoph Hellwig * SIMPLE task attribute in any manner. Any data integrity exposures related to 6901fd032eeSChristoph Hellwig * command sequence order shall be explicitly handled by the application client 6911fd032eeSChristoph Hellwig * through the selection of appropriate ommands and task attributes. 6921fd032eeSChristoph Hellwig */ 6930fd97ccfSChristoph Hellwig p[3] = (dev->dev_attrib.emulate_rest_reord == 1) ? 0x00 : 0x10; 6941fd032eeSChristoph Hellwig /* 6951fd032eeSChristoph Hellwig * From spc4r17, section 7.4.6 Control mode Page 6961fd032eeSChristoph Hellwig * 6971fd032eeSChristoph Hellwig * Unit Attention interlocks control (UN_INTLCK_CTRL) to code 00b 6981fd032eeSChristoph Hellwig * 6991fd032eeSChristoph Hellwig * 00b: The logical unit shall clear any unit attention condition 7001fd032eeSChristoph Hellwig * reported in the same I_T_L_Q nexus transaction as a CHECK CONDITION 7011fd032eeSChristoph Hellwig * status and shall not establish a unit attention condition when a com- 7021fd032eeSChristoph Hellwig * mand is completed with BUSY, TASK SET FULL, or RESERVATION CONFLICT 7031fd032eeSChristoph Hellwig * status. 7041fd032eeSChristoph Hellwig * 7051fd032eeSChristoph Hellwig * 10b: The logical unit shall not clear any unit attention condition 7061fd032eeSChristoph Hellwig * reported in the same I_T_L_Q nexus transaction as a CHECK CONDITION 7071fd032eeSChristoph Hellwig * status and shall not establish a unit attention condition when 7081fd032eeSChristoph Hellwig * a command is completed with BUSY, TASK SET FULL, or RESERVATION 7091fd032eeSChristoph Hellwig * CONFLICT status. 7101fd032eeSChristoph Hellwig * 7111fd032eeSChristoph Hellwig * 11b a The logical unit shall not clear any unit attention condition 7121fd032eeSChristoph Hellwig * reported in the same I_T_L_Q nexus transaction as a CHECK CONDITION 7131fd032eeSChristoph Hellwig * status and shall establish a unit attention condition for the 7141fd032eeSChristoph Hellwig * initiator port associated with the I_T nexus on which the BUSY, 7151fd032eeSChristoph Hellwig * TASK SET FULL, or RESERVATION CONFLICT status is being returned. 7161fd032eeSChristoph Hellwig * Depending on the status, the additional sense code shall be set to 7171fd032eeSChristoph Hellwig * PREVIOUS BUSY STATUS, PREVIOUS TASK SET FULL STATUS, or PREVIOUS 7181fd032eeSChristoph Hellwig * RESERVATION CONFLICT STATUS. Until it is cleared by a REQUEST SENSE 7191fd032eeSChristoph Hellwig * command, a unit attention condition shall be established only once 7201fd032eeSChristoph Hellwig * for a BUSY, TASK SET FULL, or RESERVATION CONFLICT status regardless 7211fd032eeSChristoph Hellwig * to the number of commands completed with one of those status codes. 7221fd032eeSChristoph Hellwig */ 7230fd97ccfSChristoph Hellwig p[4] = (dev->dev_attrib.emulate_ua_intlck_ctrl == 2) ? 0x30 : 7240fd97ccfSChristoph Hellwig (dev->dev_attrib.emulate_ua_intlck_ctrl == 1) ? 0x20 : 0x00; 7251fd032eeSChristoph Hellwig /* 7261fd032eeSChristoph Hellwig * From spc4r17, section 7.4.6 Control mode Page 7271fd032eeSChristoph Hellwig * 7281fd032eeSChristoph Hellwig * Task Aborted Status (TAS) bit set to zero. 7291fd032eeSChristoph Hellwig * 7301fd032eeSChristoph Hellwig * A task aborted status (TAS) bit set to zero specifies that aborted 7311fd032eeSChristoph Hellwig * tasks shall be terminated by the device server without any response 7321fd032eeSChristoph Hellwig * to the application client. A TAS bit set to one specifies that tasks 7331fd032eeSChristoph Hellwig * aborted by the actions of an I_T nexus other than the I_T nexus on 7341fd032eeSChristoph Hellwig * which the command was received shall be completed with TASK ABORTED 7351fd032eeSChristoph Hellwig * status (see SAM-4). 7361fd032eeSChristoph Hellwig */ 7370fd97ccfSChristoph Hellwig p[5] = (dev->dev_attrib.emulate_tas) ? 0x40 : 0x00; 7381fd032eeSChristoph Hellwig p[8] = 0xff; 7391fd032eeSChristoph Hellwig p[9] = 0xff; 7401fd032eeSChristoph Hellwig p[11] = 30; 7411fd032eeSChristoph Hellwig 742d4b2b867SRoland Dreier out: 7431fd032eeSChristoph Hellwig return 12; 7441fd032eeSChristoph Hellwig } 7451fd032eeSChristoph Hellwig 746d4b2b867SRoland Dreier static int spc_modesense_caching(struct se_device *dev, u8 pc, u8 *p) 7471fd032eeSChristoph Hellwig { 7481fd032eeSChristoph Hellwig p[0] = 0x08; 7491fd032eeSChristoph Hellwig p[1] = 0x12; 750d4b2b867SRoland Dreier 751d4b2b867SRoland Dreier /* No changeable values for now */ 752d4b2b867SRoland Dreier if (pc == 1) 753d4b2b867SRoland Dreier goto out; 754d4b2b867SRoland Dreier 7550fd97ccfSChristoph Hellwig if (dev->dev_attrib.emulate_write_cache > 0) 7561fd032eeSChristoph Hellwig p[2] = 0x04; /* Write Cache Enable */ 7571fd032eeSChristoph Hellwig p[12] = 0x20; /* Disabled Read Ahead */ 7581fd032eeSChristoph Hellwig 759d4b2b867SRoland Dreier out: 7601fd032eeSChristoph Hellwig return 20; 7611fd032eeSChristoph Hellwig } 7621fd032eeSChristoph Hellwig 763d4b2b867SRoland Dreier static struct { 764d4b2b867SRoland Dreier uint8_t page; 765d4b2b867SRoland Dreier uint8_t subpage; 766d4b2b867SRoland Dreier int (*emulate)(struct se_device *, u8, unsigned char *); 767d4b2b867SRoland Dreier } modesense_handlers[] = { 768d4b2b867SRoland Dreier { .page = 0x01, .subpage = 0x00, .emulate = spc_modesense_rwrecovery }, 769d4b2b867SRoland Dreier { .page = 0x08, .subpage = 0x00, .emulate = spc_modesense_caching }, 770d4b2b867SRoland Dreier { .page = 0x0a, .subpage = 0x00, .emulate = spc_modesense_control }, 771d4b2b867SRoland Dreier }; 772d4b2b867SRoland Dreier 7731fd032eeSChristoph Hellwig static void spc_modesense_write_protect(unsigned char *buf, int type) 7741fd032eeSChristoph Hellwig { 7751fd032eeSChristoph Hellwig /* 7761fd032eeSChristoph Hellwig * I believe that the WP bit (bit 7) in the mode header is the same for 7771fd032eeSChristoph Hellwig * all device types.. 7781fd032eeSChristoph Hellwig */ 7791fd032eeSChristoph Hellwig switch (type) { 7801fd032eeSChristoph Hellwig case TYPE_DISK: 7811fd032eeSChristoph Hellwig case TYPE_TAPE: 7821fd032eeSChristoph Hellwig default: 7831fd032eeSChristoph Hellwig buf[0] |= 0x80; /* WP bit */ 7841fd032eeSChristoph Hellwig break; 7851fd032eeSChristoph Hellwig } 7861fd032eeSChristoph Hellwig } 7871fd032eeSChristoph Hellwig 7881fd032eeSChristoph Hellwig static void spc_modesense_dpofua(unsigned char *buf, int type) 7891fd032eeSChristoph Hellwig { 7901fd032eeSChristoph Hellwig switch (type) { 7911fd032eeSChristoph Hellwig case TYPE_DISK: 7921fd032eeSChristoph Hellwig buf[0] |= 0x10; /* DPOFUA bit */ 7931fd032eeSChristoph Hellwig break; 7941fd032eeSChristoph Hellwig default: 7951fd032eeSChristoph Hellwig break; 7961fd032eeSChristoph Hellwig } 7971fd032eeSChristoph Hellwig } 7981fd032eeSChristoph Hellwig 799d4b2b867SRoland Dreier static int spc_modesense_blockdesc(unsigned char *buf, u64 blocks, u32 block_size) 800d4b2b867SRoland Dreier { 801d4b2b867SRoland Dreier *buf++ = 8; 802d4b2b867SRoland Dreier put_unaligned_be32(min(blocks, 0xffffffffull), buf); 803d4b2b867SRoland Dreier buf += 4; 804d4b2b867SRoland Dreier put_unaligned_be32(block_size, buf); 805d4b2b867SRoland Dreier return 9; 806d4b2b867SRoland Dreier } 807d4b2b867SRoland Dreier 808d4b2b867SRoland Dreier static int spc_modesense_long_blockdesc(unsigned char *buf, u64 blocks, u32 block_size) 809d4b2b867SRoland Dreier { 810d4b2b867SRoland Dreier if (blocks <= 0xffffffff) 811d4b2b867SRoland Dreier return spc_modesense_blockdesc(buf + 3, blocks, block_size) + 3; 812d4b2b867SRoland Dreier 813d4b2b867SRoland Dreier *buf++ = 1; /* LONGLBA */ 814d4b2b867SRoland Dreier buf += 2; 815d4b2b867SRoland Dreier *buf++ = 16; 816d4b2b867SRoland Dreier put_unaligned_be64(blocks, buf); 817d4b2b867SRoland Dreier buf += 12; 818d4b2b867SRoland Dreier put_unaligned_be32(block_size, buf); 819d4b2b867SRoland Dreier 820d4b2b867SRoland Dreier return 17; 821d4b2b867SRoland Dreier } 822d4b2b867SRoland Dreier 8231fd032eeSChristoph Hellwig static int spc_emulate_modesense(struct se_cmd *cmd) 8241fd032eeSChristoph Hellwig { 8251fd032eeSChristoph Hellwig struct se_device *dev = cmd->se_dev; 8261fd032eeSChristoph Hellwig char *cdb = cmd->t_task_cdb; 827d4b2b867SRoland Dreier unsigned char *buf, *map_buf; 8281fd032eeSChristoph Hellwig int type = dev->transport->get_device_type(dev); 8291fd032eeSChristoph Hellwig int ten = (cmd->t_task_cdb[0] == MODE_SENSE_10); 830d4b2b867SRoland Dreier bool dbd = !!(cdb[1] & 0x08); 831d4b2b867SRoland Dreier bool llba = ten ? !!(cdb[1] & 0x10) : false; 832d4b2b867SRoland Dreier u8 pc = cdb[2] >> 6; 833d4b2b867SRoland Dreier u8 page = cdb[2] & 0x3f; 834d4b2b867SRoland Dreier u8 subpage = cdb[3]; 8351fd032eeSChristoph Hellwig int length = 0; 836d4b2b867SRoland Dreier int ret; 837d4b2b867SRoland Dreier int i; 8381fd032eeSChristoph Hellwig 839d4b2b867SRoland Dreier map_buf = transport_kmap_data_sg(cmd); 8401fd032eeSChristoph Hellwig 841d4b2b867SRoland Dreier /* 842d4b2b867SRoland Dreier * If SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC is not set, then we 843d4b2b867SRoland Dreier * know we actually allocated a full page. Otherwise, if the 844d4b2b867SRoland Dreier * data buffer is too small, allocate a temporary buffer so we 845d4b2b867SRoland Dreier * don't have to worry about overruns in all our INQUIRY 846d4b2b867SRoland Dreier * emulation handling. 847d4b2b867SRoland Dreier */ 848d4b2b867SRoland Dreier if (cmd->data_length < SE_MODE_PAGE_BUF && 849d4b2b867SRoland Dreier (cmd->se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC)) { 850d4b2b867SRoland Dreier buf = kzalloc(SE_MODE_PAGE_BUF, GFP_KERNEL); 851d4b2b867SRoland Dreier if (!buf) { 852d4b2b867SRoland Dreier transport_kunmap_data_sg(cmd); 853d4b2b867SRoland Dreier cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; 854d4b2b867SRoland Dreier return -ENOMEM; 8551fd032eeSChristoph Hellwig } 856d4b2b867SRoland Dreier } else { 857d4b2b867SRoland Dreier buf = map_buf; 858d4b2b867SRoland Dreier } 859d4b2b867SRoland Dreier 860d4b2b867SRoland Dreier length = ten ? 2 : 1; 861d4b2b867SRoland Dreier 862d4b2b867SRoland Dreier /* DEVICE-SPECIFIC PARAMETER */ 863d4b2b867SRoland Dreier if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) || 864d4b2b867SRoland Dreier (cmd->se_deve && 865d4b2b867SRoland Dreier (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY))) 866d4b2b867SRoland Dreier spc_modesense_write_protect(&buf[length], type); 867d4b2b867SRoland Dreier 868d4b2b867SRoland Dreier if ((dev->dev_attrib.emulate_write_cache > 0) && 869d4b2b867SRoland Dreier (dev->dev_attrib.emulate_fua_write > 0)) 870d4b2b867SRoland Dreier spc_modesense_dpofua(&buf[length], type); 871d4b2b867SRoland Dreier 872d4b2b867SRoland Dreier ++length; 873d4b2b867SRoland Dreier 874d4b2b867SRoland Dreier /* BLOCK DESCRIPTOR */ 875d4b2b867SRoland Dreier 876d4b2b867SRoland Dreier /* 877d4b2b867SRoland Dreier * For now we only include a block descriptor for disk (SBC) 878d4b2b867SRoland Dreier * devices; other command sets use a slightly different format. 879d4b2b867SRoland Dreier */ 880d4b2b867SRoland Dreier if (!dbd && type == TYPE_DISK) { 881d4b2b867SRoland Dreier u64 blocks = dev->transport->get_blocks(dev); 882d4b2b867SRoland Dreier u32 block_size = dev->dev_attrib.block_size; 8831fd032eeSChristoph Hellwig 8841fd032eeSChristoph Hellwig if (ten) { 885d4b2b867SRoland Dreier if (llba) { 886d4b2b867SRoland Dreier length += spc_modesense_long_blockdesc(&buf[length], 887d4b2b867SRoland Dreier blocks, block_size); 8881fd032eeSChristoph Hellwig } else { 889d4b2b867SRoland Dreier length += 3; 890d4b2b867SRoland Dreier length += spc_modesense_blockdesc(&buf[length], 891d4b2b867SRoland Dreier blocks, block_size); 892d4b2b867SRoland Dreier } 893d4b2b867SRoland Dreier } else { 894d4b2b867SRoland Dreier length += spc_modesense_blockdesc(&buf[length], blocks, 895d4b2b867SRoland Dreier block_size); 896d4b2b867SRoland Dreier } 897d4b2b867SRoland Dreier } else { 898d4b2b867SRoland Dreier if (ten) 899d4b2b867SRoland Dreier length += 4; 900d4b2b867SRoland Dreier else 901d4b2b867SRoland Dreier length += 1; 9021fd032eeSChristoph Hellwig } 9031fd032eeSChristoph Hellwig 904d4b2b867SRoland Dreier if (page == 0x3f) { 905d4b2b867SRoland Dreier if (subpage != 0x00 && subpage != 0xff) { 906d4b2b867SRoland Dreier cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; 907d4b2b867SRoland Dreier length = -EINVAL; 908d4b2b867SRoland Dreier goto out; 909d4b2b867SRoland Dreier } 910d4b2b867SRoland Dreier 911d4b2b867SRoland Dreier for (i = 0; i < ARRAY_SIZE(modesense_handlers); ++i) { 912d4b2b867SRoland Dreier /* 913d4b2b867SRoland Dreier * Tricky way to say all subpage 00h for 914d4b2b867SRoland Dreier * subpage==0, all subpages for subpage==0xff 915d4b2b867SRoland Dreier * (and we just checked above that those are 916d4b2b867SRoland Dreier * the only two possibilities). 917d4b2b867SRoland Dreier */ 918d4b2b867SRoland Dreier if ((modesense_handlers[i].subpage & ~subpage) == 0) { 919d4b2b867SRoland Dreier ret = modesense_handlers[i].emulate(dev, pc, &buf[length]); 920d4b2b867SRoland Dreier if (!ten && length + ret >= 255) 921d4b2b867SRoland Dreier break; 922d4b2b867SRoland Dreier length += ret; 923d4b2b867SRoland Dreier } 924d4b2b867SRoland Dreier } 925d4b2b867SRoland Dreier 926d4b2b867SRoland Dreier goto set_length; 927d4b2b867SRoland Dreier } 928d4b2b867SRoland Dreier 929d4b2b867SRoland Dreier for (i = 0; i < ARRAY_SIZE(modesense_handlers); ++i) 930d4b2b867SRoland Dreier if (modesense_handlers[i].page == page && 931d4b2b867SRoland Dreier modesense_handlers[i].subpage == subpage) { 932d4b2b867SRoland Dreier length += modesense_handlers[i].emulate(dev, pc, &buf[length]); 933d4b2b867SRoland Dreier goto set_length; 934d4b2b867SRoland Dreier } 935d4b2b867SRoland Dreier 936d4b2b867SRoland Dreier /* 937d4b2b867SRoland Dreier * We don't intend to implement: 938d4b2b867SRoland Dreier * - obsolete page 03h "format parameters" (checked by Solaris) 939d4b2b867SRoland Dreier */ 940d4b2b867SRoland Dreier if (page != 0x03) 941d4b2b867SRoland Dreier pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n", 942d4b2b867SRoland Dreier page, subpage); 943d4b2b867SRoland Dreier 944d4b2b867SRoland Dreier cmd->scsi_sense_reason = TCM_UNKNOWN_MODE_PAGE; 945d4b2b867SRoland Dreier return -EINVAL; 946d4b2b867SRoland Dreier 947d4b2b867SRoland Dreier set_length: 948d4b2b867SRoland Dreier if (ten) 949d4b2b867SRoland Dreier put_unaligned_be16(length - 2, buf); 950d4b2b867SRoland Dreier else 951d4b2b867SRoland Dreier buf[0] = length - 1; 952d4b2b867SRoland Dreier 953d4b2b867SRoland Dreier out: 954d4b2b867SRoland Dreier if (buf != map_buf) { 955d4b2b867SRoland Dreier memcpy(map_buf, buf, cmd->data_length); 956d4b2b867SRoland Dreier kfree(buf); 957d4b2b867SRoland Dreier } 958d4b2b867SRoland Dreier 9591fd032eeSChristoph Hellwig transport_kunmap_data_sg(cmd); 9601fd032eeSChristoph Hellwig target_complete_cmd(cmd, GOOD); 9611fd032eeSChristoph Hellwig return 0; 9621fd032eeSChristoph Hellwig } 9631fd032eeSChristoph Hellwig 9641fd032eeSChristoph Hellwig static int spc_emulate_request_sense(struct se_cmd *cmd) 9651fd032eeSChristoph Hellwig { 9661fd032eeSChristoph Hellwig unsigned char *cdb = cmd->t_task_cdb; 96732a8811fSPaolo Bonzini unsigned char *rbuf; 9681fd032eeSChristoph Hellwig u8 ua_asc = 0, ua_ascq = 0; 96932a8811fSPaolo Bonzini unsigned char buf[SE_SENSE_BUF]; 97032a8811fSPaolo Bonzini 97132a8811fSPaolo Bonzini memset(buf, 0, SE_SENSE_BUF); 9721fd032eeSChristoph Hellwig 9731fd032eeSChristoph Hellwig if (cdb[1] & 0x01) { 9741fd032eeSChristoph Hellwig pr_err("REQUEST_SENSE description emulation not" 9751fd032eeSChristoph Hellwig " supported\n"); 9761fd032eeSChristoph Hellwig cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; 9771fd032eeSChristoph Hellwig return -ENOSYS; 9781fd032eeSChristoph Hellwig } 9791fd032eeSChristoph Hellwig 98032a8811fSPaolo Bonzini rbuf = transport_kmap_data_sg(cmd); 98132a8811fSPaolo Bonzini if (cmd->scsi_sense_reason != 0) { 98232a8811fSPaolo Bonzini /* 98332a8811fSPaolo Bonzini * Out of memory. We will fail with CHECK CONDITION, so 98432a8811fSPaolo Bonzini * we must not clear the unit attention condition. 98532a8811fSPaolo Bonzini */ 98632a8811fSPaolo Bonzini target_complete_cmd(cmd, CHECK_CONDITION); 98732a8811fSPaolo Bonzini return 0; 98832a8811fSPaolo Bonzini } else if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) { 9891fd032eeSChristoph Hellwig /* 9901fd032eeSChristoph Hellwig * CURRENT ERROR, UNIT ATTENTION 9911fd032eeSChristoph Hellwig */ 9921fd032eeSChristoph Hellwig buf[0] = 0x70; 9931fd032eeSChristoph Hellwig buf[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION; 9941fd032eeSChristoph Hellwig 9951fd032eeSChristoph Hellwig /* 9961fd032eeSChristoph Hellwig * The Additional Sense Code (ASC) from the UNIT ATTENTION 9971fd032eeSChristoph Hellwig */ 9981fd032eeSChristoph Hellwig buf[SPC_ASC_KEY_OFFSET] = ua_asc; 9991fd032eeSChristoph Hellwig buf[SPC_ASCQ_KEY_OFFSET] = ua_ascq; 10001fd032eeSChristoph Hellwig buf[7] = 0x0A; 10011fd032eeSChristoph Hellwig } else { 10021fd032eeSChristoph Hellwig /* 10031fd032eeSChristoph Hellwig * CURRENT ERROR, NO SENSE 10041fd032eeSChristoph Hellwig */ 10051fd032eeSChristoph Hellwig buf[0] = 0x70; 10061fd032eeSChristoph Hellwig buf[SPC_SENSE_KEY_OFFSET] = NO_SENSE; 10071fd032eeSChristoph Hellwig 10081fd032eeSChristoph Hellwig /* 10091fd032eeSChristoph Hellwig * NO ADDITIONAL SENSE INFORMATION 10101fd032eeSChristoph Hellwig */ 10111fd032eeSChristoph Hellwig buf[SPC_ASC_KEY_OFFSET] = 0x00; 10121fd032eeSChristoph Hellwig buf[7] = 0x0A; 10131fd032eeSChristoph Hellwig } 10141fd032eeSChristoph Hellwig 101532a8811fSPaolo Bonzini if (rbuf) { 101632a8811fSPaolo Bonzini memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); 10171fd032eeSChristoph Hellwig transport_kunmap_data_sg(cmd); 101832a8811fSPaolo Bonzini } 101932a8811fSPaolo Bonzini 10201fd032eeSChristoph Hellwig target_complete_cmd(cmd, GOOD); 10211fd032eeSChristoph Hellwig return 0; 10221fd032eeSChristoph Hellwig } 10231fd032eeSChristoph Hellwig 10248de530a5SChristoph Hellwig int spc_emulate_report_luns(struct se_cmd *cmd) 1025d1b1f805SChristoph Hellwig { 1026d1b1f805SChristoph Hellwig struct se_dev_entry *deve; 1027d1b1f805SChristoph Hellwig struct se_session *sess = cmd->se_sess; 1028d1b1f805SChristoph Hellwig unsigned char *buf; 1029d1b1f805SChristoph Hellwig u32 lun_count = 0, offset = 8, i; 1030d1b1f805SChristoph Hellwig 1031d1b1f805SChristoph Hellwig if (cmd->data_length < 16) { 1032d1b1f805SChristoph Hellwig pr_warn("REPORT LUNS allocation length %u too small\n", 1033d1b1f805SChristoph Hellwig cmd->data_length); 1034d1b1f805SChristoph Hellwig cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; 1035d1b1f805SChristoph Hellwig return -EINVAL; 1036d1b1f805SChristoph Hellwig } 1037d1b1f805SChristoph Hellwig 1038d1b1f805SChristoph Hellwig buf = transport_kmap_data_sg(cmd); 1039d1b1f805SChristoph Hellwig if (!buf) 1040d1b1f805SChristoph Hellwig return -ENOMEM; 1041d1b1f805SChristoph Hellwig 1042d1b1f805SChristoph Hellwig /* 1043d1b1f805SChristoph Hellwig * If no struct se_session pointer is present, this struct se_cmd is 1044d1b1f805SChristoph Hellwig * coming via a target_core_mod PASSTHROUGH op, and not through 1045d1b1f805SChristoph Hellwig * a $FABRIC_MOD. In that case, report LUN=0 only. 1046d1b1f805SChristoph Hellwig */ 1047d1b1f805SChristoph Hellwig if (!sess) { 1048d1b1f805SChristoph Hellwig int_to_scsilun(0, (struct scsi_lun *)&buf[offset]); 1049d1b1f805SChristoph Hellwig lun_count = 1; 1050d1b1f805SChristoph Hellwig goto done; 1051d1b1f805SChristoph Hellwig } 1052d1b1f805SChristoph Hellwig 1053d1b1f805SChristoph Hellwig spin_lock_irq(&sess->se_node_acl->device_list_lock); 1054d1b1f805SChristoph Hellwig for (i = 0; i < TRANSPORT_MAX_LUNS_PER_TPG; i++) { 1055d1b1f805SChristoph Hellwig deve = sess->se_node_acl->device_list[i]; 1056d1b1f805SChristoph Hellwig if (!(deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS)) 1057d1b1f805SChristoph Hellwig continue; 1058d1b1f805SChristoph Hellwig /* 1059d1b1f805SChristoph Hellwig * We determine the correct LUN LIST LENGTH even once we 1060d1b1f805SChristoph Hellwig * have reached the initial allocation length. 1061d1b1f805SChristoph Hellwig * See SPC2-R20 7.19. 1062d1b1f805SChristoph Hellwig */ 1063d1b1f805SChristoph Hellwig lun_count++; 1064d1b1f805SChristoph Hellwig if ((offset + 8) > cmd->data_length) 1065d1b1f805SChristoph Hellwig continue; 1066d1b1f805SChristoph Hellwig 1067d1b1f805SChristoph Hellwig int_to_scsilun(deve->mapped_lun, (struct scsi_lun *)&buf[offset]); 1068d1b1f805SChristoph Hellwig offset += 8; 1069d1b1f805SChristoph Hellwig } 1070d1b1f805SChristoph Hellwig spin_unlock_irq(&sess->se_node_acl->device_list_lock); 1071d1b1f805SChristoph Hellwig 1072d1b1f805SChristoph Hellwig /* 1073d1b1f805SChristoph Hellwig * See SPC3 r07, page 159. 1074d1b1f805SChristoph Hellwig */ 1075d1b1f805SChristoph Hellwig done: 1076d1b1f805SChristoph Hellwig lun_count *= 8; 1077d1b1f805SChristoph Hellwig buf[0] = ((lun_count >> 24) & 0xff); 1078d1b1f805SChristoph Hellwig buf[1] = ((lun_count >> 16) & 0xff); 1079d1b1f805SChristoph Hellwig buf[2] = ((lun_count >> 8) & 0xff); 1080d1b1f805SChristoph Hellwig buf[3] = (lun_count & 0xff); 1081d1b1f805SChristoph Hellwig transport_kunmap_data_sg(cmd); 1082d1b1f805SChristoph Hellwig 1083d1b1f805SChristoph Hellwig target_complete_cmd(cmd, GOOD); 1084d1b1f805SChristoph Hellwig return 0; 1085d1b1f805SChristoph Hellwig } 10868de530a5SChristoph Hellwig EXPORT_SYMBOL(spc_emulate_report_luns); 1087d1b1f805SChristoph Hellwig 10881fd032eeSChristoph Hellwig static int spc_emulate_testunitready(struct se_cmd *cmd) 10891fd032eeSChristoph Hellwig { 10901fd032eeSChristoph Hellwig target_complete_cmd(cmd, GOOD); 10911fd032eeSChristoph Hellwig return 0; 10921fd032eeSChristoph Hellwig } 10931fd032eeSChristoph Hellwig 10941fd032eeSChristoph Hellwig int spc_parse_cdb(struct se_cmd *cmd, unsigned int *size) 109588455ec4SChristoph Hellwig { 1096eba2ca45SNicholas Bellinger struct se_device *dev = cmd->se_dev; 109788455ec4SChristoph Hellwig unsigned char *cdb = cmd->t_task_cdb; 109888455ec4SChristoph Hellwig 109988455ec4SChristoph Hellwig switch (cdb[0]) { 110088455ec4SChristoph Hellwig case MODE_SELECT: 110188455ec4SChristoph Hellwig *size = cdb[4]; 110288455ec4SChristoph Hellwig break; 110388455ec4SChristoph Hellwig case MODE_SELECT_10: 110488455ec4SChristoph Hellwig *size = (cdb[7] << 8) + cdb[8]; 110588455ec4SChristoph Hellwig break; 110688455ec4SChristoph Hellwig case MODE_SENSE: 110788455ec4SChristoph Hellwig *size = cdb[4]; 11081fd032eeSChristoph Hellwig cmd->execute_cmd = spc_emulate_modesense; 110988455ec4SChristoph Hellwig break; 111088455ec4SChristoph Hellwig case MODE_SENSE_10: 111188455ec4SChristoph Hellwig *size = (cdb[7] << 8) + cdb[8]; 11121fd032eeSChristoph Hellwig cmd->execute_cmd = spc_emulate_modesense; 111388455ec4SChristoph Hellwig break; 111488455ec4SChristoph Hellwig case LOG_SELECT: 111588455ec4SChristoph Hellwig case LOG_SENSE: 111688455ec4SChristoph Hellwig *size = (cdb[7] << 8) + cdb[8]; 111788455ec4SChristoph Hellwig break; 111888455ec4SChristoph Hellwig case PERSISTENT_RESERVE_IN: 111988455ec4SChristoph Hellwig *size = (cdb[7] << 8) + cdb[8]; 1120d977f437SChristoph Hellwig cmd->execute_cmd = target_scsi3_emulate_pr_in; 112188455ec4SChristoph Hellwig break; 112288455ec4SChristoph Hellwig case PERSISTENT_RESERVE_OUT: 112388455ec4SChristoph Hellwig *size = (cdb[7] << 8) + cdb[8]; 1124d977f437SChristoph Hellwig cmd->execute_cmd = target_scsi3_emulate_pr_out; 112588455ec4SChristoph Hellwig break; 112688455ec4SChristoph Hellwig case RELEASE: 112788455ec4SChristoph Hellwig case RELEASE_10: 112888455ec4SChristoph Hellwig if (cdb[0] == RELEASE_10) 112988455ec4SChristoph Hellwig *size = (cdb[7] << 8) | cdb[8]; 113088455ec4SChristoph Hellwig else 113188455ec4SChristoph Hellwig *size = cmd->data_length; 113288455ec4SChristoph Hellwig 113388455ec4SChristoph Hellwig cmd->execute_cmd = target_scsi2_reservation_release; 113488455ec4SChristoph Hellwig break; 113588455ec4SChristoph Hellwig case RESERVE: 113688455ec4SChristoph Hellwig case RESERVE_10: 113788455ec4SChristoph Hellwig /* 113888455ec4SChristoph Hellwig * The SPC-2 RESERVE does not contain a size in the SCSI CDB. 113988455ec4SChristoph Hellwig * Assume the passthrough or $FABRIC_MOD will tell us about it. 114088455ec4SChristoph Hellwig */ 114188455ec4SChristoph Hellwig if (cdb[0] == RESERVE_10) 114288455ec4SChristoph Hellwig *size = (cdb[7] << 8) | cdb[8]; 114388455ec4SChristoph Hellwig else 114488455ec4SChristoph Hellwig *size = cmd->data_length; 114588455ec4SChristoph Hellwig 114688455ec4SChristoph Hellwig cmd->execute_cmd = target_scsi2_reservation_reserve; 114788455ec4SChristoph Hellwig break; 114888455ec4SChristoph Hellwig case REQUEST_SENSE: 114988455ec4SChristoph Hellwig *size = cdb[4]; 11501fd032eeSChristoph Hellwig cmd->execute_cmd = spc_emulate_request_sense; 115188455ec4SChristoph Hellwig break; 115288455ec4SChristoph Hellwig case INQUIRY: 115388455ec4SChristoph Hellwig *size = (cdb[3] << 8) + cdb[4]; 115488455ec4SChristoph Hellwig 115588455ec4SChristoph Hellwig /* 115688455ec4SChristoph Hellwig * Do implict HEAD_OF_QUEUE processing for INQUIRY. 115788455ec4SChristoph Hellwig * See spc4r17 section 5.3 115888455ec4SChristoph Hellwig */ 115988455ec4SChristoph Hellwig cmd->sam_task_attr = MSG_HEAD_TAG; 11601fd032eeSChristoph Hellwig cmd->execute_cmd = spc_emulate_inquiry; 116188455ec4SChristoph Hellwig break; 116288455ec4SChristoph Hellwig case SECURITY_PROTOCOL_IN: 116388455ec4SChristoph Hellwig case SECURITY_PROTOCOL_OUT: 116488455ec4SChristoph Hellwig *size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; 116588455ec4SChristoph Hellwig break; 116688455ec4SChristoph Hellwig case EXTENDED_COPY: 116788455ec4SChristoph Hellwig case READ_ATTRIBUTE: 116888455ec4SChristoph Hellwig case RECEIVE_COPY_RESULTS: 116988455ec4SChristoph Hellwig case WRITE_ATTRIBUTE: 117088455ec4SChristoph Hellwig *size = (cdb[10] << 24) | (cdb[11] << 16) | 117188455ec4SChristoph Hellwig (cdb[12] << 8) | cdb[13]; 117288455ec4SChristoph Hellwig break; 117388455ec4SChristoph Hellwig case RECEIVE_DIAGNOSTIC: 117488455ec4SChristoph Hellwig case SEND_DIAGNOSTIC: 117588455ec4SChristoph Hellwig *size = (cdb[3] << 8) | cdb[4]; 117688455ec4SChristoph Hellwig break; 117788455ec4SChristoph Hellwig case WRITE_BUFFER: 117888455ec4SChristoph Hellwig *size = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8]; 117988455ec4SChristoph Hellwig break; 118088455ec4SChristoph Hellwig case REPORT_LUNS: 1181d1b1f805SChristoph Hellwig cmd->execute_cmd = spc_emulate_report_luns; 118288455ec4SChristoph Hellwig *size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; 118388455ec4SChristoph Hellwig /* 118488455ec4SChristoph Hellwig * Do implict HEAD_OF_QUEUE processing for REPORT_LUNS 118588455ec4SChristoph Hellwig * See spc4r17 section 5.3 118688455ec4SChristoph Hellwig */ 118788455ec4SChristoph Hellwig cmd->sam_task_attr = MSG_HEAD_TAG; 118888455ec4SChristoph Hellwig break; 118988455ec4SChristoph Hellwig case TEST_UNIT_READY: 11901fd032eeSChristoph Hellwig cmd->execute_cmd = spc_emulate_testunitready; 1191d6e0175cSChristoph Hellwig *size = 0; 119288455ec4SChristoph Hellwig break; 1193eba2ca45SNicholas Bellinger case MAINTENANCE_IN: 1194eba2ca45SNicholas Bellinger if (dev->transport->get_device_type(dev) != TYPE_ROM) { 1195eba2ca45SNicholas Bellinger /* 1196eba2ca45SNicholas Bellinger * MAINTENANCE_IN from SCC-2 1197eba2ca45SNicholas Bellinger * Check for emulated MI_REPORT_TARGET_PGS 1198eba2ca45SNicholas Bellinger */ 1199c87fbd56SChristoph Hellwig if ((cdb[1] & 0x1f) == MI_REPORT_TARGET_PGS) { 1200eba2ca45SNicholas Bellinger cmd->execute_cmd = 1201eba2ca45SNicholas Bellinger target_emulate_report_target_port_groups; 1202eba2ca45SNicholas Bellinger } 1203eba2ca45SNicholas Bellinger *size = get_unaligned_be32(&cdb[6]); 1204eba2ca45SNicholas Bellinger } else { 1205eba2ca45SNicholas Bellinger /* 1206eba2ca45SNicholas Bellinger * GPCMD_SEND_KEY from multi media commands 1207eba2ca45SNicholas Bellinger */ 1208eba2ca45SNicholas Bellinger *size = get_unaligned_be16(&cdb[8]); 1209eba2ca45SNicholas Bellinger } 1210eba2ca45SNicholas Bellinger break; 1211eba2ca45SNicholas Bellinger case MAINTENANCE_OUT: 1212eba2ca45SNicholas Bellinger if (dev->transport->get_device_type(dev) != TYPE_ROM) { 1213eba2ca45SNicholas Bellinger /* 1214eba2ca45SNicholas Bellinger * MAINTENANCE_OUT from SCC-2 1215eba2ca45SNicholas Bellinger * Check for emulated MO_SET_TARGET_PGS. 1216eba2ca45SNicholas Bellinger */ 1217c87fbd56SChristoph Hellwig if (cdb[1] == MO_SET_TARGET_PGS) { 1218eba2ca45SNicholas Bellinger cmd->execute_cmd = 1219eba2ca45SNicholas Bellinger target_emulate_set_target_port_groups; 1220eba2ca45SNicholas Bellinger } 1221eba2ca45SNicholas Bellinger *size = get_unaligned_be32(&cdb[6]); 1222eba2ca45SNicholas Bellinger } else { 1223eba2ca45SNicholas Bellinger /* 1224eba2ca45SNicholas Bellinger * GPCMD_SEND_KEY from multi media commands 1225eba2ca45SNicholas Bellinger */ 1226eba2ca45SNicholas Bellinger *size = get_unaligned_be16(&cdb[8]); 1227eba2ca45SNicholas Bellinger } 1228eba2ca45SNicholas Bellinger break; 122988455ec4SChristoph Hellwig default: 123088455ec4SChristoph Hellwig pr_warn("TARGET_CORE[%s]: Unsupported SCSI Opcode" 123188455ec4SChristoph Hellwig " 0x%02x, sending CHECK_CONDITION.\n", 123288455ec4SChristoph Hellwig cmd->se_tfo->get_fabric_name(), cdb[0]); 123388455ec4SChristoph Hellwig cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; 123488455ec4SChristoph Hellwig cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; 123588455ec4SChristoph Hellwig return -EINVAL; 123688455ec4SChristoph Hellwig } 123788455ec4SChristoph Hellwig 123888455ec4SChristoph Hellwig return 0; 123988455ec4SChristoph Hellwig } 124088455ec4SChristoph Hellwig EXPORT_SYMBOL(spc_parse_cdb); 1241