sas_scsi_host.c revision 3cc27547d6ee2d50ecdd11e9127bc3cd1947e8dd
1/*
2 * Serial Attached SCSI (SAS) class SCSI Host glue.
3 *
4 * Copyright (C) 2005 Adaptec, Inc.  All rights reserved.
5 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com>
6 *
7 * This file is licensed under GPLv2.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 * USA
23 *
24 */
25
26#include "sas_internal.h"
27
28#include <scsi/scsi_host.h>
29#include <scsi/scsi_device.h>
30#include <scsi/scsi_tcq.h>
31#include <scsi/scsi.h>
32#include <scsi/scsi_transport.h>
33#include <scsi/scsi_transport_sas.h>
34#include "../scsi_sas_internal.h"
35
36#include <linux/err.h>
37#include <linux/blkdev.h>
38#include <linux/scatterlist.h>
39
40/* ---------- SCSI Host glue ---------- */
41
42#define TO_SAS_TASK(_scsi_cmd)  ((void *)(_scsi_cmd)->host_scribble)
43#define ASSIGN_SAS_TASK(_sc, _t) do { (_sc)->host_scribble = (void *) _t; } while (0)
44
45static void sas_scsi_task_done(struct sas_task *task)
46{
47	struct task_status_struct *ts = &task->task_status;
48	struct scsi_cmnd *sc = task->uldd_task;
49	unsigned ts_flags = task->task_state_flags;
50	int hs = 0, stat = 0;
51
52	if (unlikely(!sc)) {
53		SAS_DPRINTK("task_done called with non existing SCSI cmnd!\n");
54		list_del_init(&task->list);
55		sas_free_task(task);
56		return;
57	}
58
59	if (ts->resp == SAS_TASK_UNDELIVERED) {
60		/* transport error */
61		hs = DID_NO_CONNECT;
62	} else { /* ts->resp == SAS_TASK_COMPLETE */
63		/* task delivered, what happened afterwards? */
64		switch (ts->stat) {
65		case SAS_DEV_NO_RESPONSE:
66		case SAS_INTERRUPTED:
67		case SAS_PHY_DOWN:
68		case SAS_NAK_R_ERR:
69		case SAS_OPEN_TO:
70			hs = DID_NO_CONNECT;
71			break;
72		case SAS_DATA_UNDERRUN:
73			sc->resid = ts->residual;
74			if (sc->request_bufflen - sc->resid < sc->underflow)
75				hs = DID_ERROR;
76			break;
77		case SAS_DATA_OVERRUN:
78			hs = DID_ERROR;
79			break;
80		case SAS_QUEUE_FULL:
81			hs = DID_SOFT_ERROR; /* retry */
82			break;
83		case SAS_DEVICE_UNKNOWN:
84			hs = DID_BAD_TARGET;
85			break;
86		case SAS_SG_ERR:
87			hs = DID_PARITY;
88			break;
89		case SAS_OPEN_REJECT:
90			if (ts->open_rej_reason == SAS_OREJ_RSVD_RETRY)
91				hs = DID_SOFT_ERROR; /* retry */
92			else
93				hs = DID_ERROR;
94			break;
95		case SAS_PROTO_RESPONSE:
96			SAS_DPRINTK("LLDD:%s sent SAS_PROTO_RESP for an SSP "
97				    "task; please report this\n",
98				    task->dev->port->ha->sas_ha_name);
99			break;
100		case SAS_ABORTED_TASK:
101			hs = DID_ABORT;
102			break;
103		case SAM_CHECK_COND:
104			memcpy(sc->sense_buffer, ts->buf,
105			       max(SCSI_SENSE_BUFFERSIZE, ts->buf_valid_size));
106			stat = SAM_CHECK_COND;
107			break;
108		default:
109			stat = ts->stat;
110			break;
111		}
112	}
113	ASSIGN_SAS_TASK(sc, NULL);
114	sc->result = (hs << 16) | stat;
115	list_del_init(&task->list);
116	sas_free_task(task);
117	/* This is very ugly but this is how SCSI Core works. */
118	if (ts_flags & SAS_TASK_STATE_ABORTED)
119		scsi_finish_command(sc);
120	else
121		sc->scsi_done(sc);
122}
123
124static enum task_attribute sas_scsi_get_task_attr(struct scsi_cmnd *cmd)
125{
126	enum task_attribute ta = TASK_ATTR_SIMPLE;
127	if (cmd->request && blk_rq_tagged(cmd->request)) {
128		if (cmd->device->ordered_tags &&
129		    (cmd->request->flags & REQ_HARDBARRIER))
130			ta = TASK_ATTR_HOQ;
131	}
132	return ta;
133}
134
135static struct sas_task *sas_create_task(struct scsi_cmnd *cmd,
136					       struct domain_device *dev,
137					       gfp_t gfp_flags)
138{
139	struct sas_task *task = sas_alloc_task(gfp_flags);
140	struct scsi_lun lun;
141
142	if (!task)
143		return NULL;
144
145	*(u32 *)cmd->sense_buffer = 0;
146	task->uldd_task = cmd;
147	ASSIGN_SAS_TASK(cmd, task);
148
149	task->dev = dev;
150	task->task_proto = task->dev->tproto; /* BUG_ON(!SSP) */
151
152	task->ssp_task.retry_count = 1;
153	int_to_scsilun(cmd->device->lun, &lun);
154	memcpy(task->ssp_task.LUN, &lun.scsi_lun, 8);
155	task->ssp_task.task_attr = sas_scsi_get_task_attr(cmd);
156	memcpy(task->ssp_task.cdb, cmd->cmnd, 16);
157
158	task->scatter = cmd->request_buffer;
159	task->num_scatter = cmd->use_sg;
160	task->total_xfer_len = cmd->request_bufflen;
161	task->data_dir = cmd->sc_data_direction;
162
163	task->task_done = sas_scsi_task_done;
164
165	return task;
166}
167
168static int sas_queue_up(struct sas_task *task)
169{
170	struct sas_ha_struct *sas_ha = task->dev->port->ha;
171	struct scsi_core *core = &sas_ha->core;
172	unsigned long flags;
173	LIST_HEAD(list);
174
175	spin_lock_irqsave(&core->task_queue_lock, flags);
176	if (sas_ha->lldd_queue_size < core->task_queue_size + 1) {
177		spin_unlock_irqrestore(&core->task_queue_lock, flags);
178		return -SAS_QUEUE_FULL;
179	}
180	list_add_tail(&task->list, &core->task_queue);
181	core->task_queue_size += 1;
182	spin_unlock_irqrestore(&core->task_queue_lock, flags);
183	up(&core->queue_thread_sema);
184
185	return 0;
186}
187
188/**
189 * sas_queuecommand -- Enqueue a command for processing
190 * @parameters: See SCSI Core documentation
191 *
192 * Note: XXX: Remove the host unlock/lock pair when SCSI Core can
193 * call us without holding an IRQ spinlock...
194 */
195int sas_queuecommand(struct scsi_cmnd *cmd,
196		     void (*scsi_done)(struct scsi_cmnd *))
197{
198	int res = 0;
199	struct domain_device *dev = cmd_to_domain_dev(cmd);
200	struct Scsi_Host *host = cmd->device->host;
201	struct sas_internal *i = to_sas_internal(host->transportt);
202
203	spin_unlock_irq(host->host_lock);
204
205	{
206		struct sas_ha_struct *sas_ha = dev->port->ha;
207		struct sas_task *task;
208
209		res = -ENOMEM;
210		task = sas_create_task(cmd, dev, GFP_ATOMIC);
211		if (!task)
212			goto out;
213
214		cmd->scsi_done = scsi_done;
215		/* Queue up, Direct Mode or Task Collector Mode. */
216		if (sas_ha->lldd_max_execute_num < 2)
217			res = i->dft->lldd_execute_task(task, 1, GFP_ATOMIC);
218		else
219			res = sas_queue_up(task);
220
221		/* Examine */
222		if (res) {
223			SAS_DPRINTK("lldd_execute_task returned: %d\n", res);
224			ASSIGN_SAS_TASK(cmd, NULL);
225			sas_free_task(task);
226			if (res == -SAS_QUEUE_FULL) {
227				cmd->result = DID_SOFT_ERROR << 16; /* retry */
228				res = 0;
229				scsi_done(cmd);
230			}
231			goto out;
232		}
233	}
234out:
235	spin_lock_irq(host->host_lock);
236	return res;
237}
238
239static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd *my_cmd)
240{
241	struct scsi_cmnd *cmd, *n;
242
243	list_for_each_entry_safe(cmd, n, error_q, eh_entry) {
244		if (cmd == my_cmd)
245			list_del_init(&cmd->eh_entry);
246	}
247}
248
249static void sas_scsi_clear_queue_I_T(struct list_head *error_q,
250				     struct domain_device *dev)
251{
252	struct scsi_cmnd *cmd, *n;
253
254	list_for_each_entry_safe(cmd, n, error_q, eh_entry) {
255		struct domain_device *x = cmd_to_domain_dev(cmd);
256
257		if (x == dev)
258			list_del_init(&cmd->eh_entry);
259	}
260}
261
262static void sas_scsi_clear_queue_port(struct list_head *error_q,
263				      struct asd_sas_port *port)
264{
265	struct scsi_cmnd *cmd, *n;
266
267	list_for_each_entry_safe(cmd, n, error_q, eh_entry) {
268		struct domain_device *dev = cmd_to_domain_dev(cmd);
269		struct asd_sas_port *x = dev->port;
270
271		if (x == port)
272			list_del_init(&cmd->eh_entry);
273	}
274}
275
276enum task_disposition {
277	TASK_IS_DONE,
278	TASK_IS_ABORTED,
279	TASK_IS_AT_LU,
280	TASK_IS_NOT_AT_LU,
281};
282
283static enum task_disposition sas_scsi_find_task(struct sas_task *task)
284{
285	struct sas_ha_struct *ha = task->dev->port->ha;
286	unsigned long flags;
287	int i, res;
288	struct sas_internal *si =
289		to_sas_internal(task->dev->port->ha->core.shost->transportt);
290
291	if (ha->lldd_max_execute_num > 1) {
292		struct scsi_core *core = &ha->core;
293		struct sas_task *t, *n;
294
295		spin_lock_irqsave(&core->task_queue_lock, flags);
296		list_for_each_entry_safe(t, n, &core->task_queue, list) {
297			if (task == t) {
298				list_del_init(&t->list);
299				spin_unlock_irqrestore(&core->task_queue_lock,
300						       flags);
301				SAS_DPRINTK("%s: task 0x%p aborted from "
302					    "task_queue\n",
303					    __FUNCTION__, task);
304				return TASK_IS_ABORTED;
305			}
306		}
307		spin_unlock_irqrestore(&core->task_queue_lock, flags);
308	}
309
310	for (i = 0; i < 5; i++) {
311		SAS_DPRINTK("%s: aborting task 0x%p\n", __FUNCTION__, task);
312		res = si->dft->lldd_abort_task(task);
313
314		spin_lock_irqsave(&task->task_state_lock, flags);
315		if (task->task_state_flags & SAS_TASK_STATE_DONE) {
316			spin_unlock_irqrestore(&task->task_state_lock, flags);
317			SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__,
318				    task);
319			return TASK_IS_DONE;
320		}
321		spin_unlock_irqrestore(&task->task_state_lock, flags);
322
323		if (res == TMF_RESP_FUNC_COMPLETE) {
324			SAS_DPRINTK("%s: task 0x%p is aborted\n",
325				    __FUNCTION__, task);
326			return TASK_IS_ABORTED;
327		} else if (si->dft->lldd_query_task) {
328			SAS_DPRINTK("%s: querying task 0x%p\n",
329				    __FUNCTION__, task);
330			res = si->dft->lldd_query_task(task);
331			if (res == TMF_RESP_FUNC_SUCC) {
332				SAS_DPRINTK("%s: task 0x%p at LU\n",
333					    __FUNCTION__, task);
334				return TASK_IS_AT_LU;
335			} else if (res == TMF_RESP_FUNC_COMPLETE) {
336				SAS_DPRINTK("%s: task 0x%p not at LU\n",
337					    __FUNCTION__, task);
338				return TASK_IS_NOT_AT_LU;
339			}
340		}
341	}
342	return res;
343}
344
345static int sas_recover_lu(struct domain_device *dev, struct scsi_cmnd *cmd)
346{
347	int res = TMF_RESP_FUNC_FAILED;
348	struct scsi_lun lun;
349	struct sas_internal *i =
350		to_sas_internal(dev->port->ha->core.shost->transportt);
351
352	int_to_scsilun(cmd->device->lun, &lun);
353
354	SAS_DPRINTK("eh: device %llx LUN %x has the task\n",
355		    SAS_ADDR(dev->sas_addr),
356		    cmd->device->lun);
357
358	if (i->dft->lldd_abort_task_set)
359		res = i->dft->lldd_abort_task_set(dev, lun.scsi_lun);
360
361	if (res == TMF_RESP_FUNC_FAILED) {
362		if (i->dft->lldd_clear_task_set)
363			res = i->dft->lldd_clear_task_set(dev, lun.scsi_lun);
364	}
365
366	if (res == TMF_RESP_FUNC_FAILED) {
367		if (i->dft->lldd_lu_reset)
368			res = i->dft->lldd_lu_reset(dev, lun.scsi_lun);
369	}
370
371	return res;
372}
373
374static int sas_recover_I_T(struct domain_device *dev)
375{
376	int res = TMF_RESP_FUNC_FAILED;
377	struct sas_internal *i =
378		to_sas_internal(dev->port->ha->core.shost->transportt);
379
380	SAS_DPRINTK("I_T nexus reset for dev %016llx\n",
381		    SAS_ADDR(dev->sas_addr));
382
383	if (i->dft->lldd_I_T_nexus_reset)
384		res = i->dft->lldd_I_T_nexus_reset(dev);
385
386	return res;
387}
388
389void sas_scsi_recover_host(struct Scsi_Host *shost)
390{
391	struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
392	unsigned long flags;
393	LIST_HEAD(error_q);
394	struct scsi_cmnd *cmd, *n;
395	enum task_disposition res = TASK_IS_DONE;
396	int tmf_resp;
397	struct sas_internal *i = to_sas_internal(shost->transportt);
398
399	spin_lock_irqsave(shost->host_lock, flags);
400	list_splice_init(&shost->eh_cmd_q, &error_q);
401	spin_unlock_irqrestore(shost->host_lock, flags);
402
403	SAS_DPRINTK("Enter %s\n", __FUNCTION__);
404
405	/* All tasks on this list were marked SAS_TASK_STATE_ABORTED
406	 * by sas_scsi_timed_out() callback.
407	 */
408Again:
409	SAS_DPRINTK("going over list...\n");
410	list_for_each_entry_safe(cmd, n, &error_q, eh_entry) {
411		struct sas_task *task = TO_SAS_TASK(cmd);
412
413		SAS_DPRINTK("trying to find task 0x%p\n", task);
414		list_del_init(&cmd->eh_entry);
415		res = sas_scsi_find_task(task);
416
417		cmd->eh_eflags = 0;
418		shost->host_failed--;
419
420		switch (res) {
421		case TASK_IS_DONE:
422			SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__,
423				    task);
424			task->task_done(task);
425			continue;
426		case TASK_IS_ABORTED:
427			SAS_DPRINTK("%s: task 0x%p is aborted\n",
428				    __FUNCTION__, task);
429			task->task_done(task);
430			continue;
431		case TASK_IS_AT_LU:
432			SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task);
433			tmf_resp = sas_recover_lu(task->dev, cmd);
434			if (tmf_resp == TMF_RESP_FUNC_COMPLETE) {
435				SAS_DPRINTK("dev %016llx LU %x is "
436					    "recovered\n",
437					    SAS_ADDR(task->dev),
438					    cmd->device->lun);
439				task->task_done(task);
440				sas_scsi_clear_queue_lu(&error_q, cmd);
441				goto Again;
442			}
443			/* fallthrough */
444		case TASK_IS_NOT_AT_LU:
445			SAS_DPRINTK("task 0x%p is not at LU: I_T recover\n",
446				    task);
447			tmf_resp = sas_recover_I_T(task->dev);
448			if (tmf_resp == TMF_RESP_FUNC_COMPLETE) {
449				SAS_DPRINTK("I_T %016llx recovered\n",
450					    SAS_ADDR(task->dev->sas_addr));
451				task->task_done(task);
452				sas_scsi_clear_queue_I_T(&error_q, task->dev);
453				goto Again;
454			}
455			/* Hammer time :-) */
456			if (i->dft->lldd_clear_nexus_port) {
457				struct asd_sas_port *port = task->dev->port;
458				SAS_DPRINTK("clearing nexus for port:%d\n",
459					    port->id);
460				res = i->dft->lldd_clear_nexus_port(port);
461				if (res == TMF_RESP_FUNC_COMPLETE) {
462					SAS_DPRINTK("clear nexus port:%d "
463						    "succeeded\n", port->id);
464					task->task_done(task);
465					sas_scsi_clear_queue_port(&error_q,
466								  port);
467					goto Again;
468				}
469			}
470			if (i->dft->lldd_clear_nexus_ha) {
471				SAS_DPRINTK("clear nexus ha\n");
472				res = i->dft->lldd_clear_nexus_ha(ha);
473				if (res == TMF_RESP_FUNC_COMPLETE) {
474					SAS_DPRINTK("clear nexus ha "
475						    "succeeded\n");
476					task->task_done(task);
477					goto out;
478				}
479			}
480			/* If we are here -- this means that no amount
481			 * of effort could recover from errors.  Quite
482			 * possibly the HA just disappeared.
483			 */
484			SAS_DPRINTK("error from  device %llx, LUN %x "
485				    "couldn't be recovered in any way\n",
486				    SAS_ADDR(task->dev->sas_addr),
487				    cmd->device->lun);
488
489			task->task_done(task);
490			goto clear_q;
491		}
492	}
493out:
494	SAS_DPRINTK("--- Exit %s\n", __FUNCTION__);
495	return;
496clear_q:
497	SAS_DPRINTK("--- Exit %s -- clear_q\n", __FUNCTION__);
498	list_for_each_entry_safe(cmd, n, &error_q, eh_entry) {
499		struct sas_task *task = TO_SAS_TASK(cmd);
500		list_del_init(&cmd->eh_entry);
501		task->task_done(task);
502	}
503}
504
505enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd)
506{
507	struct sas_task *task = TO_SAS_TASK(cmd);
508	unsigned long flags;
509
510	if (!task) {
511		SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n",
512			    cmd, task);
513		return EH_HANDLED;
514	}
515
516	spin_lock_irqsave(&task->task_state_lock, flags);
517	if (task->task_state_flags & SAS_TASK_STATE_DONE) {
518		spin_unlock_irqrestore(&task->task_state_lock, flags);
519		SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n",
520			    cmd, task);
521		return EH_HANDLED;
522	}
523	task->task_state_flags |= SAS_TASK_STATE_ABORTED;
524	spin_unlock_irqrestore(&task->task_state_lock, flags);
525
526	SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_NOT_HANDLED\n",
527		    cmd, task);
528
529	return EH_NOT_HANDLED;
530}
531
532struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy)
533{
534	struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent);
535	struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
536	struct domain_device *found_dev = NULL;
537	int i;
538
539	spin_lock(&ha->phy_port_lock);
540	for (i = 0; i < ha->num_phys; i++) {
541		struct asd_sas_port *port = ha->sas_port[i];
542		struct domain_device *dev;
543
544		spin_lock(&port->dev_list_lock);
545		list_for_each_entry(dev, &port->dev_list, dev_list_node) {
546			if (rphy == dev->rphy) {
547				found_dev = dev;
548				spin_unlock(&port->dev_list_lock);
549				goto found;
550			}
551		}
552		spin_unlock(&port->dev_list_lock);
553	}
554 found:
555	spin_unlock(&ha->phy_port_lock);
556
557	return found_dev;
558}
559
560static inline struct domain_device *sas_find_target(struct scsi_target *starget)
561{
562	struct sas_rphy *rphy = dev_to_rphy(starget->dev.parent);
563
564	return sas_find_dev_by_rphy(rphy);
565}
566
567int sas_target_alloc(struct scsi_target *starget)
568{
569	struct domain_device *found_dev = sas_find_target(starget);
570
571	if (!found_dev)
572		return -ENODEV;
573
574	starget->hostdata = found_dev;
575	return 0;
576}
577
578#define SAS_DEF_QD 32
579#define SAS_MAX_QD 64
580
581int sas_slave_configure(struct scsi_device *scsi_dev)
582{
583	struct domain_device *dev = sdev_to_domain_dev(scsi_dev);
584	struct sas_ha_struct *sas_ha;
585
586	BUG_ON(dev->rphy->identify.device_type != SAS_END_DEVICE);
587
588	sas_ha = dev->port->ha;
589
590	sas_read_port_mode_page(scsi_dev);
591
592	if (scsi_dev->tagged_supported) {
593		scsi_set_tag_type(scsi_dev, MSG_SIMPLE_TAG);
594		scsi_activate_tcq(scsi_dev, SAS_DEF_QD);
595	} else {
596		SAS_DPRINTK("device %llx, LUN %x doesn't support "
597			    "TCQ\n", SAS_ADDR(dev->sas_addr),
598			    scsi_dev->lun);
599		scsi_dev->tagged_supported = 0;
600		scsi_set_tag_type(scsi_dev, 0);
601		scsi_deactivate_tcq(scsi_dev, 1);
602	}
603
604	return 0;
605}
606
607void sas_slave_destroy(struct scsi_device *scsi_dev)
608{
609}
610
611int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth)
612{
613	int res = min(new_depth, SAS_MAX_QD);
614
615	if (scsi_dev->tagged_supported)
616		scsi_adjust_queue_depth(scsi_dev, scsi_get_tag_type(scsi_dev),
617					res);
618	else {
619		struct domain_device *dev = sdev_to_domain_dev(scsi_dev);
620		sas_printk("device %llx LUN %x queue depth changed to 1\n",
621			   SAS_ADDR(dev->sas_addr),
622			   scsi_dev->lun);
623		scsi_adjust_queue_depth(scsi_dev, 0, 1);
624		res = 1;
625	}
626
627	return res;
628}
629
630int sas_change_queue_type(struct scsi_device *scsi_dev, int qt)
631{
632	if (!scsi_dev->tagged_supported)
633		return 0;
634
635	scsi_deactivate_tcq(scsi_dev, 1);
636
637	scsi_set_tag_type(scsi_dev, qt);
638	scsi_activate_tcq(scsi_dev, scsi_dev->queue_depth);
639
640	return qt;
641}
642
643int sas_bios_param(struct scsi_device *scsi_dev,
644			  struct block_device *bdev,
645			  sector_t capacity, int *hsc)
646{
647	hsc[0] = 255;
648	hsc[1] = 63;
649	sector_div(capacity, 255*63);
650	hsc[2] = capacity;
651
652	return 0;
653}
654
655/* ---------- Task Collector Thread implementation ---------- */
656
657static void sas_queue(struct sas_ha_struct *sas_ha)
658{
659	struct scsi_core *core = &sas_ha->core;
660	unsigned long flags;
661	LIST_HEAD(q);
662	int can_queue;
663	int res;
664	struct sas_internal *i = to_sas_internal(core->shost->transportt);
665
666	spin_lock_irqsave(&core->task_queue_lock, flags);
667	while (!core->queue_thread_kill &&
668	       !list_empty(&core->task_queue)) {
669
670		can_queue = sas_ha->lldd_queue_size - core->task_queue_size;
671		if (can_queue >= 0) {
672			can_queue = core->task_queue_size;
673			list_splice_init(&core->task_queue, &q);
674		} else {
675			struct list_head *a, *n;
676
677			can_queue = sas_ha->lldd_queue_size;
678			list_for_each_safe(a, n, &core->task_queue) {
679				list_move_tail(a, &q);
680				if (--can_queue == 0)
681					break;
682			}
683			can_queue = sas_ha->lldd_queue_size;
684		}
685		core->task_queue_size -= can_queue;
686		spin_unlock_irqrestore(&core->task_queue_lock, flags);
687		{
688			struct sas_task *task = list_entry(q.next,
689							   struct sas_task,
690							   list);
691			list_del_init(&q);
692			res = i->dft->lldd_execute_task(task, can_queue,
693							GFP_KERNEL);
694			if (unlikely(res))
695				__list_add(&q, task->list.prev, &task->list);
696		}
697		spin_lock_irqsave(&core->task_queue_lock, flags);
698		if (res) {
699			list_splice_init(&q, &core->task_queue); /*at head*/
700			core->task_queue_size += can_queue;
701		}
702	}
703	spin_unlock_irqrestore(&core->task_queue_lock, flags);
704}
705
706static DECLARE_COMPLETION(queue_th_comp);
707
708/**
709 * sas_queue_thread -- The Task Collector thread
710 * @_sas_ha: pointer to struct sas_ha
711 */
712static int sas_queue_thread(void *_sas_ha)
713{
714	struct sas_ha_struct *sas_ha = _sas_ha;
715	struct scsi_core *core = &sas_ha->core;
716
717	daemonize("sas_queue_%d", core->shost->host_no);
718	current->flags |= PF_NOFREEZE;
719
720	complete(&queue_th_comp);
721
722	while (1) {
723		down_interruptible(&core->queue_thread_sema);
724		sas_queue(sas_ha);
725		if (core->queue_thread_kill)
726			break;
727	}
728
729	complete(&queue_th_comp);
730
731	return 0;
732}
733
734int sas_init_queue(struct sas_ha_struct *sas_ha)
735{
736	int res;
737	struct scsi_core *core = &sas_ha->core;
738
739	spin_lock_init(&core->task_queue_lock);
740	core->task_queue_size = 0;
741	INIT_LIST_HEAD(&core->task_queue);
742	init_MUTEX_LOCKED(&core->queue_thread_sema);
743
744	res = kernel_thread(sas_queue_thread, sas_ha, 0);
745	if (res >= 0)
746		wait_for_completion(&queue_th_comp);
747
748	return res < 0 ? res : 0;
749}
750
751void sas_shutdown_queue(struct sas_ha_struct *sas_ha)
752{
753	unsigned long flags;
754	struct scsi_core *core = &sas_ha->core;
755	struct sas_task *task, *n;
756
757	init_completion(&queue_th_comp);
758	core->queue_thread_kill = 1;
759	up(&core->queue_thread_sema);
760	wait_for_completion(&queue_th_comp);
761
762	if (!list_empty(&core->task_queue))
763		SAS_DPRINTK("HA: %llx: scsi core task queue is NOT empty!?\n",
764			    SAS_ADDR(sas_ha->sas_addr));
765
766	spin_lock_irqsave(&core->task_queue_lock, flags);
767	list_for_each_entry_safe(task, n, &core->task_queue, list) {
768		struct scsi_cmnd *cmd = task->uldd_task;
769
770		list_del_init(&task->list);
771
772		ASSIGN_SAS_TASK(cmd, NULL);
773		sas_free_task(task);
774		cmd->result = DID_ABORT << 16;
775		cmd->scsi_done(cmd);
776	}
777	spin_unlock_irqrestore(&core->task_queue_lock, flags);
778}
779
780EXPORT_SYMBOL_GPL(sas_queuecommand);
781EXPORT_SYMBOL_GPL(sas_target_alloc);
782EXPORT_SYMBOL_GPL(sas_slave_configure);
783EXPORT_SYMBOL_GPL(sas_slave_destroy);
784EXPORT_SYMBOL_GPL(sas_change_queue_depth);
785EXPORT_SYMBOL_GPL(sas_change_queue_type);
786EXPORT_SYMBOL_GPL(sas_bios_param);
787