Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 77023
b: refs/heads/master
c: ad84db2
h: refs/heads/master
i:
  77021: 064a3e4
  77019: c15eddb
  77015: faf3e99
  77007: e11f4c9
  76991: e92340e
v: v3
  • Loading branch information
bo yang authored and James Bottomley committed Jan 12, 2008
1 parent 7e18d95 commit ded6727
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 7 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7343eb6570ae3b299e7b5185b139d8335ef60e9b
refs/heads/master: ad84db2e2e1817bb8a29e7c9108eb66bf023d99f
152 changes: 146 additions & 6 deletions trunk/drivers/scsi/megaraid/megaraid_sas.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@
#include <scsi/scsi_host.h>
#include "megaraid_sas.h"

/*
* poll_mode_io:1- schedule complete completion from q cmd
*/
static unsigned int poll_mode_io;
module_param_named(poll_mode_io, poll_mode_io, int, 0);
MODULE_PARM_DESC(poll_mode_io,
"Complete cmds from IO path, (default=0)");

MODULE_LICENSE("GPL");
MODULE_VERSION(MEGASAS_VERSION);
MODULE_AUTHOR("megaraidlinux@lsi.com");
Expand Down Expand Up @@ -860,6 +868,12 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
atomic_inc(&instance->fw_outstanding);

instance->instancet->fire_cmd(cmd->frame_phys_addr ,cmd->frame_count-1,instance->reg_set);
/*
* Check if we have pend cmds to be completed
*/
if (poll_mode_io && atomic_read(&instance->fw_outstanding))
tasklet_schedule(&instance->isr_tasklet);


return 0;

Expand Down Expand Up @@ -1891,6 +1905,47 @@ megasas_issue_init_mfi(struct megasas_instance *instance)
return -EINVAL;
}

/**
* megasas_start_timer - Initializes a timer object
* @instance: Adapter soft state
* @timer: timer object to be initialized
* @fn: timer function
* @interval: time interval between timer function call
*/
static inline void
megasas_start_timer(struct megasas_instance *instance,
struct timer_list *timer,
void *fn, unsigned long interval)
{
init_timer(timer);
timer->expires = jiffies + interval;
timer->data = (unsigned long)instance;
timer->function = fn;
add_timer(timer);
}

/**
* megasas_io_completion_timer - Timer fn
* @instance_addr: Address of adapter soft state
*
* Schedules tasklet for cmd completion
* if poll_mode_io is set
*/
static void
megasas_io_completion_timer(unsigned long instance_addr)
{
struct megasas_instance *instance =
(struct megasas_instance *)instance_addr;

if (atomic_read(&instance->fw_outstanding))
tasklet_schedule(&instance->isr_tasklet);

/* Restart timer */
if (poll_mode_io)
mod_timer(&instance->io_completion_timer,
jiffies + MEGASAS_COMPLETION_TIMER_INTERVAL);
}

/**
* megasas_init_mfi - Initializes the FW
* @instance: Adapter soft state
Expand Down Expand Up @@ -2017,8 +2072,14 @@ static int megasas_init_mfi(struct megasas_instance *instance)
* Setup tasklet for cmd completion
*/

tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc,
(unsigned long)instance);
tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc,
(unsigned long)instance);

/* Initialize the cmd completion timer */
if (poll_mode_io)
megasas_start_timer(instance, &instance->io_completion_timer,
megasas_io_completion_timer,
MEGASAS_COMPLETION_TIMER_INTERVAL);
return 0;

fail_fw_init:
Expand Down Expand Up @@ -2578,8 +2639,8 @@ static void megasas_shutdown_controller(struct megasas_instance *instance,
}

/**
* megasas_suspend - driver suspend entry point
* @pdev: PCI device structure
* megasas_suspend - driver suspend entry point
* @pdev: PCI device structure
* @state: PCI power state to suspend routine
*/
static int __devinit
Expand All @@ -2591,6 +2652,9 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
instance = pci_get_drvdata(pdev);
host = instance->host;

if (poll_mode_io)
del_timer_sync(&instance->io_completion_timer);

megasas_flush_cache(instance);
megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN);
tasklet_kill(&instance->isr_tasklet);
Expand Down Expand Up @@ -2677,6 +2741,11 @@ megasas_resume(struct pci_dev *pdev)
if (megasas_start_aen(instance))
printk(KERN_ERR "megasas: Start AEN failed\n");

/* Initialize the cmd completion timer */
if (poll_mode_io)
megasas_start_timer(instance, &instance->io_completion_timer,
megasas_io_completion_timer,
MEGASAS_COMPLETION_TIMER_INTERVAL);
return 0;

