Commit 6b0eea21 authored by FUJITA Tomonori's avatar FUJITA Tomonori Committed by James Bottomley

[SCSI] megaraid: fix mega_internal_command oops

scsi_cmnd->cmnd was changed from a static array to a pointer post
2.6.25. It breaks mega_internal_command():

static int
mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru)
{
...
	scb = &adapter->int_scb;
	memset(scb, 0, sizeof(scb_t));

	scmd = &adapter->int_scmd;
	memset(scmd, 0, sizeof(Scsi_Cmnd));

	sdev = kzalloc(sizeof(struct scsi_device), GFP_KERNEL);
	scmd->device = sdev;

	scmd->device->host = adapter->host;
	scmd->host_scribble = (void *)scb;
	scmd->cmnd[0] = MEGA_INTERNAL_CMD;

mega_internal_command() uses scsi_cmnd allocated internally so
scmd->cmnd is NULL here. This patch adds a static array for cdb to
adapter_t and uses it here. This also uses
scsi_allocate_command/scsi_free_command, the recommended way to
allocate struct scsi_cmnd since the driver might use sense_buffer in
struct scsi_cmnd.
Signed-off-by: default avatarFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Reviewed-by: default avatarBoaz Harrosh <bharrosh@panasas.com>
Tested-by: default avatarPascal Terjan <pterjan@gmail.com>
Reported-by: default avatarPascal Terjan <pterjan@gmail.com>
Acked-by: default avatar"Yang, Bo" <Bo.Yang@lsi.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent 75fa6770
...@@ -4402,6 +4402,10 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru) ...@@ -4402,6 +4402,10 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru)
scb_t *scb; scb_t *scb;
int rval; int rval;
scmd = scsi_allocate_command(GFP_KERNEL);
if (!scmd)
return -ENOMEM;
/* /*
* The internal commands share one command id and hence are * The internal commands share one command id and hence are
* serialized. This is so because we want to reserve maximum number of * serialized. This is so because we want to reserve maximum number of
...@@ -4412,12 +4416,11 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru) ...@@ -4412,12 +4416,11 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru)
scb = &adapter->int_scb; scb = &adapter->int_scb;
memset(scb, 0, sizeof(scb_t)); memset(scb, 0, sizeof(scb_t));
scmd = &adapter->int_scmd;
memset(scmd, 0, sizeof(Scsi_Cmnd));
sdev = kzalloc(sizeof(struct scsi_device), GFP_KERNEL); sdev = kzalloc(sizeof(struct scsi_device), GFP_KERNEL);
scmd->device = sdev; scmd->device = sdev;
memset(adapter->int_cdb, 0, sizeof(adapter->int_cdb));
scmd->cmnd = adapter->int_cdb;
scmd->device->host = adapter->host; scmd->device->host = adapter->host;
scmd->host_scribble = (void *)scb; scmd->host_scribble = (void *)scb;
scmd->cmnd[0] = MEGA_INTERNAL_CMD; scmd->cmnd[0] = MEGA_INTERNAL_CMD;
...@@ -4456,6 +4459,8 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru) ...@@ -4456,6 +4459,8 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru)
mutex_unlock(&adapter->int_mtx); mutex_unlock(&adapter->int_mtx);
scsi_free_command(GFP_KERNEL, scmd);
return rval; return rval;
} }
......
...@@ -888,8 +888,8 @@ typedef struct { ...@@ -888,8 +888,8 @@ typedef struct {
u8 sglen; /* f/w supported scatter-gather list length */ u8 sglen; /* f/w supported scatter-gather list length */
unsigned char int_cdb[MAX_COMMAND_SIZE];
scb_t int_scb; scb_t int_scb;
Scsi_Cmnd int_scmd;
struct mutex int_mtx; /* To synchronize the internal struct mutex int_mtx; /* To synchronize the internal
commands */ commands */
struct completion int_waitq; /* wait queue for internal struct completion int_waitq; /* wait queue for internal
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment