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

Commit cb59aa6a authored by Sumant Patro's avatar Sumant Patro Committed by James Bottomley
Browse files

[SCSI] megaraid_sas: cleanup queue command path



This patch (originally submitted by Christoph Hellwig) removes code
duplication in megasas_build_cmd.  It also defines
MEGASAS_IOC_FIRMWARE32 to allow 64 bit compiled applications to work.

Signed-off-by: default avatarSumant Patro <Sumant.Patro@lsil.com>

Rejections fixed and
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent bb1d1073
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
1 Release Date    : Mon Dec 19 14:36:26 PST 2005 - Sumant Patro <Sumant.Patro@lsil.com>
2 Current Version : 00.00.02.00-rc4 
3 Older Version   : 00.00.02.01 

i.	Code reorganized to remove code duplication in megasas_build_cmd. 

	"There's a lot of duplicate code megasas_build_cmd.  Move that out of the different codepathes and merge the reminder of megasas_build_cmd into megasas_queue_command"

		- Christoph Hellwig <hch@lst.de>

ii.	Defined MEGASAS_IOC_FIRMWARE32 for code paths that handles 32 bit applications in 64 bit systems.

	"MEGASAS_IOC_FIRMWARE can't be redefined if CONFIG_COMPAT is set, we need to define a MEGASAS_IOC_FIRMWARE32 define so native binaries continue to work"

		- Christoph Hellwig <hch@lst.de>
+48 −112
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@
 *	   2 of the License, or (at your option) any later version.
 *
 * FILE		: megaraid_sas.c
 * Version	: v00.00.02.00-rc4
 * Version	: v00.00.02.01
 *
 * Authors:
 * 	Sreenivas Bagalkote	<Sreenivas.Bagalkote@lsil.com>
@@ -558,36 +558,17 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
}

/**
 * megasas_build_cmd -	Prepares a command packet
 * @instance:		Adapter soft state
 * @scp:		SCSI command
 * @frame_count:	[OUT] Number of frames used to prepare this command
 * megasas_is_ldio -		Checks if the cmd is for logical drive
 * @scmd:			SCSI command
 *	
 * Called by megasas_queue_command to find out if the command to be queued
 * is a logical drive command	
 */
static struct megasas_cmd *megasas_build_cmd(struct megasas_instance
						    *instance,
						    struct scsi_cmnd *scp,
						    int *frame_count)
