Commit 15b7a68c authored by Bart Van Assche's avatar Bart Van Assche Committed by Martin K. Petersen
Browse files

scsi: qla2xxx: Introduce the dsd32 and dsd64 data structures



Introduce two structures for the (DMA address, length) combination instead
of using separate structure members for the DMA address and length. This
patch fixes several Coverity complaints about 'cur_dsd' being used to write
outside the bounds of structure members.

Cc: Himanshu Madhani <hmadhani@marvell.com>
Cc: Giridhar Malavali <gmalavali@marvell.com>
Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
Acked-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent bc04459c
Loading
Loading
Loading
Loading
+4 −6
Original line number Diff line number Diff line
@@ -1056,9 +1056,8 @@ qla84xx_updatefw(struct bsg_job *bsg_job)
	mn->fw_ver =  cpu_to_le32(fw_ver);
	mn->fw_size =  cpu_to_le32(data_len);
	mn->fw_seq_size =  cpu_to_le32(data_len);
	mn->dseg_address[0] = cpu_to_le32(LSD(fw_dma));
	mn->dseg_address[1] = cpu_to_le32(MSD(fw_dma));
	mn->dseg_length = cpu_to_le32(data_len);
	put_unaligned_le64(fw_dma, &mn->dsd.address);
	mn->dsd.length = cpu_to_le32(data_len);
	mn->data_seg_cnt = cpu_to_le16(1);

	rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
@@ -1237,9 +1236,8 @@ qla84xx_mgmt_cmd(struct bsg_job *bsg_job)
	if (ql84_mgmt->mgmt.cmd != QLA84_MGMT_CHNG_CONFIG) {
		mn->total_byte_cnt = cpu_to_le32(ql84_mgmt->mgmt.len);
		mn->dseg_count = cpu_to_le16(1);
		mn->dseg_address[0] = cpu_to_le32(LSD(mgmt_dma));
		mn->dseg_address[1] = cpu_to_le32(MSD(mgmt_dma));
		mn->dseg_length = cpu_to_le32(ql84_mgmt->mgmt.len);
		put_unaligned_le64(mgmt_dma, &mn->dsd.address);
		mn->dsd.length = cpu_to_le32(ql84_mgmt->mgmt.len);
	}

	rval = qla2x00_issue_iocb(vha, mn, mn_dma, 0);
+13 −45
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include <scsi/scsi_bsg_fc.h>

#include "qla_bsg.h"
#include "qla_dsd.h"
#include "qla_nx.h"
#include "qla_nx2.h"
#include "qla_nvme.h"
@@ -1754,12 +1755,10 @@ typedef struct {
	uint16_t dseg_count;		/* Data segment count. */
	uint8_t scsi_cdb[MAX_CMDSZ]; 	/* SCSI command words. */
	uint32_t byte_count;		/* Total byte count. */
	uint32_t dseg_0_address;	/* Data segment 0 address. */
	uint32_t dseg_0_length;		/* Data segment 0 length. */
	uint32_t dseg_1_address;	/* Data segment 1 address. */
	uint32_t dseg_1_length;		/* Data segment 1 length. */
	uint32_t dseg_2_address;	/* Data segment 2 address. */
	uint32_t dseg_2_length;		/* Data segment 2 length. */
	union {
		struct dsd32 dsd32[3];
		struct dsd64 dsd64[2];
	};
} cmd_entry_t;

/*
@@ -1780,10 +1779,7 @@ typedef struct {
	uint16_t dseg_count;		/* Data segment count. */
	uint8_t scsi_cdb[MAX_CMDSZ];	/* SCSI command words. */
	uint32_t byte_count;		/* Total byte count. */
	uint32_t dseg_0_address[2];	/* Data segment 0 address. */
	uint32_t dseg_0_length;		/* Data segment 0 length. */
	uint32_t dseg_1_address[2];	/* Data segment 1 address. */
	uint32_t dseg_1_length;		/* Data segment 1 length. */
	struct dsd64 dsd[2];
} cmd_a64_entry_t, request_t;

