提交 c251a7be 编写于 作者: K Kees Cook

scsi: megaraid: Convert timers to use timer_setup()

In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new timer_setup() and from_timer()
to pass the timer pointer explicitly. Also consolidates the timer setup
functions arguments, which are all identical, and corrects on-stack timer
usage.

Cc: Kashyap Desai <kashyap.desai@broadcom.com>
Cc: Sumit Saxena <sumit.saxena@broadcom.com>
Cc: Shivasharan S <shivasharan.srikanteshwara@broadcom.com>
Cc: "James E.J. Bottomley" <jejb@linux.vnet.ibm.com>
Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
Cc: megaraidlinux.pdl@broadcom.com
Cc: linux-scsi@vger.kernel.org
Signed-off-by: NKees Cook <keescook@chromium.org>
Reviewed-by: NMartin K. Petersen <martin.petersen@oracle.com>
上级 f22eb4d3
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/semaphore.h> #include <linux/semaphore.h>
#include <linux/timer.h>
#include "mbox_defs.h" #include "mbox_defs.h"
...@@ -153,6 +154,11 @@ typedef struct uioc { ...@@ -153,6 +154,11 @@ typedef struct uioc {
} __attribute__ ((aligned(1024),packed)) uioc_t; } __attribute__ ((aligned(1024),packed)) uioc_t;
/* For on-stack uioc timers. */
struct uioc_timeout {
struct timer_list timer;
uioc_t *uioc;
};
/** /**
* struct mraid_hba_info - information about the controller * struct mraid_hba_info - information about the controller
......
...@@ -3904,19 +3904,19 @@ megaraid_sysfs_get_ldmap_done(uioc_t *uioc) ...@@ -3904,19 +3904,19 @@ megaraid_sysfs_get_ldmap_done(uioc_t *uioc)
wake_up(&raid_dev->sysfs_wait_q); wake_up(&raid_dev->sysfs_wait_q);
} }
/** /**
* megaraid_sysfs_get_ldmap_timeout - timeout handling for get ldmap * megaraid_sysfs_get_ldmap_timeout - timeout handling for get ldmap
* @data : timed out packet * @t : timed out timer
* *
* Timeout routine to recover and return to application, in case the adapter * Timeout routine to recover and return to application, in case the adapter
* has stopped responding. A timeout of 60 seconds for this command seems like * has stopped responding. A timeout of 60 seconds for this command seems like
* a good value. * a good value.
*/ */
static void static void
megaraid_sysfs_get_ldmap_timeout(unsigned long data) megaraid_sysfs_get_ldmap_timeout(struct timer_list *t)
{ {
uioc_t *uioc = (uioc_t *)data; struct uioc_timeout *timeout = from_timer(timeout, t, timer);
uioc_t *uioc = timeout->uioc;
adapter_t *adapter = (adapter_t *)uioc->buf_vaddr; adapter_t *adapter = (adapter_t *)uioc->buf_vaddr;
mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter); mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter);
...@@ -3951,8 +3951,7 @@ megaraid_sysfs_get_ldmap(adapter_t *adapter) ...@@ -3951,8 +3951,7 @@ megaraid_sysfs_get_ldmap(adapter_t *adapter)
mbox64_t *mbox64; mbox64_t *mbox64;
mbox_t *mbox; mbox_t *mbox;
char *raw_mbox; char *raw_mbox;
struct timer_list sysfs_timer; struct uioc_timeout timeout;
struct timer_list *timerp;
caddr_t ldmap; caddr_t ldmap;
int rval = 0; int rval = 0;
...@@ -3988,14 +3987,12 @@ megaraid_sysfs_get_ldmap(adapter_t *adapter) ...@@ -3988,14 +3987,12 @@ megaraid_sysfs_get_ldmap(adapter_t *adapter)
/* /*
* Setup a timer to recover from a non-responding controller * Setup a timer to recover from a non-responding controller
*/ */
timerp = &sysfs_timer; timeout.uioc = uioc;
init_timer(timerp); timer_setup_on_stack(&timeout.timer,
megaraid_sysfs_get_ldmap_timeout, 0);
timerp->function = megaraid_sysfs_get_ldmap_timeout;
timerp->data = (unsigned long)uioc;
timerp->expires = jiffies + 60 * HZ;
add_timer(timerp); timeout.timer.expires = jiffies + 60 * HZ;
add_timer(&timeout.timer);
/* /*
* Send the command to the firmware * Send the command to the firmware
...@@ -4033,7 +4030,8 @@ megaraid_sysfs_get_ldmap(adapter_t *adapter) ...@@ -4033,7 +4030,8 @@ megaraid_sysfs_get_ldmap(adapter_t *adapter)
} }
del_timer_sync(timerp); del_timer_sync(&timeout.timer);
destroy_timer_on_stack(&timeout.timer);
mutex_unlock(&raid_dev->sysfs_mtx); mutex_unlock(&raid_dev->sysfs_mtx);
......
...@@ -35,7 +35,7 @@ static int kioc_to_mimd(uioc_t *, mimd_t __user *); ...@@ -35,7 +35,7 @@ static int kioc_to_mimd(uioc_t *, mimd_t __user *);
static int handle_drvrcmd(void __user *, uint8_t, int *); static int handle_drvrcmd(void __user *, uint8_t, int *);
static int lld_ioctl(mraid_mmadp_t *, uioc_t *); static int lld_ioctl(mraid_mmadp_t *, uioc_t *);
static void ioctl_done(uioc_t *); static void ioctl_done(uioc_t *);
static void lld_timedout(unsigned long); static void lld_timedout(struct timer_list *);
static void hinfo_to_cinfo(mraid_hba_info_t *, mcontroller_t *); static void hinfo_to_cinfo(mraid_hba_info_t *, mcontroller_t *);
static mraid_mmadp_t *mraid_mm_get_adapter(mimd_t __user *, int *); static mraid_mmadp_t *mraid_mm_get_adapter(mimd_t __user *, int *);
static uioc_t *mraid_mm_alloc_kioc(mraid_mmadp_t *); static uioc_t *mraid_mm_alloc_kioc(mraid_mmadp_t *);
...@@ -686,8 +686,7 @@ static int ...@@ -686,8 +686,7 @@ static int
lld_ioctl(mraid_mmadp_t *adp, uioc_t *kioc) lld_ioctl(mraid_mmadp_t *adp, uioc_t *kioc)
{ {
int rval; int rval;
struct timer_list timer; struct uioc_timeout timeout = { };
struct timer_list *tp = NULL;
kioc->status = -ENODATA; kioc->status = -ENODATA;
rval = adp->issue_uioc(adp->drvr_data, kioc, IOCTL_ISSUE); rval = adp->issue_uioc(adp->drvr_data, kioc, IOCTL_ISSUE);
...@@ -698,14 +697,12 @@ lld_ioctl(mraid_mmadp_t *adp, uioc_t *kioc) ...@@ -698,14 +697,12 @@ lld_ioctl(mraid_mmadp_t *adp, uioc_t *kioc)
* Start the timer * Start the timer
*/ */
if (adp->timeout > 0) { if (adp->timeout > 0) {
tp = &timer; timeout.uioc = kioc;
init_timer(tp); timer_setup_on_stack(&timeout.timer, lld_timedout, 0);
tp->function = lld_timedout; timeout.timer.expires = jiffies + adp->timeout * HZ;
tp->data = (unsigned long)kioc;
tp->expires = jiffies + adp->timeout * HZ;
add_timer(tp); add_timer(&timeout.timer);
} }
/* /*
...@@ -713,8 +710,9 @@ lld_ioctl(mraid_mmadp_t *adp, uioc_t *kioc) ...@@ -713,8 +710,9 @@ lld_ioctl(mraid_mmadp_t *adp, uioc_t *kioc)
* call, the ioctl either completed successfully or timedout. * call, the ioctl either completed successfully or timedout.
*/ */
wait_event(wait_q, (kioc->status != -ENODATA)); wait_event(wait_q, (kioc->status != -ENODATA));
if (tp) { if (timeout.timer.function) {
del_timer_sync(tp); del_timer_sync(&timeout.timer);
destroy_timer_on_stack(&timeout.timer);
} }
/* /*
...@@ -783,12 +781,13 @@ ioctl_done(uioc_t *kioc) ...@@ -783,12 +781,13 @@ ioctl_done(uioc_t *kioc)
/** /**
* lld_timedout - callback from the expired timer * lld_timedout - callback from the expired timer
* @ptr : ioctl packet that timed out * @t : timer that timed out
*/ */
static void static void
lld_timedout(unsigned long ptr) lld_timedout(struct timer_list *t)
{ {
uioc_t *kioc = (uioc_t *)ptr; struct uioc_timeout *timeout = from_timer(timeout, t, timer);
uioc_t *kioc = timeout->uioc;
kioc->status = -ETIME; kioc->status = -ETIME;
kioc->timedout = 1; kioc->timedout = 1;
......
...@@ -2114,22 +2114,19 @@ static void megasas_complete_cmd_dpc(unsigned long instance_addr) ...@@ -2114,22 +2114,19 @@ static void megasas_complete_cmd_dpc(unsigned long instance_addr)
megasas_check_and_restore_queue_depth(instance); megasas_check_and_restore_queue_depth(instance);
} }
static void megasas_sriov_heartbeat_handler(struct timer_list *t);
/** /**
* megasas_start_timer - Initializes a timer object * megasas_start_timer - Initializes sriov heartbeat timer object
* @instance: Adapter soft state * @instance: Adapter soft state
* @timer: timer object to be initialized
* @fn: timer function
* @interval: time interval between timer function call
* *
*/ */
void megasas_start_timer(struct megasas_instance *instance, void megasas_start_timer(struct megasas_instance *instance)
struct timer_list *timer, {
void *fn, unsigned long interval) struct timer_list *timer = &instance->sriov_heartbeat_timer;
{
init_timer(timer); timer_setup(timer, megasas_sriov_heartbeat_handler, 0);
timer->expires = jiffies + interval; timer->expires = jiffies + MEGASAS_SRIOV_HEARTBEAT_INTERVAL_VF;
timer->data = (unsigned long)instance;
timer->function = fn;
add_timer(timer); add_timer(timer);
} }
...@@ -2515,10 +2512,10 @@ int megasas_sriov_start_heartbeat(struct megasas_instance *instance, ...@@ -2515,10 +2512,10 @@ int megasas_sriov_start_heartbeat(struct megasas_instance *instance,
} }
/* Handler for SR-IOV heartbeat */ /* Handler for SR-IOV heartbeat */
void megasas_sriov_heartbeat_handler(unsigned long instance_addr) static void megasas_sriov_heartbeat_handler(struct timer_list *t)
{ {
struct megasas_instance *instance = struct megasas_instance *instance =
(struct megasas_instance *)instance_addr; from_timer(instance, t, sriov_heartbeat_timer);
if (instance->hb_host_mem->HB.fwCounter != if (instance->hb_host_mem->HB.fwCounter !=
instance->hb_host_mem->HB.driverCounter) { instance->hb_host_mem->HB.driverCounter) {
...@@ -5493,10 +5490,7 @@ static int megasas_init_fw(struct megasas_instance *instance) ...@@ -5493,10 +5490,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
/* Launch SR-IOV heartbeat timer */ /* Launch SR-IOV heartbeat timer */
if (instance->requestorId) { if (instance->requestorId) {
if (!megasas_sriov_start_heartbeat(instance, 1)) if (!megasas_sriov_start_heartbeat(instance, 1))
megasas_start_timer(instance, megasas_start_timer(instance);
&instance->sriov_heartbeat_timer,
megasas_sriov_heartbeat_handler,
MEGASAS_SRIOV_HEARTBEAT_INTERVAL_VF);
else else
instance->skip_heartbeat_timer_del = 1; instance->skip_heartbeat_timer_del = 1;
} }
...@@ -6507,10 +6501,7 @@ megasas_resume(struct pci_dev *pdev) ...@@ -6507,10 +6501,7 @@ megasas_resume(struct pci_dev *pdev)
/* Re-launch SR-IOV heartbeat timer */ /* Re-launch SR-IOV heartbeat timer */
if (instance->requestorId) { if (instance->requestorId) {
if (!megasas_sriov_start_heartbeat(instance, 0)) if (!megasas_sriov_start_heartbeat(instance, 0))
megasas_start_timer(instance, megasas_start_timer(instance);
&instance->sriov_heartbeat_timer,
megasas_sriov_heartbeat_handler,
MEGASAS_SRIOV_HEARTBEAT_INTERVAL_VF);
else { else {
instance->skip_heartbeat_timer_del = 1; instance->skip_heartbeat_timer_del = 1;
goto fail_init_mfi; goto fail_init_mfi;
......
...@@ -85,12 +85,9 @@ int megasas_transition_to_ready(struct megasas_instance *instance, int ocr); ...@@ -85,12 +85,9 @@ int megasas_transition_to_ready(struct megasas_instance *instance, int ocr);
void megaraid_sas_kill_hba(struct megasas_instance *instance); void megaraid_sas_kill_hba(struct megasas_instance *instance);
extern u32 megasas_dbg_lvl; extern u32 megasas_dbg_lvl;
void megasas_sriov_heartbeat_handler(unsigned long instance_addr);
int megasas_sriov_start_heartbeat(struct megasas_instance *instance, int megasas_sriov_start_heartbeat(struct megasas_instance *instance,
int initial); int initial);
void megasas_start_timer(struct megasas_instance *instance, void megasas_start_timer(struct megasas_instance *instance);
struct timer_list *timer,
void *fn, unsigned long interval);
extern struct megasas_mgmt_info megasas_mgmt_info; extern struct megasas_mgmt_info megasas_mgmt_info;
extern unsigned int resetwaittime; extern unsigned int resetwaittime;
extern unsigned int dual_qdepth_disable; extern unsigned int dual_qdepth_disable;
...@@ -4369,10 +4366,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason) ...@@ -4369,10 +4366,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason)
/* Restart SR-IOV heartbeat */ /* Restart SR-IOV heartbeat */
if (instance->requestorId) { if (instance->requestorId) {
if (!megasas_sriov_start_heartbeat(instance, 0)) if (!megasas_sriov_start_heartbeat(instance, 0))
megasas_start_timer(instance, megasas_start_timer(instance);
&instance->sriov_heartbeat_timer,
megasas_sriov_heartbeat_handler,
MEGASAS_SRIOV_HEARTBEAT_INTERVAL_VF);
else else
instance->skip_heartbeat_timer_del = 1; instance->skip_heartbeat_timer_del = 1;
} }
...@@ -4404,10 +4398,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason) ...@@ -4404,10 +4398,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason)
} else { } else {
/* For VF: Restart HB timer if we didn't OCR */ /* For VF: Restart HB timer if we didn't OCR */
if (instance->requestorId) { if (instance->requestorId) {
megasas_start_timer(instance, megasas_start_timer(instance);
&instance->sriov_heartbeat_timer,
megasas_sriov_heartbeat_handler,
MEGASAS_SRIOV_HEARTBEAT_INTERVAL_VF);
} }
clear_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags); clear_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);
instance->instancet->enable_intr(instance); instance->instancet->enable_intr(instance);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册