fail_irq:
Expand Down Expand Up @@ -2715,6 +2784,9 @@ static void megasas_detach_one(struct pci_dev *pdev)
instance = pci_get_drvdata(pdev);
host = instance->host;

if (poll_mode_io)
del_timer_sync(&instance->io_completion_timer);

scsi_remove_host(instance->host);
megasas_flush_cache(instance);
megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
Expand Down Expand Up @@ -3188,7 +3260,7 @@ static DRIVER_ATTR(release_date, S_IRUGO, megasas_sysfs_show_release_date,
static ssize_t
megasas_sysfs_show_dbg_lvl(struct device_driver *dd, char *buf)
{
return sprintf(buf,"%u",megasas_dbg_lvl);
return sprintf(buf, "%u\n", megasas_dbg_lvl);
}

static ssize_t
Expand All @@ -3203,7 +3275,65 @@ megasas_sysfs_set_dbg_lvl(struct device_driver *dd, const char *buf, size_t coun
}

static DRIVER_ATTR(dbg_lvl, S_IRUGO|S_IWUGO, megasas_sysfs_show_dbg_lvl,
megasas_sysfs_set_dbg_lvl);
megasas_sysfs_set_dbg_lvl);

static ssize_t
megasas_sysfs_show_poll_mode_io(struct device_driver *dd, char *buf)
{
return sprintf(buf, "%u\n", poll_mode_io);
}

static ssize_t
megasas_sysfs_set_poll_mode_io(struct device_driver *dd,
const char *buf, size_t count)
{
int retval = count;
int tmp = poll_mode_io;
int i;
struct megasas_instance *instance;

if (sscanf(buf, "%u", &poll_mode_io) < 1) {
printk(KERN_ERR "megasas: could not set poll_mode_io\n");
retval = -EINVAL;
}

/*
* Check if poll_mode_io is already set or is same as previous value
*/
if ((tmp && poll_mode_io) || (tmp == poll_mode_io))
goto out;

if (poll_mode_io) {
/*
* Start timers for all adapters
*/
for (i = 0; i < megasas_mgmt_info.max_index; i++) {
instance = megasas_mgmt_info.instance[i];
if (instance) {
megasas_start_timer(instance,
&instance->io_completion_timer,
megasas_io_completion_timer,
MEGASAS_COMPLETION_TIMER_INTERVAL);
}
}
} else {
/*
* Delete timers for all adapters
*/
for (i = 0; i < megasas_mgmt_info.max_index; i++) {
instance = megasas_mgmt_info.instance[i];
if (instance)
del_timer_sync(&instance->io_completion_timer);
}
}

out:
return retval;
}

static DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUGO,
megasas_sysfs_show_poll_mode_io,
megasas_sysfs_set_poll_mode_io);

/**
* megasas_init - Driver load entry point
Expand Down Expand Up @@ -3254,8 +3384,16 @@ static int __init megasas_init(void)
&driver_attr_dbg_lvl);
if (rval)
goto err_dcf_dbg_lvl;
rval = driver_create_file(&megasas_pci_driver.driver,
&driver_attr_poll_mode_io);
if (rval)
goto err_dcf_poll_mode_io;

return rval;

err_dcf_poll_mode_io:
driver_remove_file(&megasas_pci_driver.driver,
&driver_attr_dbg_lvl);
err_dcf_dbg_lvl:
driver_remove_file(&megasas_pci_driver.driver,
&driver_attr_release_date);
Expand All @@ -3273,6 +3411,8 @@ static int __init megasas_init(void)
*/
static void __exit megasas_exit(void)
{
driver_remove_file(&megasas_pci_driver.driver,
&driver_attr_poll_mode_io);
driver_remove_file(&megasas_pci_driver.driver,
&driver_attr_dbg_lvl);
driver_remove_file(&megasas_pci_driver.driver,
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/scsi/megaraid/megaraid_sas.h
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,7 @@ struct megasas_ctrl_info {

#define MFI_OB_INTR_STATUS_MASK 0x00000002
#define MFI_POLL_TIMEOUT_SECS 60
#define MEGASAS_COMPLETION_TIMER_INTERVAL (HZ/10)

#define MFI_REPLY_1078_MESSAGE_INTERRUPT 0x80000000

Expand Down Expand Up @@ -1111,6 +1112,8 @@ struct megasas_instance {

u8 flag;
unsigned long last_time;

struct timer_list io_completion_timer;
};

#define MEGASAS_IS_LOGICAL(scp) \
Expand Down

0 comments on commit ded6727

Please sign in to comment.