static inline int megasas_is_ldio(struct scsi_cmnd *cmd)
{
	u32 logical_cmd;
	struct megasas_cmd *cmd;

	/*
	 * Find out if this is logical or physical drive command.
	 */
	logical_cmd = MEGASAS_IS_LOGICAL(scp);

	/*
	 * Logical drive command
	 */
	if (logical_cmd) {

		if (scp->device->id >= MEGASAS_MAX_LD) {
			scp->result = DID_BAD_TARGET << 16;
			return NULL;
		}

		switch (scp->cmnd[0]) {

	if (!MEGASAS_IS_LOGICAL(cmd))
		return 0;
	switch (cmd->cmnd[0]) {
	case READ_10:
	case WRITE_10:
	case READ_12:
@@ -596,74 +577,10 @@ static struct megasas_cmd *megasas_build_cmd(struct megasas_instance
	case WRITE_6:
	case READ_16:
	case WRITE_16:
			/*
			 * Fail for LUN > 0
			 */
			if (scp->device->lun) {
				scp->result = DID_BAD_TARGET << 16;
				return NULL;
			}

			cmd = megasas_get_cmd(instance);

			if (!cmd) {
				scp->result = DID_IMM_RETRY << 16;
				return NULL;
			}

			*frame_count = megasas_build_ldio(instance, scp, cmd);

			if (!(*frame_count)) {
				megasas_return_cmd(instance, cmd);
				return NULL;
			}

			return cmd;

		return 1;
	default:
			/*
			 * Fail for LUN > 0
			 */
			if (scp->device->lun) {
				scp->result = DID_BAD_TARGET << 16;
				return NULL;
			}

			cmd = megasas_get_cmd(instance);

			if (!cmd) {
				scp->result = DID_IMM_RETRY << 16;
				return NULL;
			}

			*frame_count = megasas_build_dcdb(instance, scp, cmd);

			if (!(*frame_count)) {
				megasas_return_cmd(instance, cmd);
				return NULL;
			}

			return cmd;
		}
	} else {
		cmd = megasas_get_cmd(instance);

		if (!cmd) {
			scp->result = DID_IMM_RETRY << 16;
			return NULL;
		}

		*frame_count = megasas_build_dcdb(instance, scp, cmd);

		if (!(*frame_count)) {
			megasas_return_cmd(instance, cmd);
			return NULL;
		}

		return cmd;
		return 0;
	}

	return NULL;
}

/**
@@ -684,13 +601,27 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
	scmd->scsi_done = done;
	scmd->result = 0;

	cmd = megasas_build_cmd(instance, scmd, &frame_count);

	if (!cmd) {
		done(scmd);
		return 0;
	if (MEGASAS_IS_LOGICAL(scmd) &&
	    (scmd->device->id >= MEGASAS_MAX_LD || scmd->device->lun)) {
		scmd->result = DID_BAD_TARGET << 16;
		goto out_done;
	}

	cmd = megasas_get_cmd(instance);
	if (!cmd)
		return SCSI_MLQUEUE_HOST_BUSY;

	/*
	 * Logical drive command
	 */
	if (megasas_is_ldio(scmd))
		frame_count = megasas_build_ldio(instance, scmd, cmd);
	else
		frame_count = megasas_build_dcdb(instance, scmd, cmd);

	if (!frame_count)
		goto out_return_cmd;

	cmd->scmd = scmd;
	scmd->SCp.ptr = (char *)cmd;
	scmd->SCp.sent_command = jiffies;
@@ -706,6 +637,12 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
	       &instance->reg_set->inbound_queue_port);

	return 0;

 out_return_cmd:
	megasas_return_cmd(instance, cmd);
 out_done:
	done(scmd);
	return 0;
}

/**
@@ -2681,9 +2618,8 @@ megasas_mgmt_compat_ioctl(struct file *file, unsigned int cmd,
			  unsigned long arg)
{
	switch (cmd) {
	case MEGASAS_IOC_FIRMWARE:{
	case MEGASAS_IOC_FIRMWARE32:
		return megasas_mgmt_compat_ioctl_fw(file, arg);
		}
	case MEGASAS_IOC_GET_AEN:
		return megasas_mgmt_ioctl_aen(file, arg);
	}
+5 −7
Original line number Diff line number Diff line
@@ -18,10 +18,9 @@
/**
 * MegaRAID SAS Driver meta data
 */
#define MEGASAS_VERSION				"00.00.02.00-rc4"
#define MEGASAS_RELDATE				"Sep 16, 2005"
#define MEGASAS_EXT_VERSION			"Fri Sep 16 12:37:08 EDT 2005"

#define MEGASAS_VERSION				"00.00.02.01"
#define MEGASAS_RELDATE				"Dec 19, 2005"
#define MEGASAS_EXT_VERSION			"Mon Dec 19 14:36:26 PST 2005"
/*
 * =====================================
 * MegaRAID SAS MFI firmware definitions
@@ -1125,11 +1124,10 @@ struct compat_megasas_iocpacket {
	struct compat_iovec sgl[MAX_IOCTL_SGE];
} __attribute__ ((packed));

#define MEGASAS_IOC_FIRMWARE	_IOWR('M', 1, struct compat_megasas_iocpacket)
#else
#define MEGASAS_IOC_FIRMWARE	_IOWR('M', 1, struct megasas_iocpacket)
#endif

#define MEGASAS_IOC_FIRMWARE	_IOWR('M', 1, struct megasas_iocpacket)
#define MEGASAS_IOC_FIRMWARE32	_IOWR('M', 1, struct compat_megasas_iocpacket)
#define MEGASAS_IOC_GET_AEN	_IOW('M', 3, struct megasas_aen)

struct megasas_mgmt_info {