diff options
author | Edmund Nadolski <edmund.nadolski@intel.com> | 2011-05-19 07:59:10 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 07:04:49 -0400 |
commit | 5553ba2be0f3e3741e1a885a33d2b89921f9fd48 (patch) | |
tree | ba29bd7a120cc170b4b6e9f09ee8a4751a3773be /drivers/scsi/isci/isci.h | |
parent | 9269e0e898594c65dee6b20d4ed48e33dbbd4eeb (diff) |
isci: replace isci_timer list with proper embedded timers
Rather than preallocating a list of timers and doling them out at runtime,
embed a struct timerlist in each object that needs one. A struct sci_timer
interface is introduced to manage the timer cancellation semantics which
currently need to guarantee the timer is cancelled while holding
spin_lock(ihost->scic_lock). Since the timeout functions also need to acquire
the lock it currently prevents the driver from using del_timer_sync() for
runtime cancellations.
del_timer_sync() is used however before the objects go out of scope.
Signed-off-by: Edmund Nadolski <edmund.nadolski@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/scsi/isci/isci.h')
-rw-r--r-- | drivers/scsi/isci/isci.h | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/scsi/isci/isci.h b/drivers/scsi/isci/isci.h index 69826eac97b5..2fe5557d8590 100644 --- a/drivers/scsi/isci/isci.h +++ b/drivers/scsi/isci/isci.h | |||
@@ -551,4 +551,37 @@ extern unsigned char max_concurr_spinup; | |||
551 | irqreturn_t isci_msix_isr(int vec, void *data); | 551 | irqreturn_t isci_msix_isr(int vec, void *data); |
552 | irqreturn_t isci_intx_isr(int vec, void *data); | 552 | irqreturn_t isci_intx_isr(int vec, void *data); |
553 | irqreturn_t isci_error_isr(int vec, void *data); | 553 | irqreturn_t isci_error_isr(int vec, void *data); |
554 | |||
555 | /* | ||
556 | * Each timer is associated with a cancellation flag that is set when | ||
557 | * del_timer() is called and checked in the timer callback function. This | ||
558 | * is needed since del_timer_sync() cannot be called with scic_lock held. | ||
559 | * For deinit however, del_timer_sync() is used without holding the lock. | ||
560 | */ | ||
561 | struct sci_timer { | ||
562 | struct timer_list timer; | ||
563 | bool cancel; | ||
564 | }; | ||
565 | |||
566 | static inline | ||
567 | void sci_init_timer(struct sci_timer *tmr, void (*fn)(unsigned long)) | ||
568 | { | ||
569 | tmr->timer.function = fn; | ||
570 | tmr->timer.data = (unsigned long) tmr; | ||
571 | tmr->cancel = 0; | ||
572 | init_timer(&tmr->timer); | ||
573 | } | ||
574 | |||
575 | static inline void sci_mod_timer(struct sci_timer *tmr, unsigned long msec) | ||
576 | { | ||
577 | tmr->cancel = 0; | ||
578 | mod_timer(&tmr->timer, jiffies + msecs_to_jiffies(msec)); | ||
579 | } | ||
580 | |||
581 | static inline void sci_del_timer(struct sci_timer *tmr) | ||
582 | { | ||
583 | tmr->cancel = 1; | ||
584 | del_timer(&tmr->timer); | ||
585 | } | ||
586 | |||
554 | #endif /* __ISCI_H__ */ | 587 | #endif /* __ISCI_H__ */ |