diff -Naur linux2.6.orig/Documentation/scsi/ChangeLog.megaraid_sas linux2.6/Documentation/scsi/ChangeLog.megaraid_sas --- linux2.6.orig/Documentation/scsi/ChangeLog.megaraid_sas 1969-12-31 16:00:00.000000000 -0800 +++ linux2.6/Documentation/scsi/ChangeLog.megaraid_sas 2005-12-19 14:37:33.000000000 -0800 @@ -0,0 +1,15 @@ +1 Release Date : Mon Dec 19 14:36:26 PST 2005 - Sumant Patro +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 + +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 diff -Naur linux2.6.orig/drivers/scsi/megaraid/megaraid_sas.c linux2.6/drivers/scsi/megaraid/megaraid_sas.c --- linux2.6.orig/drivers/scsi/megaraid/megaraid_sas.c 2005-12-15 14:08:21.000000000 -0800 +++ linux2.6/drivers/scsi/megaraid/megaraid_sas.c 2005-12-19 14:36:16.000000000 -0800 @@ -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 @@ -557,112 +557,29 @@ } /** - * 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 inline 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]) { - - case READ_10: - case WRITE_10: - case READ_12: - case WRITE_12: - case READ_6: - 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; - - 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; + if (!MEGASAS_IS_LOGICAL(cmd)) + return 0; + switch (cmd->cmnd[0]) { + case READ_10: + case WRITE_10: + case READ_12: + case WRITE_12: + case READ_6: + case WRITE_6: + case READ_16: + case WRITE_16: + return 1; + default: + return 0; } - - return NULL; } /** @@ -683,13 +600,27 @@ 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; @@ -705,6 +636,12 @@ &instance->reg_set->inbound_queue_port); return 0; + + out_return_cmd: + megasas_return_cmd(instance, cmd); + out_done: + done(scmd); + return 0; } /** @@ -2680,9 +2617,8 @@ unsigned long arg) { switch (cmd) { - case MEGASAS_IOC_FIRMWARE:{ - return megasas_mgmt_compat_ioctl_fw(file, arg); - } + case MEGASAS_IOC_FIRMWARE32: + return megasas_mgmt_compat_ioctl_fw(file, arg); case MEGASAS_IOC_GET_AEN: return megasas_mgmt_ioctl_aen(file, arg); } diff -Naur linux2.6.orig/drivers/scsi/megaraid/megaraid_sas.h linux2.6/drivers/scsi/megaraid/megaraid_sas.h --- linux2.6.orig/drivers/scsi/megaraid/megaraid_sas.h 2005-12-15 14:08:21.000000000 -0800 +++ linux2.6/drivers/scsi/megaraid/megaraid_sas.h 2005-12-19 14:29:32.000000000 -0800 @@ -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_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 {