Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 05c78081 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull SCSI target updates from Nicholas Bellinger:
 "Here are the outstanding target-pending updates for v4.3-rc1.

  Mostly bug-fixes and minor changes this round.  The fallout from the
  big v4.2-rc1 RCU conversion have (thus far) been minimal.

  The highlights this round include:

   - Move sense handling routines into scsi_common code (Sagi)

   - Return ABORTED_COMMAND sense key for PI errors (Sagi)

   - Add tpg_enabled_sendtargets attribute for disabled iscsi-target
     discovery (David)

   - Shrink target struct se_cmd by rearranging fields (Roland)

   - Drop iSCSI use of mutex around max_cmd_sn increment (Roland)

   - Replace iSCSI __kernel_sockaddr_storage with sockaddr_storage (Andy +
     Chris)

   - Honor fabric max_data_sg_nents I/O transfer limit (Arun + Himanshu +
     nab)

   - Fix EXTENDED_COPY >= v4.1 regression OOPsen (Alex + nab)"

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (37 commits)
  target: use stringify.h instead of own definition
  target/user: Fix UFLAG_UNKNOWN_OP handling
  target: Remove no-op conditional
  target/user: Remove unused variable
  target: Fix max_cmd_sn increment w/o cmdsn mutex regressions
  target: Attach EXTENDED_COPY local I/O descriptors to xcopy_pt_sess
  target/qla2xxx: Honor max_data_sg_nents I/O transfer limit
  target/iscsi: Replace __kernel_sockaddr_storage with sockaddr_storage
  target/iscsi: Replace conn->login_ip with login_sockaddr
  target/iscsi: Keep local_ip as the actual sockaddr
  target/iscsi: Fix np_ip bracket issue by removing np_ip
  target: Drop iSCSI use of mutex around max_cmd_sn increment
  qla2xxx: Update tcm_qla2xxx module description to 24xx+
  iscsi-target: Add tpg_enabled_sendtargets for disabled discovery
  drivers: target: Drop unlikely before IS_ERR(_OR_NULL)
  target: check DPO/FUA usage for COMPARE AND WRITE
  target: Shrink struct se_cmd by rearranging fields
  target: Remove cmd->se_ordered_id (unused except debug log lines)
  target: add support for START_STOP_UNIT SCSI opcode
  target: improve unsupported opcode message
  ...
parents 8e78b7dc ac64a2ce
Loading
Loading
Loading
Loading
+4 −25
Original line number Diff line number Diff line
@@ -3095,7 +3095,7 @@ isert_setup_id(struct isert_np *isert_np)

static int
isert_setup_np(struct iscsi_np *np,
	       struct __kernel_sockaddr_storage *ksockaddr)
	       struct sockaddr_storage *ksockaddr)
{
	struct isert_np *isert_np;
	struct rdma_cm_id *isert_lid;
@@ -3117,7 +3117,7 @@ isert_setup_np(struct iscsi_np *np,
	 * in iscsi_target_configfs.c code..
	 */
	memcpy(&np->np_sockaddr, ksockaddr,
	       sizeof(struct __kernel_sockaddr_storage));
	       sizeof(struct sockaddr_storage));

