diff options
Diffstat (limited to 'drivers/scsi/libsas/sas_scsi_host.c')
-rw-r--r-- | drivers/scsi/libsas/sas_scsi_host.c | 176 |
1 files changed, 1 insertions, 175 deletions
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index b492293..72918d2 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -112,7 +112,6 @@ static void sas_end_task(struct scsi_cmnd *sc, struct sas_task *task) sc->result = (hs << 16) | stat; ASSIGN_SAS_TASK(sc, NULL); - list_del_init(&task->list); sas_free_task(task); } @@ -138,7 +137,6 @@ static void sas_scsi_task_done(struct sas_task *task) if (unlikely(!sc)) { SAS_DPRINTK("task_done called with non existing SCSI cmnd!\n"); - list_del_init(&task->list); sas_free_task(task); return; } @@ -179,31 +177,10 @@ static struct sas_task *sas_create_task(struct scsi_cmnd *cmd, return task; } -int sas_queue_up(struct sas_task *task) -{ - struct sas_ha_struct *sas_ha = task->dev->port->ha; - struct scsi_core *core = &sas_ha->core; - unsigned long flags; - LIST_HEAD(list); - - spin_lock_irqsave(&core->task_queue_lock, flags); - if (sas_ha->lldd_queue_size < core->task_queue_size + 1) { - spin_unlock_irqrestore(&core->task_queue_lock, flags); - return -SAS_QUEUE_FULL; - } - list_add_tail(&task->list, &core->task_queue); - core->task_queue_size += 1; - spin_unlock_irqrestore(&core->task_queue_lock, flags); - wake_up_process(core->queue_thread); - - return 0; -} - int sas_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) { struct sas_internal *i = to_sas_internal(host->transportt); struct domain_device *dev = cmd_to_domain_dev(cmd); - struct sas_ha_struct *sas_ha = dev->port->ha; struct sas_task *task; int res = 0; @@ -224,12 +201,7 @@ int sas_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) if (!task) return SCSI_MLQUEUE_HOST_BUSY; - /* Queue up, Direct Mode or Task Collector Mode. */ - if (sas_ha->lldd_max_execute_num < 2) - res = i->dft->lldd_execute_task(task, 1, GFP_ATOMIC); - else - res = sas_queue_up(task); - + res = i->dft->lldd_execute_task(task, GFP_ATOMIC); if (res) goto out_free_task; return 0; @@ -323,37 +295,17 @@ enum task_disposition { TASK_IS_DONE, TASK_IS_ABORTED, TASK_IS_AT_LU, - TASK_IS_NOT_AT_HA, TASK_IS_NOT_AT_LU, TASK_ABORT_FAILED, }; static enum task_disposition sas_scsi_find_task(struct sas_task *task) { - struct sas_ha_struct *ha = task->dev->port->ha; unsigned long flags; int i, res; struct sas_internal *si = to_sas_internal(task->dev->port->ha->core.shost->transportt); - if (ha->lldd_max_execute_num > 1) { - struct scsi_core *core = &ha->core; - struct sas_task *t, *n; - - mutex_lock(&core->task_queue_flush); - spin_lock_irqsave(&core->task_queue_lock, flags); - list_for_each_entry_safe(t, n, &core->task_queue, list) - if (task == t) { - list_del_init(&t->list); - break; - } - spin_unlock_irqrestore(&core->task_queue_lock, flags); - mutex_unlock(&core->task_queue_flush); - - if (task == t) - return TASK_IS_NOT_AT_HA; - } - for (i = 0; i < 5; i++) { SAS_DPRINTK("%s: aborting task 0x%p\n", __func__, task); res = si->dft->lldd_abort_task(task); @@ -667,14 +619,6 @@ static void sas_eh_handle_sas_errors(struct Scsi_Host *shost, struct list_head * cmd->eh_eflags = 0; switch (res) { - case TASK_IS_NOT_AT_HA: - SAS_DPRINTK("%s: task 0x%p is not at ha: %s\n", - __func__, task, - cmd->retries ? "retry" : "aborted"); - if (cmd->retries) - cmd->retries--; - sas_eh_finish_cmd(cmd); - continue; case TASK_IS_DONE: SAS_DPRINTK("%s: task 0x%p is done\n", __func__, task); @@ -836,9 +780,6 @@ retry: scsi_eh_ready_devs(shost, &eh_work_q, &ha->eh_done_q); out: - if (ha->lldd_max_execute_num > 1) - wake_up_process(ha->core.queue_thread); - sas_eh_handle_resets(shost); /* now link into libata eh --- if we have any ata devices */ @@ -984,121 +925,6 @@ int sas_bios_param(struct scsi_device *scsi_dev, return 0; } -/* ---------- Task Collector Thread implementation ---------- */ - -static void sas_queue(struct sas_ha_struct *sas_ha) -{ - struct scsi_core *core = &sas_ha->core; - unsigned long flags; - LIST_HEAD(q); - int can_queue; - int res; - struct sas_internal *i = to_sas_internal(core->shost->transportt); - - mutex_lock(&core->task_queue_flush); - spin_lock_irqsave(&core->task_queue_lock, flags); - while (!kthread_should_stop() && - !list_empty(&core->task_queue) && - !test_bit(SAS_HA_FROZEN, &sas_ha->state)) { - - can_queue = sas_ha->lldd_queue_size - core->task_queue_size; - if (can_queue >= 0) { - can_queue = core->task_queue_size; - list_splice_init(&core->task_queue, &q); - } else { - struct list_head *a, *n; - - can_queue = sas_ha->lldd_queue_size; - list_for_each_safe(a, n, &core->task_queue) { - list_move_tail(a, &q); - if (--can_queue == 0) - break; - } - can_queue = sas_ha->lldd_queue_size; - } - core->task_queue_size -= can_queue; - spin_unlock_irqrestore(&core->task_queue_lock, flags); - { - struct sas_task *task = list_entry(q.next, - struct sas_task, - list); - list_del_init(&q); - res = i->dft->lldd_execute_task(task, can_queue, - GFP_KERNEL); - if (unlikely(res)) - __list_add(&q, task->list.prev, &task->list); - } - spin_lock_irqsave(&core->task_queue_lock, flags); - if (res) { - list_splice_init(&q, &core->task_queue); /*at head*/ - core->task_queue_size += can_queue; - } - } - spin_unlock_irqrestore(&core->task_queue_lock, flags); - mutex_unlock(&core->task_queue_flush); -} - -/** - * sas_queue_thread -- The Task Collector thread - * @_sas_ha: pointer to struct sas_ha - */ -static int sas_queue_thread(void *_sas_ha) -{ - struct sas_ha_struct *sas_ha = _sas_ha; - - while (1) { - set_current_state(TASK_INTERRUPTIBLE); - schedule(); - sas_queue(sas_ha); - if (kthread_should_stop()) - break; - } - - return 0; -} - -int sas_init_queue(struct sas_ha_struct *sas_ha) -{ - struct scsi_core *core = &sas_ha->core; - - spin_lock_init(&core->task_queue_lock); - mutex_init(&core->task_queue_flush); - core->task_queue_size = 0; - INIT_LIST_HEAD(&core->task_queue); - - core->queue_thread = kthread_run(sas_queue_thread, sas_ha, - "sas_queue_%d", core->shost->host_no); - if (IS_ERR(core->queue_thread)) - return PTR_ERR(core->queue_thread); - return 0; -} - -void sas_shutdown_queue(struct sas_ha_struct *sas_ha) -{ - unsigned long flags; - struct scsi_core *core = &sas_ha->core; - struct sas_task *task, *n; - - kthread_stop(core->queue_thread); - - if (!list_empty(&core->task_queue)) - SAS_DPRINTK("HA: %llx: scsi core task queue is NOT empty!?\n", - SAS_ADDR(sas_ha->sas_addr)); - - spin_lock_irqsave(&core->task_queue_lock, flags); - list_for_each_entry_safe(task, n, &core->task_queue, list) { - struct scsi_cmnd *cmd = task->uldd_task; - - list_del_init(&task->list); - - ASSIGN_SAS_TASK(cmd, NULL); - sas_free_task(task); - cmd->result = DID_ABORT << 16; - cmd->scsi_done(cmd); - } - spin_unlock_irqrestore(&core->task_queue_lock, flags); -} - /* * Tell an upper layer that it needs to initiate an abort for a given task. * This should only ever be called by an LLDD. |