mirror of https://gitee.com/openkylin/linux.git
[SCSI] arcmsr: fix message allocation
arcmsr_iop_message_xfer() is called from atomic context under the queuecommand scsi_host_template handler. James Bottomley pointed out that the current GFP_KERNEL|GFP_DMA flags are wrong: firstly we are in atomic context, secondly this memory is not used for DMA. Also removed some unneeded casts. Signed-off-by: Daniel Drake <dsd@gentoo.org> Cc: Nick Cheng <nick.cheng@areca.com.tw> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
parent
ad008d42bc
commit
69e562c234
|
@ -1387,18 +1387,16 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \
|
||||||
switch(controlcode) {
|
switch(controlcode) {
|
||||||
|
|
||||||
case ARCMSR_MESSAGE_READ_RQBUFFER: {
|
case ARCMSR_MESSAGE_READ_RQBUFFER: {
|
||||||
unsigned long *ver_addr;
|
unsigned char *ver_addr;
|
||||||
uint8_t *pQbuffer, *ptmpQbuffer;
|
uint8_t *pQbuffer, *ptmpQbuffer;
|
||||||
int32_t allxfer_len = 0;
|
int32_t allxfer_len = 0;
|
||||||
void *tmp;
|
|
||||||
|
|
||||||
tmp = kmalloc(1032, GFP_KERNEL|GFP_DMA);
|
ver_addr = kmalloc(1032, GFP_ATOMIC);
|
||||||
ver_addr = (unsigned long *)tmp;
|
if (!ver_addr) {
|
||||||
if (!tmp) {
|
|
||||||
retvalue = ARCMSR_MESSAGE_FAIL;
|
retvalue = ARCMSR_MESSAGE_FAIL;
|
||||||
goto message_out;
|
goto message_out;
|
||||||
}
|
}
|
||||||
ptmpQbuffer = (uint8_t *) ver_addr;
|
ptmpQbuffer = ver_addr;
|
||||||
while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex)
|
while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex)
|
||||||
&& (allxfer_len < 1031)) {
|
&& (allxfer_len < 1031)) {
|
||||||
pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex];
|
pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex];
|
||||||
|
@ -1427,26 +1425,24 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \
|
||||||
}
|
}
|
||||||
arcmsr_iop_message_read(acb);
|
arcmsr_iop_message_read(acb);
|
||||||
}
|
}
|
||||||
memcpy(pcmdmessagefld->messagedatabuffer, (uint8_t *)ver_addr, allxfer_len);
|
memcpy(pcmdmessagefld->messagedatabuffer, ver_addr, allxfer_len);
|
||||||
pcmdmessagefld->cmdmessage.Length = allxfer_len;
|
pcmdmessagefld->cmdmessage.Length = allxfer_len;
|
||||||
pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
|
pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
|
||||||
kfree(tmp);
|
kfree(ver_addr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
|
case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
|
||||||
unsigned long *ver_addr;
|
unsigned char *ver_addr;
|
||||||
int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
|
int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
|
||||||
uint8_t *pQbuffer, *ptmpuserbuffer;
|
uint8_t *pQbuffer, *ptmpuserbuffer;
|
||||||
void *tmp;
|
|
||||||
|
|
||||||
tmp = kmalloc(1032, GFP_KERNEL|GFP_DMA);
|
ver_addr = kmalloc(1032, GFP_ATOMIC);
|
||||||
ver_addr = (unsigned long *)tmp;
|
if (!ver_addr) {
|
||||||
if (!tmp) {
|
|
||||||
retvalue = ARCMSR_MESSAGE_FAIL;
|
retvalue = ARCMSR_MESSAGE_FAIL;
|
||||||
goto message_out;
|
goto message_out;
|
||||||
}
|
}
|
||||||
ptmpuserbuffer = (uint8_t *)ver_addr;
|
ptmpuserbuffer = ver_addr;
|
||||||
user_len = pcmdmessagefld->cmdmessage.Length;
|
user_len = pcmdmessagefld->cmdmessage.Length;
|
||||||
memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len);
|
memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len);
|
||||||
wqbuf_lastindex = acb->wqbuf_lastindex;
|
wqbuf_lastindex = acb->wqbuf_lastindex;
|
||||||
|
@ -1492,7 +1488,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \
|
||||||
retvalue = ARCMSR_MESSAGE_FAIL;
|
retvalue = ARCMSR_MESSAGE_FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
kfree(tmp);
|
kfree(ver_addr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue