Skip to content

Commit

Permalink
isci: rework timer api
Browse files Browse the repository at this point in the history
Prepare the timer api for the arrival of dynamic creation and
destruction events from the core.  It pretended to do this previously
but the core to date only used it in a static init-time only fashion.
This is an interim fix until a cleaner event queue can be developed.

1/ make all locking external to the api (add WARN_ONCE to verify)
2/ add a timer_destroy interface (to be used by the core)
3/ use del_timer_sync() prior to deallocating timer data
4/ delete the "timer_list" indirection, we only have timers allocated
   for the isci_host
5/ fix detection of timer list allocation errors

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
  • Loading branch information
Dan Williams committed Jul 3, 2011
1 parent 150fc6f commit 7c40a80
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 232 deletions.
49 changes: 21 additions & 28 deletions drivers/scsi/isci/events.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,35 +75,23 @@
* whenever the timer expires.
* @controller: This parameter specifies the controller with which this timer
* is to be associated.
* @cookie: This parameter specifies a piece of information that the user must
* retain. This cookie is to be supplied by the user anytime a timeout
* occurs for the created timer.
* @cb_param: opaque callback parameter
*
* This method returns a handle to a timer object created by the user. The
* handle will be utilized for all further interactions relating to this timer.
*/
void *isci_event_timer_create(
struct scic_sds_controller *controller,
void (*timer_callback)(void *),
void *cookie)
void *isci_event_timer_create(struct scic_sds_controller *scic,
void (*timer_callback)(void *),
void *cb_param)
{
struct isci_host *isci_host;
struct isci_timer *timer = NULL;

isci_host = (struct isci_host *)sci_object_get_association(controller);
struct isci_host *ihost = sci_object_get_association(scic);
struct isci_timer *itimer;

dev_dbg(&isci_host->pdev->dev,
"%s: isci_host = %p",
__func__, isci_host);

timer = isci_timer_create(&isci_host->timer_list_struct,
isci_host,
cookie,
timer_callback);
itimer = isci_timer_create(ihost, cb_param, timer_callback);

dev_dbg(&isci_host->pdev->dev, "%s: timer = %p\n", __func__, timer);
dev_dbg(&ihost->pdev->dev, "%s: timer = %p\n", __func__, itimer);

return (void *)timer;
return itimer;
}


