Commit 6b0eea21efed26f92e18741e54a3121cf5cd197e

Authored by FUJITA Tomonori
Committed by James Bottomley
1 parent 75fa67706c

[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: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Reviewed-by: Boaz Harrosh <bharrosh@panasas.com>
Tested-by: Pascal Terjan <pterjan@gmail.com>
Reported-by: Pascal Terjan <pterjan@gmail.com>
Acked-by: "Yang, Bo" <Bo.Yang@lsi.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>

Showing 2 changed files with 9 additions and 4 deletions Side-by-side Diff

drivers/scsi/megaraid.c
... ... @@ -4402,6 +4402,10 @@
4402 4402 scb_t *scb;
4403 4403 int rval;
4404 4404  
  4405 + scmd = scsi_allocate_command(GFP_KERNEL);
  4406 + if (!scmd)
  4407 + return -ENOMEM;
  4408 +
4405 4409 /*
4406 4410 * The internal commands share one command id and hence are
4407 4411 * serialized. This is so because we want to reserve maximum number of
4408 4412  
... ... @@ -4412,12 +4416,11 @@
4412 4416 scb = &adapter->int_scb;
4413 4417 memset(scb, 0, sizeof(scb_t));
4414 4418  
4415   - scmd = &adapter->int_scmd;
4416   - memset(scmd, 0, sizeof(Scsi_Cmnd));
4417   -
4418 4419 sdev = kzalloc(sizeof(struct scsi_device), GFP_KERNEL);
4419 4420 scmd->device = sdev;
4420 4421  
  4422 + memset(adapter->int_cdb, 0, sizeof(adapter->int_cdb));
  4423 + scmd->cmnd = adapter->int_cdb;
4421 4424 scmd->device->host = adapter->host;
4422 4425 scmd->host_scribble = (void *)scb;
4423 4426 scmd->cmnd[0] = MEGA_INTERNAL_CMD;
... ... @@ -4455,6 +4458,8 @@
4455 4458 }
4456 4459  
4457 4460 mutex_unlock(&adapter->int_mtx);
  4461 +
  4462 + scsi_free_command(GFP_KERNEL, scmd);
4458 4463  
4459 4464 return rval;
4460 4465 }
drivers/scsi/megaraid.h
... ... @@ -888,8 +888,8 @@
888 888  
889 889 u8 sglen; /* f/w supported scatter-gather list length */
890 890  
  891 + unsigned char int_cdb[MAX_COMMAND_SIZE];
891 892 scb_t int_scb;
892   - Scsi_Cmnd int_scmd;
893 893 struct mutex int_mtx; /* To synchronize the internal
894 894 commands */
895 895 struct completion int_waitq; /* wait queue for internal