Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 20406
b: refs/heads/master
c: faead26
h: refs/heads/master
v: v3
  • Loading branch information
James Bottomley authored and unknown committed Feb 14, 2006
1 parent 80546fe commit 78c1154
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e2230eac17486e2ee07091d54d898eb40bcd0fdd
refs/heads/master: faead26d7a06605add627f29aee73ba654ce11f9
59 changes: 59 additions & 0 deletions trunk/drivers/scsi/scsi_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/hardirq.h>

#include <scsi/scsi.h>
#include <scsi/scsi_dbg.h>
Expand Down Expand Up @@ -2248,3 +2249,61 @@ scsi_target_unblock(struct device *dev)
device_for_each_child(dev, NULL, target_unblock);
}
EXPORT_SYMBOL_GPL(scsi_target_unblock);


struct work_queue_work {
struct work_struct work;
void (*fn)(void *);
void *data;
};

static void execute_in_process_context_work(void *data)
{
void (*fn)(void *data);
struct work_queue_work *wqw = data;

fn = wqw->fn;
data = wqw->data;

kfree(wqw);

fn(data);
}

/**
* scsi_execute_in_process_context - reliably execute the routine with user context
* @fn: the function to execute
* @data: data to pass to the function
*
* Executes the function immediately if process context is available,
* otherwise schedules the function for delayed execution.
*
* Returns: 0 - function was executed
* 1 - function was scheduled for execution
* <0 - error
*/
int scsi_execute_in_process_context(void (*fn)(void *data), void *data)
{
struct work_queue_work *wqw;

if (!in_interrupt()) {
fn(data);
return 0;
}

wqw = kmalloc(sizeof(struct work_queue_work), GFP_ATOMIC);

if (unlikely(!wqw)) {
printk(KERN_ERR "Failed to allocate memory\n");
WARN_ON(1);
return -ENOMEM;
}

INIT_WORK(&wqw->work, execute_in_process_context_work, wqw);
wqw->fn = fn;
wqw->data = data;
schedule_work(&wqw->work);

return 1;
}
EXPORT_SYMBOL_GPL(scsi_execute_in_process_context);
2 changes: 2 additions & 0 deletions trunk/include/scsi/scsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -433,4 +433,6 @@ struct scsi_lun {
/* Used to obtain the PCI location of a device */
#define SCSI_IOCTL_GET_PCI 0x5387

int scsi_execute_in_process_context(void (*fn)(void *data), void *data);

#endif /* _SCSI_SCSI_H */

0 comments on commit 78c1154

Please sign in to comment.