Linux Audio

Check our new training course

Loading...
v4.10.11
  1/*
  2 * Serial Attached SCSI (SAS) Transport Layer initialization
  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 <linux/module.h>
 27#include <linux/slab.h>
 28#include <linux/init.h>
 29#include <linux/device.h>
 30#include <linux/spinlock.h>
 31#include <scsi/sas_ata.h>
 32#include <scsi/scsi_host.h>
 33#include <scsi/scsi_device.h>
 34#include <scsi/scsi_transport.h>
 35#include <scsi/scsi_transport_sas.h>
 36
 37#include "sas_internal.h"
 38
 39#include "../scsi_sas_internal.h"
 40
 41static struct kmem_cache *sas_task_cache;
 42
 43struct sas_task *sas_alloc_task(gfp_t flags)
 44{
 45	struct sas_task *task = kmem_cache_zalloc(sas_task_cache, flags);
 46
 47	if (task) {
 
 48		spin_lock_init(&task->task_state_lock);
 49		task->task_state_flags = SAS_TASK_STATE_PENDING;
 50	}
 51
 52	return task;
 53}
 54EXPORT_SYMBOL_GPL(sas_alloc_task);
 55
 56struct sas_task *sas_alloc_slow_task(gfp_t flags)
 57{
 58	struct sas_task *task = sas_alloc_task(flags);
 59	struct sas_task_slow *slow = kmalloc(sizeof(*slow), flags);
 60
 61	if (!task || !slow) {
 62		if (task)
 63			kmem_cache_free(sas_task_cache, task);
 64		kfree(slow);
 65		return NULL;
 66	}
 67
 68	task->slow_task = slow;
 69	init_timer(&slow->timer);
 70	init_completion(&slow->completion);
 71
 72	return task;
 73}
 74EXPORT_SYMBOL_GPL(sas_alloc_slow_task);
 75
 76void sas_free_task(struct sas_task *task)
 77{
 78	if (task) {
 
 79		kfree(task->slow_task);
 80		kmem_cache_free(sas_task_cache, task);
 81	}
 82}
 83EXPORT_SYMBOL_GPL(sas_free_task);
 84
 85/*------------ SAS addr hash -----------*/
 86void sas_hash_addr(u8 *hashed, const u8 *sas_addr)
 87{
 88        const u32 poly = 0x00DB2777;
 89        u32     r = 0;
 90        int     i;
 91
 92        for (i = 0; i < 8; i++) {
 93                int b;
 94                for (b = 7; b >= 0; b--) {
 95                        r <<= 1;
 96                        if ((1 << b) & sas_addr[i]) {
 97                                if (!(r & 0x01000000))
 98                                        r ^= poly;
 99                        } else if (r & 0x01000000)
100                                r ^= poly;
101                }
102        }
103
104        hashed[0] = (r >> 16) & 0xFF;
105        hashed[1] = (r >> 8) & 0xFF ;
106        hashed[2] = r & 0xFF;
107}
108
109
110/* ---------- HA events ---------- */
111
112void sas_hae_reset(struct work_struct *work)
113{
114	struct sas_ha_event *ev = to_sas_ha_event(work);
115	struct sas_ha_struct *ha = ev->ha;
116
117	clear_bit(HAE_RESET, &ha->pending);
118}
119
120int sas_register_ha(struct sas_ha_struct *sas_ha)
121{
122	int error = 0;
123
124	mutex_init(&sas_ha->disco_mutex);
125	spin_lock_init(&sas_ha->phy_port_lock);
126	sas_hash_addr(sas_ha->hashed_sas_addr, sas_ha->sas_addr);
127
 
 
 
 
 
128	set_bit(SAS_HA_REGISTERED, &sas_ha->state);
129	spin_lock_init(&sas_ha->lock);
130	mutex_init(&sas_ha->drain_mutex);
131	init_waitqueue_head(&sas_ha->eh_wait_q);
132	INIT_LIST_HEAD(&sas_ha->defer_q);
133	INIT_LIST_HEAD(&sas_ha->eh_dev_q);
134
135	error = sas_register_phys(sas_ha);
136	if (error) {
137		printk(KERN_NOTICE "couldn't register sas phys:%d\n", error);
138		return error;
139	}
140
141	error = sas_register_ports(sas_ha);
142	if (error) {
143		printk(KERN_NOTICE "couldn't register sas ports:%d\n", error);
144		goto Undo_phys;
145	}
146
147	error = sas_init_events(sas_ha);
148	if (error) {
149		printk(KERN_NOTICE "couldn't start event thread:%d\n", error);
150		goto Undo_ports;
151	}
152
 
 
 
 
 
 
 
 
 
153	INIT_LIST_HEAD(&sas_ha->eh_done_q);
154	INIT_LIST_HEAD(&sas_ha->eh_ata_q);
155
156	return 0;
157
158Undo_ports:
159	sas_unregister_ports(sas_ha);
160Undo_phys:
161
162	return error;
163}
164
165static void sas_disable_events(struct sas_ha_struct *sas_ha)
166{
167	/* Set the state to unregistered to avoid further unchained
168	 * events to be queued, and flush any in-progress drainers
169	 */
170	mutex_lock(&sas_ha->drain_mutex);
171	spin_lock_irq(&sas_ha->lock);
172	clear_bit(SAS_HA_REGISTERED, &sas_ha->state);
173	spin_unlock_irq(&sas_ha->lock);
174	__sas_drain_work(sas_ha);
175	mutex_unlock(&sas_ha->drain_mutex);
176}
177
178int sas_unregister_ha(struct sas_ha_struct *sas_ha)
179{
180	sas_disable_events(sas_ha);
181	sas_unregister_ports(sas_ha);
182
183	/* flush unregistration work */
184	mutex_lock(&sas_ha->drain_mutex);
185	__sas_drain_work(sas_ha);
186	mutex_unlock(&sas_ha->drain_mutex);
 
 
 
 
 
187
188	return 0;
189}
190
191static int sas_get_linkerrors(struct sas_phy *phy)
192{
193	if (scsi_is_sas_phy_local(phy)) {
194		struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
195		struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
196		struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number];
197		struct sas_internal *i =
198			to_sas_internal(sas_ha->core.shost->transportt);
199
200		return i->dft->lldd_control_phy(asd_phy, PHY_FUNC_GET_EVENTS, NULL);
201	}
202
203	return sas_smp_get_phy_events(phy);
204}
205
206int sas_try_ata_reset(struct asd_sas_phy *asd_phy)
207{
208	struct domain_device *dev = NULL;
209
210	/* try to route user requested link resets through libata */
211	if (asd_phy->port)
212		dev = asd_phy->port->port_dev;
213
214	/* validate that dev has been probed */
215	if (dev)
216		dev = sas_find_dev_by_rphy(dev->rphy);
217
218	if (dev && dev_is_sata(dev)) {
219		sas_ata_schedule_reset(dev);
220		sas_ata_wait_eh(dev);
221		return 0;
222	}
223
224	return -ENODEV;
225}
226
227/**
228 * transport_sas_phy_reset - reset a phy and permit libata to manage the link
229 *
230 * phy reset request via sysfs in host workqueue context so we know we
231 * can block on eh and safely traverse the domain_device topology
232 */
233static int transport_sas_phy_reset(struct sas_phy *phy, int hard_reset)
234{
235	enum phy_func reset_type;
236
237	if (hard_reset)
238		reset_type = PHY_FUNC_HARD_RESET;
239	else
240		reset_type = PHY_FUNC_LINK_RESET;
241
242	if (scsi_is_sas_phy_local(phy)) {
243		struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
244		struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
245		struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number];
246		struct sas_internal *i =
247			to_sas_internal(sas_ha->core.shost->transportt);
248
249		if (!hard_reset && sas_try_ata_reset(asd_phy) == 0)
250			return 0;
251		return i->dft->lldd_control_phy(asd_phy, reset_type, NULL);
252	} else {
253		struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent);
254		struct domain_device *ddev = sas_find_dev_by_rphy(rphy);
255		struct domain_device *ata_dev = sas_ex_to_ata(ddev, phy->number);
256
257		if (ata_dev && !hard_reset) {
258			sas_ata_schedule_reset(ata_dev);
259			sas_ata_wait_eh(ata_dev);
260			return 0;
261		} else
262			return sas_smp_phy_control(ddev, phy->number, reset_type, NULL);
263	}
264}
265
266static int sas_phy_enable(struct sas_phy *phy, int enable)
267{
268	int ret;
269	enum phy_func cmd;
270
271	if (enable)
272		cmd = PHY_FUNC_LINK_RESET;
273	else
274		cmd = PHY_FUNC_DISABLE;
275
276	if (scsi_is_sas_phy_local(phy)) {
277		struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
278		struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
279		struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number];
280		struct sas_internal *i =
281			to_sas_internal(sas_ha->core.shost->transportt);
282
283		if (enable)
284			ret = transport_sas_phy_reset(phy, 0);
285		else
286			ret = i->dft->lldd_control_phy(asd_phy, cmd, NULL);
287	} else {
288		struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent);
289		struct domain_device *ddev = sas_find_dev_by_rphy(rphy);
290
291		if (enable)
292			ret = transport_sas_phy_reset(phy, 0);
293		else
294			ret = sas_smp_phy_control(ddev, phy->number, cmd, NULL);
295	}
296	return ret;
297}
298
299int sas_phy_reset(struct sas_phy *phy, int hard_reset)
300{
301	int ret;
302	enum phy_func reset_type;
303
304	if (!phy->enabled)
305		return -ENODEV;
306
307	if (hard_reset)
308		reset_type = PHY_FUNC_HARD_RESET;
309	else
310		reset_type = PHY_FUNC_LINK_RESET;
311
312	if (scsi_is_sas_phy_local(phy)) {
313		struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
314		struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
315		struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number];
316		struct sas_internal *i =
317			to_sas_internal(sas_ha->core.shost->transportt);
318
319		ret = i->dft->lldd_control_phy(asd_phy, reset_type, NULL);
320	} else {
321		struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent);
322		struct domain_device *ddev = sas_find_dev_by_rphy(rphy);
323		ret = sas_smp_phy_control(ddev, phy->number, reset_type, NULL);
324	}
325	return ret;
326}
327
328int sas_set_phy_speed(struct sas_phy *phy,
329		      struct sas_phy_linkrates *rates)
330{
331	int ret;
332
333	if ((rates->minimum_linkrate &&
334	     rates->minimum_linkrate > phy->maximum_linkrate) ||
335	    (rates->maximum_linkrate &&
336	     rates->maximum_linkrate < phy->minimum_linkrate))
337		return -EINVAL;
338
339	if (rates->minimum_linkrate &&
340	    rates->minimum_linkrate < phy->minimum_linkrate_hw)
341		rates->minimum_linkrate = phy->minimum_linkrate_hw;
342
343	if (rates->maximum_linkrate &&
344	    rates->maximum_linkrate > phy->maximum_linkrate_hw)
345		rates->maximum_linkrate = phy->maximum_linkrate_hw;
346
347	if (scsi_is_sas_phy_local(phy)) {
348		struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
349		struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
350		struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number];
351		struct sas_internal *i =
352			to_sas_internal(sas_ha->core.shost->transportt);
353
354		ret = i->dft->lldd_control_phy(asd_phy, PHY_FUNC_SET_LINK_RATE,
355					       rates);
356	} else {
357		struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent);
358		struct domain_device *ddev = sas_find_dev_by_rphy(rphy);
359		ret = sas_smp_phy_control(ddev, phy->number,
360					  PHY_FUNC_LINK_RESET, rates);
361
362	}
363
364	return ret;
365}
366
367void sas_prep_resume_ha(struct sas_ha_struct *ha)
368{
369	int i;
370
371	set_bit(SAS_HA_REGISTERED, &ha->state);
372
373	/* clear out any stale link events/data from the suspension path */
374	for (i = 0; i < ha->num_phys; i++) {
375		struct asd_sas_phy *phy = ha->sas_phy[i];
376
377		memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
378		phy->port_events_pending = 0;
379		phy->phy_events_pending = 0;
380		phy->frame_rcvd_size = 0;
381	}
382}
383EXPORT_SYMBOL(sas_prep_resume_ha);
384
385static int phys_suspended(struct sas_ha_struct *ha)
386{
387	int i, rc = 0;
388
389	for (i = 0; i < ha->num_phys; i++) {
390		struct asd_sas_phy *phy = ha->sas_phy[i];
391
392		if (phy->suspended)
393			rc++;
394	}
395
396	return rc;
397}
398
399void sas_resume_ha(struct sas_ha_struct *ha)
400{
401	const unsigned long tmo = msecs_to_jiffies(25000);
402	int i;
403
404	/* deform ports on phys that did not resume
405	 * at this point we may be racing the phy coming back (as posted
406	 * by the lldd).  So we post the event and once we are in the
407	 * libsas context check that the phy remains suspended before
408	 * tearing it down.
409	 */
410	i = phys_suspended(ha);
411	if (i)
412		dev_info(ha->dev, "waiting up to 25 seconds for %d phy%s to resume\n",
413			 i, i > 1 ? "s" : "");
414	wait_event_timeout(ha->eh_wait_q, phys_suspended(ha) == 0, tmo);
415	for (i = 0; i < ha->num_phys; i++) {
416		struct asd_sas_phy *phy = ha->sas_phy[i];
417
418		if (phy->suspended) {
419			dev_warn(&phy->phy->dev, "resume timeout\n");
420			sas_notify_phy_event(phy, PHYE_RESUME_TIMEOUT);
421		}
422	}
423
424	/* all phys are back up or timed out, turn on i/o so we can
425	 * flush out disks that did not return
426	 */
427	scsi_unblock_requests(ha->core.shost);
428	sas_drain_work(ha);
429}
430EXPORT_SYMBOL(sas_resume_ha);
431
432void sas_suspend_ha(struct sas_ha_struct *ha)
433{
434	int i;
435
436	sas_disable_events(ha);
437	scsi_block_requests(ha->core.shost);
438	for (i = 0; i < ha->num_phys; i++) {
439		struct asd_sas_port *port = ha->sas_port[i];
440
441		sas_discover_event(port, DISCE_SUSPEND);
442	}
443
444	/* flush suspend events while unregistered */
445	mutex_lock(&ha->drain_mutex);
446	__sas_drain_work(ha);
447	mutex_unlock(&ha->drain_mutex);
448}
449EXPORT_SYMBOL(sas_suspend_ha);
450
451static void sas_phy_release(struct sas_phy *phy)
452{
453	kfree(phy->hostdata);
454	phy->hostdata = NULL;
455}
456
457static void phy_reset_work(struct work_struct *work)
458{
459	struct sas_phy_data *d = container_of(work, typeof(*d), reset_work.work);
460
461	d->reset_result = transport_sas_phy_reset(d->phy, d->hard_reset);
462}
463
464static void phy_enable_work(struct work_struct *work)
465{
466	struct sas_phy_data *d = container_of(work, typeof(*d), enable_work.work);
467
468	d->enable_result = sas_phy_enable(d->phy, d->enable);
469}
470
471static int sas_phy_setup(struct sas_phy *phy)
472{
473	struct sas_phy_data *d = kzalloc(sizeof(*d), GFP_KERNEL);
474
475	if (!d)
476		return -ENOMEM;
477
478	mutex_init(&d->event_lock);
479	INIT_SAS_WORK(&d->reset_work, phy_reset_work);
480	INIT_SAS_WORK(&d->enable_work, phy_enable_work);
481	d->phy = phy;
482	phy->hostdata = d;
483
484	return 0;
485}
486
487static int queue_phy_reset(struct sas_phy *phy, int hard_reset)
488{
489	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
490	struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
491	struct sas_phy_data *d = phy->hostdata;
492	int rc;
493
494	if (!d)
495		return -ENOMEM;
496
497	/* libsas workqueue coordinates ata-eh reset with discovery */
498	mutex_lock(&d->event_lock);
499	d->reset_result = 0;
500	d->hard_reset = hard_reset;
501
502	spin_lock_irq(&ha->lock);
503	sas_queue_work(ha, &d->reset_work);
504	spin_unlock_irq(&ha->lock);
505
506	rc = sas_drain_work(ha);
507	if (rc == 0)
508		rc = d->reset_result;
509	mutex_unlock(&d->event_lock);
510
511	return rc;
512}
513
514static int queue_phy_enable(struct sas_phy *phy, int enable)
515{
516	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
517	struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
518	struct sas_phy_data *d = phy->hostdata;
519	int rc;
520
521	if (!d)
522		return -ENOMEM;
523
524	/* libsas workqueue coordinates ata-eh reset with discovery */
525	mutex_lock(&d->event_lock);
526	d->enable_result = 0;
527	d->enable = enable;
528
529	spin_lock_irq(&ha->lock);
530	sas_queue_work(ha, &d->enable_work);
531	spin_unlock_irq(&ha->lock);
532
533	rc = sas_drain_work(ha);
534	if (rc == 0)
535		rc = d->enable_result;
536	mutex_unlock(&d->event_lock);
537
538	return rc;
539}
540
541static struct sas_function_template sft = {
542	.phy_enable = queue_phy_enable,
543	.phy_reset = queue_phy_reset,
544	.phy_setup = sas_phy_setup,
545	.phy_release = sas_phy_release,
546	.set_phy_speed = sas_set_phy_speed,
547	.get_linkerrors = sas_get_linkerrors,
548	.smp_handler = sas_smp_handler,
549};
550
551struct scsi_transport_template *
552sas_domain_attach_transport(struct sas_domain_function_template *dft)
553{
554	struct scsi_transport_template *stt = sas_attach_transport(&sft);
555	struct sas_internal *i;
556
557	if (!stt)
558		return stt;
559
560	i = to_sas_internal(stt);
561	i->dft = dft;
562	stt->create_work_queue = 1;
563	stt->eh_timed_out = sas_scsi_timed_out;
564	stt->eh_strategy_handler = sas_scsi_recover_host;
565
566	return stt;
567}
568EXPORT_SYMBOL_GPL(sas_domain_attach_transport);
569
570
571void sas_domain_release_transport(struct scsi_transport_template *stt)
572{
573	sas_release_transport(stt);
574}
575EXPORT_SYMBOL_GPL(sas_domain_release_transport);
576
577/* ---------- SAS Class register/unregister ---------- */
578
579static int __init sas_class_init(void)
580{
581	sas_task_cache = KMEM_CACHE(sas_task, SLAB_HWCACHE_ALIGN);
582	if (!sas_task_cache)
583		return -ENOMEM;
584
585	return 0;
586}
587
588static void __exit sas_class_exit(void)
589{
590	kmem_cache_destroy(sas_task_cache);
591}
592
593MODULE_AUTHOR("Luben Tuikov <luben_tuikov@adaptec.com>");
594MODULE_DESCRIPTION("SAS Transport Layer");
595MODULE_LICENSE("GPL v2");
596
597module_init(sas_class_init);
598module_exit(sas_class_exit);
599
600EXPORT_SYMBOL_GPL(sas_register_ha);
601EXPORT_SYMBOL_GPL(sas_unregister_ha);
v3.15
  1/*
  2 * Serial Attached SCSI (SAS) Transport Layer initialization
  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 <linux/module.h>
 27#include <linux/slab.h>
 28#include <linux/init.h>
 29#include <linux/device.h>
 30#include <linux/spinlock.h>
 31#include <scsi/sas_ata.h>
 32#include <scsi/scsi_host.h>
 33#include <scsi/scsi_device.h>
 34#include <scsi/scsi_transport.h>
 35#include <scsi/scsi_transport_sas.h>
 36
 37#include "sas_internal.h"
 38
 39#include "../scsi_sas_internal.h"
 40
 41static struct kmem_cache *sas_task_cache;
 42
 43struct sas_task *sas_alloc_task(gfp_t flags)
 44{
 45	struct sas_task *task = kmem_cache_zalloc(sas_task_cache, flags);
 46
 47	if (task) {
 48		INIT_LIST_HEAD(&task->list);
 49		spin_lock_init(&task->task_state_lock);
 50		task->task_state_flags = SAS_TASK_STATE_PENDING;
 51	}
 52
 53	return task;
 54}
 55EXPORT_SYMBOL_GPL(sas_alloc_task);
 56
 57struct sas_task *sas_alloc_slow_task(gfp_t flags)
 58{
 59	struct sas_task *task = sas_alloc_task(flags);
 60	struct sas_task_slow *slow = kmalloc(sizeof(*slow), flags);
 61
 62	if (!task || !slow) {
 63		if (task)
 64			kmem_cache_free(sas_task_cache, task);
 65		kfree(slow);
 66		return NULL;
 67	}
 68
 69	task->slow_task = slow;
 70	init_timer(&slow->timer);
 71	init_completion(&slow->completion);
 72
 73	return task;
 74}
 75EXPORT_SYMBOL_GPL(sas_alloc_slow_task);
 76
 77void sas_free_task(struct sas_task *task)
 78{
 79	if (task) {
 80		BUG_ON(!list_empty(&task->list));
 81		kfree(task->slow_task);
 82		kmem_cache_free(sas_task_cache, task);
 83	}
 84}
 85EXPORT_SYMBOL_GPL(sas_free_task);
 86
 87/*------------ SAS addr hash -----------*/
 88void sas_hash_addr(u8 *hashed, const u8 *sas_addr)
 89{
 90        const u32 poly = 0x00DB2777;
 91        u32     r = 0;
 92        int     i;
 93
 94        for (i = 0; i < 8; i++) {
 95                int b;
 96                for (b = 7; b >= 0; b--) {
 97                        r <<= 1;
 98                        if ((1 << b) & sas_addr[i]) {
 99                                if (!(r & 0x01000000))
100                                        r ^= poly;
101                        } else if (r & 0x01000000)
102                                r ^= poly;
103                }
104        }
105
106        hashed[0] = (r >> 16) & 0xFF;
107        hashed[1] = (r >> 8) & 0xFF ;
108        hashed[2] = r & 0xFF;
109}
110
111
112/* ---------- HA events ---------- */
113
114void sas_hae_reset(struct work_struct *work)
115{
116	struct sas_ha_event *ev = to_sas_ha_event(work);
117	struct sas_ha_struct *ha = ev->ha;
118
119	clear_bit(HAE_RESET, &ha->pending);
120}
121
122int sas_register_ha(struct sas_ha_struct *sas_ha)
123{
124	int error = 0;
125
126	mutex_init(&sas_ha->disco_mutex);
127	spin_lock_init(&sas_ha->phy_port_lock);
128	sas_hash_addr(sas_ha->hashed_sas_addr, sas_ha->sas_addr);
129
130	if (sas_ha->lldd_queue_size == 0)
131		sas_ha->lldd_queue_size = 1;
132	else if (sas_ha->lldd_queue_size == -1)
133		sas_ha->lldd_queue_size = 128; /* Sanity */
134
135	set_bit(SAS_HA_REGISTERED, &sas_ha->state);
136	spin_lock_init(&sas_ha->lock);
137	mutex_init(&sas_ha->drain_mutex);
138	init_waitqueue_head(&sas_ha->eh_wait_q);
139	INIT_LIST_HEAD(&sas_ha->defer_q);
140	INIT_LIST_HEAD(&sas_ha->eh_dev_q);
141
142	error = sas_register_phys(sas_ha);
143	if (error) {
144		printk(KERN_NOTICE "couldn't register sas phys:%d\n", error);
145		return error;
146	}
147
148	error = sas_register_ports(sas_ha);
149	if (error) {
150		printk(KERN_NOTICE "couldn't register sas ports:%d\n", error);
151		goto Undo_phys;
152	}
153
154	error = sas_init_events(sas_ha);
155	if (error) {
156		printk(KERN_NOTICE "couldn't start event thread:%d\n", error);
157		goto Undo_ports;
158	}
159
160	if (sas_ha->lldd_max_execute_num > 1) {
161		error = sas_init_queue(sas_ha);
162		if (error) {
163			printk(KERN_NOTICE "couldn't start queue thread:%d, "
164			       "running in direct mode\n", error);
165			sas_ha->lldd_max_execute_num = 1;
166		}
167	}
168
169	INIT_LIST_HEAD(&sas_ha->eh_done_q);
170	INIT_LIST_HEAD(&sas_ha->eh_ata_q);
171
172	return 0;
173
174Undo_ports:
175	sas_unregister_ports(sas_ha);
176Undo_phys:
177
178	return error;
179}
180
181static void sas_disable_events(struct sas_ha_struct *sas_ha)
182{
183	/* Set the state to unregistered to avoid further unchained
184	 * events to be queued, and flush any in-progress drainers
185	 */
186	mutex_lock(&sas_ha->drain_mutex);
187	spin_lock_irq(&sas_ha->lock);
188	clear_bit(SAS_HA_REGISTERED, &sas_ha->state);
189	spin_unlock_irq(&sas_ha->lock);
190	__sas_drain_work(sas_ha);
191	mutex_unlock(&sas_ha->drain_mutex);
192}
193
194int sas_unregister_ha(struct sas_ha_struct *sas_ha)
195{
196	sas_disable_events(sas_ha);
197	sas_unregister_ports(sas_ha);
198
199	/* flush unregistration work */
200	mutex_lock(&sas_ha->drain_mutex);
201	__sas_drain_work(sas_ha);
202	mutex_unlock(&sas_ha->drain_mutex);
203
204	if (sas_ha->lldd_max_execute_num > 1) {
205		sas_shutdown_queue(sas_ha);
206		sas_ha->lldd_max_execute_num = 1;
207	}
208
209	return 0;
210}
211
212static int sas_get_linkerrors(struct sas_phy *phy)
213{
214	if (scsi_is_sas_phy_local(phy)) {
215		struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
216		struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
217		struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number];
218		struct sas_internal *i =
219			to_sas_internal(sas_ha->core.shost->transportt);
220
221		return i->dft->lldd_control_phy(asd_phy, PHY_FUNC_GET_EVENTS, NULL);
222	}
223
224	return sas_smp_get_phy_events(phy);
225}
226
227int sas_try_ata_reset(struct asd_sas_phy *asd_phy)
228{
229	struct domain_device *dev = NULL;
230
231	/* try to route user requested link resets through libata */
232	if (asd_phy->port)
233		dev = asd_phy->port->port_dev;
234
235	/* validate that dev has been probed */
236	if (dev)
237		dev = sas_find_dev_by_rphy(dev->rphy);
238
239	if (dev && dev_is_sata(dev)) {
240		sas_ata_schedule_reset(dev);
241		sas_ata_wait_eh(dev);
242		return 0;
243	}
244
245	return -ENODEV;
246}
247
248/**
249 * transport_sas_phy_reset - reset a phy and permit libata to manage the link
250 *
251 * phy reset request via sysfs in host workqueue context so we know we
252 * can block on eh and safely traverse the domain_device topology
253 */
254static int transport_sas_phy_reset(struct sas_phy *phy, int hard_reset)
255{
256	enum phy_func reset_type;
257
258	if (hard_reset)
259		reset_type = PHY_FUNC_HARD_RESET;
260	else
261		reset_type = PHY_FUNC_LINK_RESET;
262
263	if (scsi_is_sas_phy_local(phy)) {
264		struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
265		struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
266		struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number];
267		struct sas_internal *i =
268			to_sas_internal(sas_ha->core.shost->transportt);
269
270		if (!hard_reset && sas_try_ata_reset(asd_phy) == 0)
271			return 0;
272		return i->dft->lldd_control_phy(asd_phy, reset_type, NULL);
273	} else {
274		struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent);
275		struct domain_device *ddev = sas_find_dev_by_rphy(rphy);
276		struct domain_device *ata_dev = sas_ex_to_ata(ddev, phy->number);
277
278		if (ata_dev && !hard_reset) {
279			sas_ata_schedule_reset(ata_dev);
280			sas_ata_wait_eh(ata_dev);
281			return 0;
282		} else
283			return sas_smp_phy_control(ddev, phy->number, reset_type, NULL);
284	}
285}
286
287static int sas_phy_enable(struct sas_phy *phy, int enable)
288{
289	int ret;
290	enum phy_func cmd;
291
292	if (enable)
293		cmd = PHY_FUNC_LINK_RESET;
294	else
295		cmd = PHY_FUNC_DISABLE;
296
297	if (scsi_is_sas_phy_local(phy)) {
298		struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
299		struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
300		struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number];
301		struct sas_internal *i =
302			to_sas_internal(sas_ha->core.shost->transportt);
303
304		if (enable)
305			ret = transport_sas_phy_reset(phy, 0);
306		else
307			ret = i->dft->lldd_control_phy(asd_phy, cmd, NULL);
308	} else {
309		struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent);
310		struct domain_device *ddev = sas_find_dev_by_rphy(rphy);
311
312		if (enable)
313			ret = transport_sas_phy_reset(phy, 0);
314		else
315			ret = sas_smp_phy_control(ddev, phy->number, cmd, NULL);
316	}
317	return ret;
318}
319
320int sas_phy_reset(struct sas_phy *phy, int hard_reset)
321{
322	int ret;
323	enum phy_func reset_type;
324
325	if (!phy->enabled)
326		return -ENODEV;
327
328	if (hard_reset)
329		reset_type = PHY_FUNC_HARD_RESET;
330	else
331		reset_type = PHY_FUNC_LINK_RESET;
332
333	if (scsi_is_sas_phy_local(phy)) {
334		struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
335		struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
336		struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number];
337		struct sas_internal *i =
338			to_sas_internal(sas_ha->core.shost->transportt);
339
340		ret = i->dft->lldd_control_phy(asd_phy, reset_type, NULL);
341	} else {
342		struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent);
343		struct domain_device *ddev = sas_find_dev_by_rphy(rphy);
344		ret = sas_smp_phy_control(ddev, phy->number, reset_type, NULL);
345	}
346	return ret;
347}
348
349int sas_set_phy_speed(struct sas_phy *phy,
350		      struct sas_phy_linkrates *rates)
351{
352	int ret;
353
354	if ((rates->minimum_linkrate &&
355	     rates->minimum_linkrate > phy->maximum_linkrate) ||
356	    (rates->maximum_linkrate &&
357	     rates->maximum_linkrate < phy->minimum_linkrate))
358		return -EINVAL;
359
360	if (rates->minimum_linkrate &&
361	    rates->minimum_linkrate < phy->minimum_linkrate_hw)
362		rates->minimum_linkrate = phy->minimum_linkrate_hw;
363
364	if (rates->maximum_linkrate &&
365	    rates->maximum_linkrate > phy->maximum_linkrate_hw)
366		rates->maximum_linkrate = phy->maximum_linkrate_hw;
367
368	if (scsi_is_sas_phy_local(phy)) {
369		struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
370		struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
371		struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number];
372		struct sas_internal *i =
373			to_sas_internal(sas_ha->core.shost->transportt);
374
375		ret = i->dft->lldd_control_phy(asd_phy, PHY_FUNC_SET_LINK_RATE,
376					       rates);
377	} else {
378		struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent);
379		struct domain_device *ddev = sas_find_dev_by_rphy(rphy);
380		ret = sas_smp_phy_control(ddev, phy->number,
381					  PHY_FUNC_LINK_RESET, rates);
382
383	}
384
385	return ret;
386}
387
388void sas_prep_resume_ha(struct sas_ha_struct *ha)
389{
390	int i;
391
392	set_bit(SAS_HA_REGISTERED, &ha->state);
393
394	/* clear out any stale link events/data from the suspension path */
395	for (i = 0; i < ha->num_phys; i++) {
396		struct asd_sas_phy *phy = ha->sas_phy[i];
397
398		memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
399		phy->port_events_pending = 0;
400		phy->phy_events_pending = 0;
401		phy->frame_rcvd_size = 0;
402	}
403}
404EXPORT_SYMBOL(sas_prep_resume_ha);
405
406static int phys_suspended(struct sas_ha_struct *ha)
407{
408	int i, rc = 0;
409
410	for (i = 0; i < ha->num_phys; i++) {
411		struct asd_sas_phy *phy = ha->sas_phy[i];
412
413		if (phy->suspended)
414			rc++;
415	}
416
417	return rc;
418}
419
420void sas_resume_ha(struct sas_ha_struct *ha)
421{
422	const unsigned long tmo = msecs_to_jiffies(25000);
423	int i;
424
425	/* deform ports on phys that did not resume
426	 * at this point we may be racing the phy coming back (as posted
427	 * by the lldd).  So we post the event and once we are in the
428	 * libsas context check that the phy remains suspended before
429	 * tearing it down.
430	 */
431	i = phys_suspended(ha);
432	if (i)
433		dev_info(ha->dev, "waiting up to 25 seconds for %d phy%s to resume\n",
434			 i, i > 1 ? "s" : "");
435	wait_event_timeout(ha->eh_wait_q, phys_suspended(ha) == 0, tmo);
436	for (i = 0; i < ha->num_phys; i++) {
437		struct asd_sas_phy *phy = ha->sas_phy[i];
438
439		if (phy->suspended) {
440			dev_warn(&phy->phy->dev, "resume timeout\n");
441			sas_notify_phy_event(phy, PHYE_RESUME_TIMEOUT);
442		}
443	}
444
445	/* all phys are back up or timed out, turn on i/o so we can
446	 * flush out disks that did not return
447	 */
448	scsi_unblock_requests(ha->core.shost);
449	sas_drain_work(ha);
450}
451EXPORT_SYMBOL(sas_resume_ha);
452
453void sas_suspend_ha(struct sas_ha_struct *ha)
454{
455	int i;
456
457	sas_disable_events(ha);
458	scsi_block_requests(ha->core.shost);
459	for (i = 0; i < ha->num_phys; i++) {
460		struct asd_sas_port *port = ha->sas_port[i];
461
462		sas_discover_event(port, DISCE_SUSPEND);
463	}
464
465	/* flush suspend events while unregistered */
466	mutex_lock(&ha->drain_mutex);
467	__sas_drain_work(ha);
468	mutex_unlock(&ha->drain_mutex);
469}
470EXPORT_SYMBOL(sas_suspend_ha);
471
472static void sas_phy_release(struct sas_phy *phy)
473{
474	kfree(phy->hostdata);
475	phy->hostdata = NULL;
476}
477
478static void phy_reset_work(struct work_struct *work)
479{
480	struct sas_phy_data *d = container_of(work, typeof(*d), reset_work.work);
481
482	d->reset_result = transport_sas_phy_reset(d->phy, d->hard_reset);
483}
484
485static void phy_enable_work(struct work_struct *work)
486{
487	struct sas_phy_data *d = container_of(work, typeof(*d), enable_work.work);
488
489	d->enable_result = sas_phy_enable(d->phy, d->enable);
490}
491
492static int sas_phy_setup(struct sas_phy *phy)
493{
494	struct sas_phy_data *d = kzalloc(sizeof(*d), GFP_KERNEL);
495
496	if (!d)
497		return -ENOMEM;
498
499	mutex_init(&d->event_lock);
500	INIT_SAS_WORK(&d->reset_work, phy_reset_work);
501	INIT_SAS_WORK(&d->enable_work, phy_enable_work);
502	d->phy = phy;
503	phy->hostdata = d;
504
505	return 0;
506}
507
508static int queue_phy_reset(struct sas_phy *phy, int hard_reset)
509{
510	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
511	struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
512	struct sas_phy_data *d = phy->hostdata;
513	int rc;
514
515	if (!d)
516		return -ENOMEM;
517
518	/* libsas workqueue coordinates ata-eh reset with discovery */
519	mutex_lock(&d->event_lock);
520	d->reset_result = 0;
521	d->hard_reset = hard_reset;
522
523	spin_lock_irq(&ha->lock);
524	sas_queue_work(ha, &d->reset_work);
525	spin_unlock_irq(&ha->lock);
526
527	rc = sas_drain_work(ha);
528	if (rc == 0)
529		rc = d->reset_result;
530	mutex_unlock(&d->event_lock);
531
532	return rc;
533}
534
535static int queue_phy_enable(struct sas_phy *phy, int enable)
536{
537	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
538	struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
539	struct sas_phy_data *d = phy->hostdata;
540	int rc;
541
542	if (!d)
543		return -ENOMEM;
544
545	/* libsas workqueue coordinates ata-eh reset with discovery */
546	mutex_lock(&d->event_lock);
547	d->enable_result = 0;
548	d->enable = enable;
549
550	spin_lock_irq(&ha->lock);
551	sas_queue_work(ha, &d->enable_work);
552	spin_unlock_irq(&ha->lock);
553
554	rc = sas_drain_work(ha);
555	if (rc == 0)
556		rc = d->enable_result;
557	mutex_unlock(&d->event_lock);
558
559	return rc;
560}
561
562static struct sas_function_template sft = {
563	.phy_enable = queue_phy_enable,
564	.phy_reset = queue_phy_reset,
565	.phy_setup = sas_phy_setup,
566	.phy_release = sas_phy_release,
567	.set_phy_speed = sas_set_phy_speed,
568	.get_linkerrors = sas_get_linkerrors,
569	.smp_handler = sas_smp_handler,
570};
571
572struct scsi_transport_template *
573sas_domain_attach_transport(struct sas_domain_function_template *dft)
574{
575	struct scsi_transport_template *stt = sas_attach_transport(&sft);
576	struct sas_internal *i;
577
578	if (!stt)
579		return stt;
580
581	i = to_sas_internal(stt);
582	i->dft = dft;
583	stt->create_work_queue = 1;
584	stt->eh_timed_out = sas_scsi_timed_out;
585	stt->eh_strategy_handler = sas_scsi_recover_host;
586
587	return stt;
588}
589EXPORT_SYMBOL_GPL(sas_domain_attach_transport);
590
591
592void sas_domain_release_transport(struct scsi_transport_template *stt)
593{
594	sas_release_transport(stt);
595}
596EXPORT_SYMBOL_GPL(sas_domain_release_transport);
597
598/* ---------- SAS Class register/unregister ---------- */
599
600static int __init sas_class_init(void)
601{
602	sas_task_cache = KMEM_CACHE(sas_task, SLAB_HWCACHE_ALIGN);
603	if (!sas_task_cache)
604		return -ENOMEM;
605
606	return 0;
607}
608
609static void __exit sas_class_exit(void)
610{
611	kmem_cache_destroy(sas_task_cache);
612}
613
614MODULE_AUTHOR("Luben Tuikov <luben_tuikov@adaptec.com>");
615MODULE_DESCRIPTION("SAS Transport Layer");
616MODULE_LICENSE("GPL v2");
617
618module_init(sas_class_init);
619module_exit(sas_class_exit);
620
621EXPORT_SYMBOL_GPL(sas_register_ha);
622EXPORT_SYMBOL_GPL(sas_unregister_ha);