aha1542: Allocate memory before taking a lock
The driver currently calls kmalloc with GFP_KERNEL while holding a lock. Fix it by doing the allocation earlier, before taking the lock. Tested on AHA-1542B. Signed-off-by: Ondrej Zary <linux@rainbow-software.org> Signed-off-by: James Bottomley <JBottomley@Odin.com>
This commit is contained in:
parent
35e9a9f939
commit
8c08a6215a
1 changed files with 11 additions and 12 deletions
|
@ -375,9 +375,10 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
|
||||||
u8 lun = cmd->device->lun;
|
u8 lun = cmd->device->lun;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int bufflen = scsi_bufflen(cmd);
|
int bufflen = scsi_bufflen(cmd);
|
||||||
int mbo;
|
int mbo, sg_count;
|
||||||
struct mailbox *mb = aha1542->mb;
|
struct mailbox *mb = aha1542->mb;
|
||||||
struct ccb *ccb = aha1542->ccb;
|
struct ccb *ccb = aha1542->ccb;
|
||||||
|
struct chain *cptr;
|
||||||
|
|
||||||
if (*cmd->cmnd == REQUEST_SENSE) {
|
if (*cmd->cmnd == REQUEST_SENSE) {
|
||||||
/* Don't do the command - we have the sense data already */
|
/* Don't do the command - we have the sense data already */
|
||||||
|
@ -397,6 +398,13 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
|
||||||
print_hex_dump_bytes("command: ", DUMP_PREFIX_NONE, cmd->cmnd, cmd->cmd_len);
|
print_hex_dump_bytes("command: ", DUMP_PREFIX_NONE, cmd->cmnd, cmd->cmd_len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (bufflen) { /* allocate memory before taking host_lock */
|
||||||
|
sg_count = scsi_sg_count(cmd);
|
||||||
|
cptr = kmalloc(sizeof(*cptr) * sg_count, GFP_KERNEL | GFP_DMA);
|
||||||
|
if (!cptr)
|
||||||
|
return SCSI_MLQUEUE_HOST_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
/* Use the outgoing mailboxes in a round-robin fashion, because this
|
/* Use the outgoing mailboxes in a round-robin fashion, because this
|
||||||
is how the host adapter will scan for them */
|
is how the host adapter will scan for them */
|
||||||
|
|
||||||
|
@ -441,19 +449,10 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
|
||||||
|
|
||||||
if (bufflen) {
|
if (bufflen) {
|
||||||
struct scatterlist *sg;
|
struct scatterlist *sg;
|
||||||
struct chain *cptr;
|
int i;
|
||||||
int i, sg_count = scsi_sg_count(cmd);
|
|
||||||
|
|
||||||
ccb[mbo].op = 2; /* SCSI Initiator Command w/scatter-gather */
|
ccb[mbo].op = 2; /* SCSI Initiator Command w/scatter-gather */
|
||||||
cmd->host_scribble = kmalloc(sizeof(*cptr)*sg_count,
|
cmd->host_scribble = (void *)cptr;
|
||||||
GFP_KERNEL | GFP_DMA);
|
|
||||||
cptr = (struct chain *) cmd->host_scribble;
|
|
||||||
if (cptr == NULL) {
|
|
||||||
/* free the claimed mailbox slot */
|
|
||||||
aha1542->int_cmds[mbo] = NULL;
|
|
||||||
spin_unlock_irqrestore(sh->host_lock, flags);
|
|
||||||
return SCSI_MLQUEUE_HOST_BUSY;
|
|
||||||
}
|
|
||||||
scsi_for_each_sg(cmd, sg, sg_count, i) {
|
scsi_for_each_sg(cmd, sg, sg_count, i) {
|
||||||
any2scsi(cptr[i].dataptr, isa_page_to_bus(sg_page(sg))
|
any2scsi(cptr[i].dataptr, isa_page_to_bus(sg_page(sg))
|
||||||
+ sg->offset);
|
+ sg->offset);
|
||||||
|
|
Loading…
Add table
Reference in a new issue