	isert_lid = isert_setup_id(isert_np);
	if (IS_ERR(isert_lid)) {
@@ -3199,32 +3199,11 @@ isert_set_conn_info(struct iscsi_np *np, struct iscsi_conn *conn,
{
	struct rdma_cm_id *cm_id = isert_conn->cm_id;
	struct rdma_route *cm_route = &cm_id->route;
	struct sockaddr_in *sock_in;
	struct sockaddr_in6 *sock_in6;

	conn->login_family = np->np_sockaddr.ss_family;

	if (np->np_sockaddr.ss_family == AF_INET6) {
		sock_in6 = (struct sockaddr_in6 *)&cm_route->addr.dst_addr;
		snprintf(conn->login_ip, sizeof(conn->login_ip), "%pI6c",
			 &sock_in6->sin6_addr.in6_u);
		conn->login_port = ntohs(sock_in6->sin6_port);

		sock_in6 = (struct sockaddr_in6 *)&cm_route->addr.src_addr;
		snprintf(conn->local_ip, sizeof(conn->local_ip), "%pI6c",
			 &sock_in6->sin6_addr.in6_u);
		conn->local_port = ntohs(sock_in6->sin6_port);
	} else {
		sock_in = (struct sockaddr_in *)&cm_route->addr.dst_addr;
		sprintf(conn->login_ip, "%pI4",
			&sock_in->sin_addr.s_addr);
		conn->login_port = ntohs(sock_in->sin_port);

		sock_in = (struct sockaddr_in *)&cm_route->addr.src_addr;
		sprintf(conn->local_ip, "%pI4",
			&sock_in->sin_addr.s_addr);
		conn->local_port = ntohs(sock_in->sin_port);
	}
	conn->login_sockaddr = cm_route->addr.dst_addr;
	conn->local_sockaddr = cm_route->addr.src_addr;
}

static int
+3 −6
Original line number Diff line number Diff line
@@ -853,12 +853,9 @@ static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
				     SAM_STAT_CHECK_CONDITION;
			scsi_build_sense_buffer(1, sc->sense_buffer,
						ILLEGAL_REQUEST, 0x10, ascq);
			sc->sense_buffer[7] = 0xc; /* Additional sense length */
			sc->sense_buffer[8] = 0;   /* Information desc type */
			sc->sense_buffer[9] = 0xa; /* Additional desc length */
			sc->sense_buffer[10] = 0x80; /* Validity bit */

			put_unaligned_be64(sector, &sc->sense_buffer[12]);
			scsi_set_sense_information(sc->sense_buffer,
						   SCSI_SENSE_BUFFERSIZE,
						   sector);
			goto out;
		}
	}
+2 −2
Original line number Diff line number Diff line
@@ -32,10 +32,10 @@ config SCSI_QLA_FC
	They are also included in the linux-firmware tree as well.

config TCM_QLA2XXX
	tristate "TCM_QLA2XXX fabric module for Qlogic 2xxx series target mode HBAs"
	tristate "TCM_QLA2XXX fabric module for QLogic 24xx+ series target mode HBAs"
	depends on SCSI_QLA_FC && TARGET_CORE
	depends on LIBFC
	select BTREE
	default n
	---help---
	Say Y here to enable the TCM_QLA2XXX fabric module for Qlogic 2xxx series target mode HBAs
	Say Y here to enable the TCM_QLA2XXX fabric module for QLogic 24xx+ series target mode HBAs
+6 −7
Original line number Diff line number Diff line
@@ -1359,9 +1359,7 @@ static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess)
	struct qla_hw_data *ha = tgt->ha;
	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
	struct se_session *se_sess;
	struct se_node_acl *se_nacl;
	struct tcm_qla2xxx_lport *lport;
	struct tcm_qla2xxx_nacl *nacl;

	BUG_ON(in_interrupt());

@@ -1371,8 +1369,6 @@ static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess)
		dump_stack();
		return;
	}
	se_nacl = se_sess->se_node_acl;
	nacl = container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl);

	lport = vha->vha_tgt.target_lport_ptr;
	if (!lport) {
@@ -1680,7 +1676,6 @@ static int tcm_qla2xxx_lport_register_npiv_cb(struct scsi_qla_host *base_vha,
			(struct tcm_qla2xxx_lport *)target_lport_ptr;
	struct tcm_qla2xxx_lport *base_lport =
			(struct tcm_qla2xxx_lport *)base_vha->vha_tgt.target_lport_ptr;
	struct tcm_qla2xxx_tpg *base_tpg;
	struct fc_vport_identifiers vport_id;

	if (!qla_tgt_mode_enabled(base_vha)) {
@@ -1693,7 +1688,6 @@ static int tcm_qla2xxx_lport_register_npiv_cb(struct scsi_qla_host *base_vha,
		pr_err("qla2xxx base_lport or tpg_1 not available\n");
		return -EPERM;
	}
	base_tpg = base_lport->tpg_1;

	memset(&vport_id, 0, sizeof(vport_id));
	vport_id.port_name = npiv_wwpn;
@@ -1810,6 +1804,11 @@ static const struct target_core_fabric_ops tcm_qla2xxx_ops = {
	.module				= THIS_MODULE,
	.name				= "qla2xxx",
	.node_acl_size			= sizeof(struct tcm_qla2xxx_nacl),
	/*
	 * XXX: Limit assumes single page per scatter-gather-list entry.
	 * Current maximum is ~4.9 MB per se_cmd->t_data_sg with PAGE_SIZE=4096
	 */
	.max_data_sg_nents		= 1200,
	.get_fabric_name		= tcm_qla2xxx_get_fabric_name,
	.tpg_get_wwn			= tcm_qla2xxx_get_fabric_wwn,
	.tpg_get_tag			= tcm_qla2xxx_get_tag,
@@ -1958,7 +1957,7 @@ static void __exit tcm_qla2xxx_exit(void)
	tcm_qla2xxx_deregister_configfs();
}

MODULE_DESCRIPTION("TCM QLA2XXX series NPIV enabled fabric driver");
MODULE_DESCRIPTION("TCM QLA24XX+ series NPIV enabled fabric driver");
MODULE_LICENSE("GPL");
module_init(tcm_qla2xxx_init);
module_exit(tcm_qla2xxx_exit);
+109 −0
Original line number Diff line number Diff line
@@ -5,6 +5,8 @@
#include <linux/bug.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <asm/unaligned.h>
#include <scsi/scsi_common.h>

/* NB: These are exposed through /proc/scsi/scsi and form part of the ABI.
@@ -176,3 +178,110 @@ bool scsi_normalize_sense(const u8 *sense_buffer, int sb_len,
	return true;
}
EXPORT_SYMBOL(scsi_normalize_sense);

/**
 * scsi_sense_desc_find - search for a given descriptor type in	descriptor sense data format.
 * @sense_buffer:	byte array of descriptor format sense data
 * @sb_len:		number of valid bytes in sense_buffer
 * @desc_type:		value of descriptor type to find
 *			(e.g. 0 -> information)
 *
 * Notes:
 *	only valid when sense data is in descriptor format
 *
 * Return value:
 *	pointer to start of (first) descriptor if found else NULL
 */
const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len,
				int desc_type)
{
	int add_sen_len, add_len, desc_len, k;
	const u8 * descp;

	if ((sb_len < 8) || (0 == (add_sen_len = sense_buffer[7])))
		return NULL;
	if ((sense_buffer[0] < 0x72) || (sense_buffer[0] > 0x73))
		return NULL;
	add_sen_len = (add_sen_len < (sb_len - 8)) ?
			add_sen_len : (sb_len - 8);
	descp = &sense_buffer[8];
	for (desc_len = 0, k = 0; k < add_sen_len; k += desc_len) {
		descp += desc_len;
		add_len = (k < (add_sen_len - 1)) ? descp[1]: -1;
		desc_len = add_len + 2;
		if (descp[0] == desc_type)
			return descp;
		if (add_len < 0) // short descriptor ??
			break;
	}
	return NULL;
}
EXPORT_SYMBOL(scsi_sense_desc_find);

/**
 * scsi_build_sense_buffer - build sense data in a buffer
 * @desc:	Sense format (non zero == descriptor format,
 *              0 == fixed format)
 * @buf:	Where to build sense data
 * @key:	Sense key
 * @asc:	Additional sense code
 * @ascq:	Additional sense code qualifier
 *
 **/
void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq)
{
	if (desc) {
		buf[0] = 0x72;	/* descriptor, current */
		buf[1] = key;
		buf[2] = asc;
		buf[3] = ascq;
		buf[7] = 0;
	} else {
		buf[0] = 0x70;	/* fixed, current */
		buf[2] = key;
		buf[7] = 0xa;
		buf[12] = asc;
		buf[13] = ascq;
	}
}
EXPORT_SYMBOL(scsi_build_sense_buffer);

/**
 * scsi_set_sense_information - set the information field in a
 *		formatted sense data buffer
 * @buf:	Where to build sense data
 * @buf_len:    buffer length
 * @info:	64-bit information value to be set
 *
 * Return value:
 *	0 on success or EINVAL for invalid sense buffer length
 **/
int scsi_set_sense_information(u8 *buf, int buf_len, u64 info)
{
	if ((buf[0] & 0x7f) == 0x72) {
		u8 *ucp, len;

		len = buf[7];
		ucp = (char *)scsi_sense_desc_find(buf, len + 8, 0);
		if (!ucp) {
			buf[7] = len + 0xc;
			ucp = buf + 8 + len;
		}

		if (buf_len < len + 0xc)
			/* Not enough room for info */
			return -EINVAL;

		ucp[0] = 0;
		ucp[1] = 0xa;
		ucp[2] = 0x80; /* Valid bit */
		ucp[3] = 0;
		put_unaligned_be64(info, &ucp[4]);
	} else if ((buf[0] & 0x7f) == 0x70) {
		buf[0] |= 0x80;
		put_unaligned_be64(info, &buf[3]);
	}

	return 0;
}
EXPORT_SYMBOL(scsi_set_sense_information);
Loading