/*
@@ -1796,20 +1792,7 @@ typedef struct {
	uint8_t sys_define;		/* System defined. */
	uint8_t entry_status;		/* Entry Status. */
	uint32_t reserved;
	uint32_t dseg_0_address;	/* Data segment 0 address. */
	uint32_t dseg_0_length;		/* Data segment 0 length. */
	uint32_t dseg_1_address;	/* Data segment 1 address. */
	uint32_t dseg_1_length;		/* Data segment 1 length. */
	uint32_t dseg_2_address;	/* Data segment 2 address. */
	uint32_t dseg_2_length;		/* Data segment 2 length. */
	uint32_t dseg_3_address;	/* Data segment 3 address. */
	uint32_t dseg_3_length;		/* Data segment 3 length. */
	uint32_t dseg_4_address;	/* Data segment 4 address. */
	uint32_t dseg_4_length;		/* Data segment 4 length. */
	uint32_t dseg_5_address;	/* Data segment 5 address. */
	uint32_t dseg_5_length;		/* Data segment 5 length. */
	uint32_t dseg_6_address;	/* Data segment 6 address. */
	uint32_t dseg_6_length;		/* Data segment 6 length. */
	struct dsd32 dsd[7];
} cont_entry_t;

/*
@@ -1821,16 +1804,7 @@ typedef struct {
	uint8_t entry_count;		/* Entry count. */
	uint8_t sys_define;		/* System defined. */
	uint8_t entry_status;		/* Entry Status. */
	uint32_t dseg_0_address[2];	/* Data segment 0 address. */
	uint32_t dseg_0_length;		/* Data segment 0 length. */
	uint32_t dseg_1_address[2];	/* Data segment 1 address. */
	uint32_t dseg_1_length;		/* Data segment 1 length. */
	uint32_t dseg_2_address	[2];	/* Data segment 2 address. */
	uint32_t dseg_2_length;		/* Data segment 2 length. */
	uint32_t dseg_3_address[2];	/* Data segment 3 address. */
	uint32_t dseg_3_length;		/* Data segment 3 length. */
	uint32_t dseg_4_address[2];	/* Data segment 4 address. */
	uint32_t dseg_4_length;		/* Data segment 4 length. */
	struct dsd64 dsd[5];
} cont_a64_entry_t;

#define PO_MODE_DIF_INSERT	0
@@ -1874,8 +1848,7 @@ struct crc_context {
			uint16_t	reserved_2;
			uint16_t	reserved_3;
			uint32_t	reserved_4;
			uint32_t	data_address[2];
			uint32_t	data_length;
			struct dsd64	data_dsd;
			uint32_t	reserved_5[2];
			uint32_t	reserved_6;
		} nobundling;
@@ -1885,11 +1858,8 @@ struct crc_context {
			uint16_t	reserved_1;
			__le16	dseg_count;	/* Data segment count */
			uint32_t	reserved_2;
			uint32_t	data_address[2];
			uint32_t	data_length;
			uint32_t	dif_address[2];
			uint32_t	dif_length;	/* Data segment 0
							 * length */
			struct dsd64	data_dsd;
			struct dsd64	dif_dsd;
		} bundling;
	} u;

@@ -2088,10 +2058,8 @@ typedef struct {
	uint32_t handle2;
	uint32_t rsp_bytecount;
	uint32_t req_bytecount;
	uint32_t dseg_req_address[2];	/* Data segment 0 address. */
	uint32_t dseg_req_length;	/* Data segment 0 length. */
	uint32_t dseg_rsp_address[2];	/* Data segment 1 address. */
	uint32_t dseg_rsp_length;	/* Data segment 1 length. */
	struct dsd64 req_dsd;
	struct dsd64 rsp_dsd;
} ms_iocb_entry_t;


+30 −0
Original line number Diff line number Diff line
#ifndef _QLA_DSD_H_
#define _QLA_DSD_H_

/* 32-bit data segment descriptor (8 bytes) */
struct dsd32 {
	__le32 address;
	__le32 length;
};

static inline void append_dsd32(struct dsd32 **dsd, struct scatterlist *sg)
{
	put_unaligned_le32(sg_dma_address(sg), &(*dsd)->address);
	put_unaligned_le32(sg_dma_len(sg),     &(*dsd)->length);
	(*dsd)++;
}

/* 64-bit data segment descriptor (12 bytes) */
struct dsd64 {
	__le64 address;
	__le32 length;
} __packed;

