diff options
Diffstat (limited to 'drivers/scsi/megaraid/megaraid_sas_fusion.c')
| -rw-r--r-- | drivers/scsi/megaraid/megaraid_sas_fusion.c | 27 | 
1 files changed, 12 insertions, 15 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index ddf094e7d0a..74030aff69a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1,7 +1,7 @@  /*   *  Linux MegaRAID driver for SAS based RAID controllers   * - *  Copyright (c) 2009-2011  LSI Corporation. + *  Copyright (c) 2009-2012  LSI Corporation.   *   *  This program is free software; you can redistribute it and/or   *  modify it under the terms of the GNU General Public License @@ -1184,8 +1184,6 @@ megasas_set_pd_lba(struct MPI2_RAID_SCSI_IO_REQUEST *io_request, u8 cdb_len,  		io_request->CDB.EEDP32.PrimaryReferenceTag =  			cpu_to_be32(ref_tag);  		io_request->CDB.EEDP32.PrimaryApplicationTagMask = 0xffff; - -		io_request->DataLength = num_blocks * 512;  		io_request->IoFlags = 32; /* Specify 32-byte cdb */  		/* Transfer length */ @@ -1329,7 +1327,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,  			  struct megasas_cmd_fusion *cmd)  {  	u8 fp_possible; -	u32 start_lba_lo, start_lba_hi, device_id; +	u32 start_lba_lo, start_lba_hi, device_id, datalength = 0;  	struct MPI2_RAID_SCSI_IO_REQUEST *io_request;  	union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;  	struct IO_REQUEST_INFO io_info; @@ -1355,7 +1353,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,  	 * 6-byte READ(0x08) or WRITE(0x0A) cdb  	 */  	if (scp->cmd_len == 6) { -		io_request->DataLength = (u32) scp->cmnd[4]; +		datalength = (u32) scp->cmnd[4];  		start_lba_lo = ((u32) scp->cmnd[1] << 16) |  			((u32) scp->cmnd[2] << 8) | (u32) scp->cmnd[3]; @@ -1366,7 +1364,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,  	 * 10-byte READ(0x28) or WRITE(0x2A) cdb  	 */  	else if (scp->cmd_len == 10) { -		io_request->DataLength = (u32) scp->cmnd[8] | +		datalength = (u32) scp->cmnd[8] |  			((u32) scp->cmnd[7] << 8);  		start_lba_lo = ((u32) scp->cmnd[2] << 24) |  			((u32) scp->cmnd[3] << 16) | @@ -1377,7 +1375,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,  	 * 12-byte READ(0xA8) or WRITE(0xAA) cdb  	 */  	else if (scp->cmd_len == 12) { -		io_request->DataLength = ((u32) scp->cmnd[6] << 24) | +		datalength = ((u32) scp->cmnd[6] << 24) |  			((u32) scp->cmnd[7] << 16) |  			((u32) scp->cmnd[8] << 8) | (u32) scp->cmnd[9];  		start_lba_lo = ((u32) scp->cmnd[2] << 24) | @@ -1389,7 +1387,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,  	 * 16-byte READ(0x88) or WRITE(0x8A) cdb  	 */  	else if (scp->cmd_len == 16) { -		io_request->DataLength = ((u32) scp->cmnd[10] << 24) | +		datalength = ((u32) scp->cmnd[10] << 24) |  			((u32) scp->cmnd[11] << 16) |  			((u32) scp->cmnd[12] << 8) | (u32) scp->cmnd[13];  		start_lba_lo = ((u32) scp->cmnd[6] << 24) | @@ -1403,8 +1401,9 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,  	memset(&io_info, 0, sizeof(struct IO_REQUEST_INFO));  	io_info.ldStartBlock = ((u64)start_lba_hi << 32) | start_lba_lo; -	io_info.numBlocks = io_request->DataLength; +	io_info.numBlocks = datalength;  	io_info.ldTgtId = device_id; +	io_request->DataLength = scsi_bufflen(scp);  	if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)  		io_info.isRead = 1; @@ -1431,7 +1430,6 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,  	if (fp_possible) {  		megasas_set_pd_lba(io_request, scp->cmd_len, &io_info, scp,  				   local_map_ptr, start_lba_lo); -		io_request->DataLength = scsi_bufflen(scp);  		io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;  		cmd->request_desc->SCSIIO.RequestFlags =  			(MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY @@ -1510,7 +1508,8 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance,  	local_map_ptr = fusion->ld_map[(instance->map_id & 1)];  	/* Check if this is a system PD I/O */ -	if (instance->pd_list[pd_index].driveState == MR_PD_STATE_SYSTEM) { +	if (scmd->device->channel < MEGASAS_MAX_PD_CHANNELS && +	    instance->pd_list[pd_index].driveState == MR_PD_STATE_SYSTEM) {  		io_request->Function = 0;  		io_request->DevHandle =  			local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl; @@ -1525,6 +1524,8 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance,  		cmd->request_desc->SCSIIO.RequestFlags =  			(MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<  			 MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); +		cmd->request_desc->SCSIIO.DevHandle = +			local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;  	} else {  		io_request->Function  = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;  		io_request->DevHandle = device_id; @@ -1732,8 +1733,6 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)  	if (reply_descript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED)  		return IRQ_NONE; -	d_val.word = desc->Words; -  	num_completed = 0;  	while ((d_val.u.low != UINT_MAX) && (d_val.u.high != UINT_MAX)) { @@ -1855,10 +1854,8 @@ megasas_complete_cmd_dpc_fusion(unsigned long instance_addr)  	}  	spin_unlock_irqrestore(&instance->hba_lock, flags); -	spin_lock_irqsave(&instance->completion_lock, flags);  	for (MSIxIndex = 0 ; MSIxIndex < count; MSIxIndex++)  		complete_cmd_fusion(instance, MSIxIndex); -	spin_unlock_irqrestore(&instance->completion_lock, flags);  }  /**  |