Expand Down Expand Up @@ -146,14 +134,9 @@ void isci_event_timer_start(
* @timer: This parameter specifies the timer to be stopped.
*
*/
void isci_event_timer_stop(
struct scic_sds_controller *controller,
void *timer)
void isci_event_timer_stop(struct scic_sds_controller *controller, void *timer)
{
struct isci_host *isci_host;

isci_host =
(struct isci_host *)sci_object_get_association(controller);
struct isci_host *isci_host = sci_object_get_association(controller);

dev_dbg(&isci_host->pdev->dev,
"%s: isci_host = %p, timer = %p\n",
Expand All @@ -162,6 +145,16 @@ void isci_event_timer_stop(
isci_timer_stop((struct isci_timer *)timer);
}

void isci_event_timer_destroy(struct scic_sds_controller *scic, void *timer)
{
struct isci_host *ihost = sci_object_get_association(scic);

dev_dbg(&ihost->pdev->dev, "%s: ihost = %p, timer = %p\n",
__func__, ihost, timer);

isci_del_timer(ihost, timer);
}

/**
* isci_event_controller_start_complete() - This user callback will inform the
* user that the controller has finished the start process. The associated
Expand Down
3 changes: 3 additions & 0 deletions drivers/scsi/isci/events.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ void isci_event_timer_stop(
struct scic_sds_controller *controller,
void *timer);


void isci_event_timer_destroy(struct scic_sds_controller *scic, void *timer);

/**
* isci_event_controller_start_complete() - This user callback will inform the
* user that the controller has finished the start process.
Expand Down
32 changes: 16 additions & 16 deletions drivers/scsi/isci/host.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,9 +349,14 @@ void isci_host_deinit(struct isci_host *ihost)
}

set_bit(IHOST_STOP_PENDING, &ihost->flags);

spin_lock_irq(&ihost->scic_lock);
scic_controller_stop(scic, SCIC_CONTROLLER_STOP_TIMEOUT);
spin_unlock_irq(&ihost->scic_lock);

wait_for_stop(ihost);
scic_controller_reset(scic);
isci_timer_list_destroy(ihost);
}

static void __iomem *scu_base(struct isci_host *isci_host)
Expand All @@ -370,8 +375,6 @@ static void __iomem *smu_base(struct isci_host *isci_host)
return pcim_iomap_table(pdev)[SCI_SMU_BAR * 2] + SCI_SMU_BAR_SIZE * id;
}

#define SCI_MAX_TIMER_COUNT 25

int isci_host_init(struct isci_host *isci_host)
{
int err = 0;
Expand All @@ -382,11 +385,7 @@ int isci_host_init(struct isci_host *isci_host)
union scic_oem_parameters scic_oem_params;
union scic_user_parameters scic_user_params;

INIT_LIST_HEAD(&isci_host->timer_list_struct.timers);
isci_timer_list_construct(
&isci_host->timer_list_struct,
SCI_MAX_TIMER_COUNT
);
isci_timer_list_construct(isci_host);

controller = scic_controller_alloc(&isci_host->pdev->dev);

Expand Down Expand Up @@ -473,7 +472,17 @@ int isci_host_init(struct isci_host *isci_host)
}
}

tasklet_init(&isci_host->completion_tasklet,
isci_host_completion_routine, (unsigned long)isci_host);

INIT_LIST_HEAD(&(isci_host->mdl_struct_list));

INIT_LIST_HEAD(&isci_host->requests_to_complete);
INIT_LIST_HEAD(&isci_host->requests_to_abort);

spin_lock_irq(&isci_host->scic_lock);
status = scic_controller_initialize(isci_host->core_controller);
spin_unlock_irq(&isci_host->scic_lock);
if (status != SCI_SUCCESS) {
dev_warn(&isci_host->pdev->dev,
"%s: scic_controller_initialize failed -"
Expand All @@ -482,17 +491,8 @@ int isci_host_init(struct isci_host *isci_host)
return -ENODEV;
}

tasklet_init(&isci_host->completion_tasklet,
isci_host_completion_routine, (unsigned long)isci_host);

INIT_LIST_HEAD(&(isci_host->mdl_struct_list));

INIT_LIST_HEAD(&isci_host->requests_to_complete);
INIT_LIST_HEAD(&isci_host->requests_to_abort);

/* populate mdl with dma memory. scu_mdl_allocate_coherent() */
err = isci_host_mdl_allocate_coherent(isci_host);

if (err)
return err;

Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/isci/host.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ struct isci_host {
union scic_oem_parameters oem_parameters;

int id; /* unique within a given pci device */
struct isci_timer_list timer_list_struct;
struct list_head timers;
void *core_ctrl_memory;
struct dma_pool *dma_pool;
unsigned int dma_pool_alloc_size;
Expand Down
17 changes: 3 additions & 14 deletions drivers/scsi/isci/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -475,14 +475,8 @@ int isci_task_execute_tmf(
}

/* Allocate the TMF timeout timer. */
tmf->timeout_timer = isci_timer_create(
&isci_host->timer_list_struct,
isci_host,
request,
isci_tmf_timeout_cb
);

spin_lock_irqsave(&isci_host->scic_lock, flags);
tmf->timeout_timer = isci_timer_create(isci_host, request, isci_tmf_timeout_cb);

/* Start the timer. */
if (tmf->timeout_timer)
Expand Down Expand Up @@ -557,9 +551,7 @@ int isci_task_execute_tmf(

/* Clean up the timer if needed. */
if (tmf->timeout_timer) {
isci_timer_stop(tmf->timeout_timer);
isci_timer_free(&isci_host->timer_list_struct,
tmf->timeout_timer);
isci_del_timer(isci_host, tmf->timeout_timer);
tmf->timeout_timer = NULL;
}

Expand Down Expand Up @@ -1468,10 +1460,7 @@ void isci_task_request_complete(

/* Manage the timer if it is still running. */
if (tmf->timeout_timer) {

isci_timer_stop(tmf->timeout_timer);
isci_timer_free(&isci_host->timer_list_struct,
tmf->timeout_timer);
isci_del_timer(isci_host, tmf->timeout_timer);
tmf->timeout_timer = NULL;
}

Expand Down
Loading

0 comments on commit 7c40a80

Please sign in to comment.