static inline void append_dsd64(struct dsd64 **dsd, struct scatterlist *sg)
{
	put_unaligned_le64(sg_dma_address(sg), &(*dsd)->address);
	put_unaligned_le32(sg_dma_len(sg),     &(*dsd)->length);
	(*dsd)++;
}

#endif
+8 −14
Original line number Diff line number Diff line
@@ -10,6 +10,8 @@
#include <linux/nvme.h>
#include <linux/nvme-fc.h>

#include "qla_dsd.h"

#define MBS_CHECKSUM_ERROR	0x4010
#define MBS_INVALID_PRODUCT_KEY	0x4020

@@ -463,8 +465,7 @@ struct cmd_bidir {
	uint8_t port_id[3];			/* PortID of destination port.*/
	uint8_t vp_index;

	uint32_t fcp_data_dseg_address[2];	/* Data segment address. */
	uint16_t fcp_data_dseg_len;		/* Data segment length. */
	struct dsd64 fcp_dsd;
};

#define COMMAND_TYPE_6	0x48		/* Command Type 6 entry */
@@ -501,8 +502,7 @@ struct cmd_type_6 {
	uint8_t port_id[3];		/* PortID of destination port. */
	uint8_t vp_index;

	uint32_t fcp_data_dseg_address[2];	/* Data segment address. */
	uint32_t fcp_data_dseg_len;		/* Data segment length. */
	struct dsd64 fcp_dsd;
};

#define COMMAND_TYPE_7	0x18		/* Command Type 7 entry */
@@ -548,8 +548,7 @@ struct cmd_type_7 {
	uint8_t port_id[3];		/* PortID of destination port. */
	uint8_t vp_index;

	uint32_t dseg_0_address[2];	/* Data segment 0 address. */
	uint32_t dseg_0_len;		/* Data segment 0 length. */
	struct dsd64 dsd;
};

#define COMMAND_TYPE_CRC_2	0x6A	/* Command Type CRC_2 (Type 6)
@@ -717,10 +716,7 @@ struct ct_entry_24xx {
	uint32_t rsp_byte_count;
	uint32_t cmd_byte_count;

	uint32_t dseg_0_address[2];	/* Data segment 0 address. */
	uint32_t dseg_0_len;		/* Data segment 0 length. */
	uint32_t dseg_1_address[2];	/* Data segment 1 address. */
	uint32_t dseg_1_len;		/* Data segment 1 length. */
	struct dsd64 dsd[2];
};

/*
@@ -1606,8 +1602,7 @@ struct verify_chip_entry_84xx {
	uint32_t fw_seq_size;
	uint32_t relative_offset;

	uint32_t dseg_address[2];
	uint32_t dseg_length;
	struct dsd64 dsd;
};

struct verify_chip_rsp_84xx {
@@ -1664,8 +1659,7 @@ struct access_chip_84xx {
	uint32_t total_byte_cnt;
	uint32_t reserved4;

	uint32_t dseg_address[2];
	uint32_t dseg_length;
	struct dsd64 dsd;
};

struct access_chip_rsp_84xx {
+3 −3
Original line number Diff line number Diff line
@@ -287,11 +287,11 @@ extern void *qla2x00_alloc_iocbs(struct scsi_qla_host *, srb_t *);
extern void *__qla2x00_alloc_iocbs(struct qla_qpair *, srb_t *);
extern int qla2x00_issue_marker(scsi_qla_host_t *, int);
extern int qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *, srb_t *,
	uint32_t *, uint16_t, struct qla_tc_param *);
	struct dsd64 *, uint16_t, struct qla_tc_param *);
extern int qla24xx_walk_and_build_sglist(struct qla_hw_data *, srb_t *,
	uint32_t *, uint16_t, struct qla_tc_param *);
	struct dsd64 *, uint16_t, struct qla_tc_param *);
extern int qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *, srb_t *,
	uint32_t *, uint16_t, struct qla_tgt_cmd *);
	struct dsd64 *, uint16_t, struct qla_tgt_cmd *);
extern int qla24xx_get_one_block_sg(uint32_t, struct qla2_sgx *, uint32_t *);
extern int qla24xx_configure_prot_mode(srb_t *, uint16_t *);

Loading