Commit 6b0eea21efed26f92e18741e54a3121cf5cd197e
Committed by
James Bottomley
1 parent
75fa67706c
Exists in
master
and in
20 other branches
[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 |