aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libsas
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libsas')
-rw-r--r--drivers/scsi/libsas/sas_discover.c62
-rw-r--r--drivers/scsi/libsas/sas_event.c6
-rw-r--r--drivers/scsi/libsas/sas_expander.c48
-rw-r--r--drivers/scsi/libsas/sas_init.c52
-rw-r--r--drivers/scsi/libsas/sas_internal.h9
-rw-r--r--drivers/scsi/libsas/sas_port.c14
-rw-r--r--drivers/scsi/libsas/sas_scsi_host.c290
7 files changed, 364 insertions, 117 deletions
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c
index fb7df7b75811..a65598b1e536 100644
--- a/drivers/scsi/libsas/sas_discover.c
+++ b/drivers/scsi/libsas/sas_discover.c
@@ -548,7 +548,7 @@ int sas_discover_sata(struct domain_device *dev)
548 548
549 res = sas_notify_lldd_dev_found(dev); 549 res = sas_notify_lldd_dev_found(dev);
550 if (res) 550 if (res)
551 return res; 551 goto out_err2;
552 552
553 switch (dev->dev_type) { 553 switch (dev->dev_type) {
554 case SATA_DEV: 554 case SATA_DEV:
@@ -560,11 +560,23 @@ int sas_discover_sata(struct domain_device *dev)
560 default: 560 default:
561 break; 561 break;
562 } 562 }
563 if (res)
564 goto out_err;
563 565
564 sas_notify_lldd_dev_gone(dev); 566 sas_notify_lldd_dev_gone(dev);
565 if (!res) { 567 res = sas_notify_lldd_dev_found(dev);
566 sas_notify_lldd_dev_found(dev); 568 if (res)
567 } 569 goto out_err2;
570
571 res = sas_rphy_add(dev->rphy);
572 if (res)
573 goto out_err;
574
575 return res;
576
577out_err:
578 sas_notify_lldd_dev_gone(dev);
579out_err2:
568 return res; 580 return res;
569} 581}
570 582
@@ -580,21 +592,17 @@ int sas_discover_end_dev(struct domain_device *dev)
580 592
581 res = sas_notify_lldd_dev_found(dev); 593 res = sas_notify_lldd_dev_found(dev);
582 if (res) 594 if (res)
583 return res; 595 goto out_err2;
584 596
585 res = sas_rphy_add(dev->rphy); 597 res = sas_rphy_add(dev->rphy);
586 if (res) 598 if (res)
587 goto out_err; 599 goto out_err;
588 600
589 /* do this to get the end device port attributes which will have
590 * been scanned in sas_rphy_add */
591 sas_notify_lldd_dev_gone(dev);
592 sas_notify_lldd_dev_found(dev);
593
594 return 0; 601 return 0;
595 602
596out_err: 603out_err:
597 sas_notify_lldd_dev_gone(dev); 604 sas_notify_lldd_dev_gone(dev);
605out_err2:
598 return res; 606 return res;
599} 607}
600 608
@@ -649,6 +657,7 @@ void sas_unregister_domain_devices(struct asd_sas_port *port)
649 */ 657 */
650static void sas_discover_domain(struct work_struct *work) 658static void sas_discover_domain(struct work_struct *work)
651{ 659{
660 struct domain_device *dev;
652 int error = 0; 661 int error = 0;
653 struct sas_discovery_event *ev = 662 struct sas_discovery_event *ev =
654 container_of(work, struct sas_discovery_event, work); 663 container_of(work, struct sas_discovery_event, work);
@@ -658,35 +667,42 @@ static void sas_discover_domain(struct work_struct *work)
658 &port->disc.pending); 667 &port->disc.pending);
659 668
660 if (port->port_dev) 669 if (port->port_dev)
661 return ; 670 return;
662 else { 671
663 error = sas_get_port_device(port); 672 error = sas_get_port_device(port);
664 if (error) 673 if (error)
665 return; 674 return;
666 } 675 dev = port->port_dev;
667 676
668 SAS_DPRINTK("DOING DISCOVERY on port %d, pid:%d\n", port->id, 677 SAS_DPRINTK("DOING DISCOVERY on port %d, pid:%d\n", port->id,
669 current->pid); 678 current->pid);
670 679
671 switch (port->port_dev->dev_type) { 680 switch (dev->dev_type) {
672 case SAS_END_DEV: 681 case SAS_END_DEV:
673 error = sas_discover_end_dev(port->port_dev); 682 error = sas_discover_end_dev(dev);
674 break; 683 break;
675 case EDGE_DEV: 684 case EDGE_DEV:
676 case FANOUT_DEV: 685 case FANOUT_DEV:
677 error = sas_discover_root_expander(port->port_dev); 686 error = sas_discover_root_expander(dev);
678 break; 687 break;
679 case SATA_DEV: 688 case SATA_DEV:
680 case SATA_PM: 689 case SATA_PM:
681 error = sas_discover_sata(port->port_dev); 690 error = sas_discover_sata(dev);
682 break; 691 break;
683 default: 692 default:
684 SAS_DPRINTK("unhandled device %d\n", port->port_dev->dev_type); 693 SAS_DPRINTK("unhandled device %d\n", dev->dev_type);
685 break; 694 break;
686 } 695 }
687 696
688 if (error) { 697 if (error) {
689 kfree(port->port_dev); /* not kobject_register-ed yet */ 698 sas_rphy_free(dev->rphy);
699 dev->rphy = NULL;
700
701 spin_lock(&port->dev_list_lock);
702 list_del_init(&dev->dev_list_node);
703 spin_unlock(&port->dev_list_lock);
704
705 kfree(dev); /* not kobject_register-ed yet */
690 port->port_dev = NULL; 706 port->port_dev = NULL;
691 } 707 }
692 708
@@ -726,7 +742,7 @@ int sas_discover_event(struct asd_sas_port *port, enum discover_event ev)
726 BUG_ON(ev >= DISC_NUM_EVENTS); 742 BUG_ON(ev >= DISC_NUM_EVENTS);
727 743
728 sas_queue_event(ev, &disc->disc_event_lock, &disc->pending, 744 sas_queue_event(ev, &disc->disc_event_lock, &disc->pending,
729 &disc->disc_work[ev].work, port->ha->core.shost); 745 &disc->disc_work[ev].work, port->ha);
730 746
731 return 0; 747 return 0;
732} 748}
diff --git a/drivers/scsi/libsas/sas_event.c b/drivers/scsi/libsas/sas_event.c
index d83392ee6823..9db30fb5caf2 100644
--- a/drivers/scsi/libsas/sas_event.c
+++ b/drivers/scsi/libsas/sas_event.c
@@ -31,7 +31,7 @@ static void notify_ha_event(struct sas_ha_struct *sas_ha, enum ha_event event)
31 BUG_ON(event >= HA_NUM_EVENTS); 31 BUG_ON(event >= HA_NUM_EVENTS);
32 32
33 sas_queue_event(event, &sas_ha->event_lock, &sas_ha->pending, 33 sas_queue_event(event, &sas_ha->event_lock, &sas_ha->pending,
34 &sas_ha->ha_events[event].work, sas_ha->core.shost); 34 &sas_ha->ha_events[event].work, sas_ha);
35} 35}
36 36
37static void notify_port_event(struct asd_sas_phy *phy, enum port_event event) 37static void notify_port_event(struct asd_sas_phy *phy, enum port_event event)
@@ -41,7 +41,7 @@ static void notify_port_event(struct asd_sas_phy *phy, enum port_event event)
41 BUG_ON(event >= PORT_NUM_EVENTS); 41 BUG_ON(event >= PORT_NUM_EVENTS);
42 42
43 sas_queue_event(event, &ha->event_lock, &phy->port_events_pending, 43 sas_queue_event(event, &ha->event_lock, &phy->port_events_pending,
44 &phy->port_events[event].work, ha->core.shost); 44 &phy->port_events[event].work, ha);
45} 45}
46 46
47static void notify_phy_event(struct asd_sas_phy *phy, enum phy_event event) 47static void notify_phy_event(struct asd_sas_phy *phy, enum phy_event event)
@@ -51,7 +51,7 @@ static void notify_phy_event(struct asd_sas_phy *phy, enum phy_event event)
51 BUG_ON(event >= PHY_NUM_EVENTS); 51 BUG_ON(event >= PHY_NUM_EVENTS);
52 52
53 sas_queue_event(event, &ha->event_lock, &phy->phy_events_pending, 53 sas_queue_event(event, &ha->event_lock, &phy->phy_events_pending,
54 &phy->phy_events[event].work, ha->core.shost); 54 &phy->phy_events[event].work, ha);
55} 55}
56 56
57int sas_init_events(struct sas_ha_struct *sas_ha) 57int sas_init_events(struct sas_ha_struct *sas_ha)
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index d31e6fa466f7..dc70c180e115 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -667,8 +667,9 @@ static struct domain_device *sas_ex_discover_end_dev(
667 return child; 667 return child;
668 668
669 out_list_del: 669 out_list_del:
670 sas_rphy_free(child->rphy);
671 child->rphy = NULL;
670 list_del(&child->dev_list_node); 672 list_del(&child->dev_list_node);
671 sas_rphy_free(rphy);
672 out_free: 673 out_free:
673 sas_port_delete(phy->port); 674 sas_port_delete(phy->port);
674 out_err: 675 out_err:
@@ -677,6 +678,29 @@ static struct domain_device *sas_ex_discover_end_dev(
677 return NULL; 678 return NULL;
678} 679}
679 680
681/* See if this phy is part of a wide port */
682static int sas_ex_join_wide_port(struct domain_device *parent, int phy_id)
683{
684 struct ex_phy *phy = &parent->ex_dev.ex_phy[phy_id];
685 int i;
686
687 for (i = 0; i < parent->ex_dev.num_phys; i++) {
688 struct ex_phy *ephy = &parent->ex_dev.ex_phy[i];
689
690 if (ephy == phy)
691 continue;
692
693 if (!memcmp(phy->attached_sas_addr, ephy->attached_sas_addr,
694 SAS_ADDR_SIZE) && ephy->port) {
695 sas_port_add_phy(ephy->port, phy->phy);
696 phy->phy_state = PHY_DEVICE_DISCOVERED;
697 return 0;
698 }
699 }
700
701 return -ENODEV;
702}
703
680static struct domain_device *sas_ex_discover_expander( 704static struct domain_device *sas_ex_discover_expander(
681 struct domain_device *parent, int phy_id) 705 struct domain_device *parent, int phy_id)
682{ 706{
@@ -809,6 +833,13 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id)
809 return res; 833 return res;
810 } 834 }
811 835
836 res = sas_ex_join_wide_port(dev, phy_id);
837 if (!res) {
838 SAS_DPRINTK("Attaching ex phy%d to wide port %016llx\n",
839 phy_id, SAS_ADDR(ex_phy->attached_sas_addr));
840 return res;
841 }
842
812 switch (ex_phy->attached_dev_type) { 843 switch (ex_phy->attached_dev_type) {
813 case SAS_END_DEV: 844 case SAS_END_DEV:
814 child = sas_ex_discover_end_dev(dev, phy_id); 845 child = sas_ex_discover_end_dev(dev, phy_id);
@@ -1431,14 +1462,23 @@ int sas_discover_root_expander(struct domain_device *dev)
1431 int res; 1462 int res;
1432 struct sas_expander_device *ex = rphy_to_expander_device(dev->rphy); 1463 struct sas_expander_device *ex = rphy_to_expander_device(dev->rphy);
1433 1464
1434 sas_rphy_add(dev->rphy); 1465 res = sas_rphy_add(dev->rphy);
1466 if (res)
1467 goto out_err;
1435 1468
1436 ex->level = dev->port->disc.max_level; /* 0 */ 1469 ex->level = dev->port->disc.max_level; /* 0 */
1437 res = sas_discover_expander(dev); 1470 res = sas_discover_expander(dev);
1438 if (!res) 1471 if (res)
1439 sas_ex_bfs_disc(dev->port); 1472 goto out_err2;
1473
1474 sas_ex_bfs_disc(dev->port);
1440 1475
1441 return res; 1476 return res;
1477
1478out_err2:
1479 sas_rphy_remove(dev->rphy);
1480out_err:
1481 return res;
1442} 1482}
1443 1483
1444/* ---------- Domain revalidation ---------- */ 1484/* ---------- Domain revalidation ---------- */
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c
index 2f0c07fc3f48..965698c8b7bf 100644
--- a/drivers/scsi/libsas/sas_init.c
+++ b/drivers/scsi/libsas/sas_init.c
@@ -87,6 +87,9 @@ int sas_register_ha(struct sas_ha_struct *sas_ha)
87 else if (sas_ha->lldd_queue_size == -1) 87 else if (sas_ha->lldd_queue_size == -1)
88 sas_ha->lldd_queue_size = 128; /* Sanity */ 88 sas_ha->lldd_queue_size = 128; /* Sanity */
89 89
90 sas_ha->state = SAS_HA_REGISTERED;
91 spin_lock_init(&sas_ha->state_lock);
92
90 error = sas_register_phys(sas_ha); 93 error = sas_register_phys(sas_ha);
91 if (error) { 94 if (error) {
92 printk(KERN_NOTICE "couldn't register sas phys:%d\n", error); 95 printk(KERN_NOTICE "couldn't register sas phys:%d\n", error);
@@ -127,12 +130,22 @@ Undo_phys:
127 130
128int sas_unregister_ha(struct sas_ha_struct *sas_ha) 131int sas_unregister_ha(struct sas_ha_struct *sas_ha)
129{ 132{
133 unsigned long flags;
134
135 /* Set the state to unregistered to avoid further
136 * events to be queued */
137 spin_lock_irqsave(&sas_ha->state_lock, flags);
138 sas_ha->state = SAS_HA_UNREGISTERED;
139 spin_unlock_irqrestore(&sas_ha->state_lock, flags);
140 scsi_flush_work(sas_ha->core.shost);
141
142 sas_unregister_ports(sas_ha);
143
130 if (sas_ha->lldd_max_execute_num > 1) { 144 if (sas_ha->lldd_max_execute_num > 1) {
131 sas_shutdown_queue(sas_ha); 145 sas_shutdown_queue(sas_ha);
146 sas_ha->lldd_max_execute_num = 1;
132 } 147 }
133 148
134 sas_unregister_ports(sas_ha);
135
136 return 0; 149 return 0;
137} 150}
138 151
@@ -146,6 +159,36 @@ static int sas_get_linkerrors(struct sas_phy *phy)
146 return sas_smp_get_phy_events(phy); 159 return sas_smp_get_phy_events(phy);
147} 160}
148 161
162int sas_phy_enable(struct sas_phy *phy, int enable)
163{
164 int ret;
165 enum phy_func command;
166
167 if (enable)
168 command = PHY_FUNC_LINK_RESET;
169 else
170 command = PHY_FUNC_DISABLE;
171
172 if (scsi_is_sas_phy_local(phy)) {
173 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
174 struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
175 struct asd_sas_phy *asd_phy = sas_ha->sas_phy[phy->number];
176 struct sas_internal *i =
177 to_sas_internal(sas_ha->core.shost->transportt);
178
179 if (!enable) {
180 sas_phy_disconnected(asd_phy);
181 sas_ha->notify_phy_event(asd_phy, PHYE_LOSS_OF_SIGNAL);
182 }
183 ret = i->dft->lldd_control_phy(asd_phy, command, NULL);
184 } else {
185 struct sas_rphy *rphy = dev_to_rphy(phy->dev.parent);
186 struct domain_device *ddev = sas_find_dev_by_rphy(rphy);
187 ret = sas_smp_phy_control(ddev, phy->number, command, NULL);
188 }
189 return ret;
190}
191
149int sas_phy_reset(struct sas_phy *phy, int hard_reset) 192int sas_phy_reset(struct sas_phy *phy, int hard_reset)
150{ 193{
151 int ret; 194 int ret;
@@ -172,8 +215,8 @@ int sas_phy_reset(struct sas_phy *phy, int hard_reset)
172 return ret; 215 return ret;
173} 216}
174 217
175static int sas_set_phy_speed(struct sas_phy *phy, 218int sas_set_phy_speed(struct sas_phy *phy,
176 struct sas_phy_linkrates *rates) 219 struct sas_phy_linkrates *rates)
177{ 220{
178 int ret; 221 int ret;
179 222
@@ -212,6 +255,7 @@ static int sas_set_phy_speed(struct sas_phy *phy,
212} 255}
213 256
214static struct sas_function_template sft = { 257static struct sas_function_template sft = {
258 .phy_enable = sas_phy_enable,
215 .phy_reset = sas_phy_reset, 259 .phy_reset = sas_phy_reset,
216 .set_phy_speed = sas_set_phy_speed, 260 .set_phy_speed = sas_set_phy_speed,
217 .get_linkerrors = sas_get_linkerrors, 261 .get_linkerrors = sas_get_linkerrors,
diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h
index 137d7e496b6d..a78638df2018 100644
--- a/drivers/scsi/libsas/sas_internal.h
+++ b/drivers/scsi/libsas/sas_internal.h
@@ -80,7 +80,7 @@ void sas_hae_reset(struct work_struct *work);
80static inline void sas_queue_event(int event, spinlock_t *lock, 80static inline void sas_queue_event(int event, spinlock_t *lock,
81 unsigned long *pending, 81 unsigned long *pending,
82 struct work_struct *work, 82 struct work_struct *work,
83 struct Scsi_Host *shost) 83 struct sas_ha_struct *sas_ha)
84{ 84{
85 unsigned long flags; 85 unsigned long flags;
86 86
@@ -91,7 +91,12 @@ static inline void sas_queue_event(int event, spinlock_t *lock,
91 } 91 }
92 __set_bit(event, pending); 92 __set_bit(event, pending);
93 spin_unlock_irqrestore(lock, flags); 93 spin_unlock_irqrestore(lock, flags);
94 scsi_queue_work(shost, work); 94
95 spin_lock_irqsave(&sas_ha->state_lock, flags);
96 if (sas_ha->state != SAS_HA_UNREGISTERED) {
97 scsi_queue_work(sas_ha->core.shost, work);
98 }
99 spin_unlock_irqrestore(&sas_ha->state_lock, flags);
95} 100}
96 101
97static inline void sas_begin_event(int event, spinlock_t *lock, 102static inline void sas_begin_event(int event, spinlock_t *lock,
diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c
index 971c37ceecb4..e1e2d085c920 100644
--- a/drivers/scsi/libsas/sas_port.c
+++ b/drivers/scsi/libsas/sas_port.c
@@ -42,10 +42,11 @@ static void sas_form_port(struct asd_sas_phy *phy)
42 struct asd_sas_port *port = phy->port; 42 struct asd_sas_port *port = phy->port;
43 struct sas_internal *si = 43 struct sas_internal *si =
44 to_sas_internal(sas_ha->core.shost->transportt); 44 to_sas_internal(sas_ha->core.shost->transportt);
45 unsigned long flags;
45 46
46 if (port) { 47 if (port) {
47 if (memcmp(port->attached_sas_addr, phy->attached_sas_addr, 48 if (memcmp(port->attached_sas_addr, phy->attached_sas_addr,
48 SAS_ADDR_SIZE) == 0) 49 SAS_ADDR_SIZE) != 0)
49 sas_deform_port(phy); 50 sas_deform_port(phy);
50 else { 51 else {
51 SAS_DPRINTK("%s: phy%d belongs to port%d already(%d)!\n", 52 SAS_DPRINTK("%s: phy%d belongs to port%d already(%d)!\n",
@@ -56,7 +57,7 @@ static void sas_form_port(struct asd_sas_phy *phy)
56 } 57 }
57 58
58 /* find a port */ 59 /* find a port */
59 spin_lock(&sas_ha->phy_port_lock); 60 spin_lock_irqsave(&sas_ha->phy_port_lock, flags);
60 for (i = 0; i < sas_ha->num_phys; i++) { 61 for (i = 0; i < sas_ha->num_phys; i++) {
61 port = sas_ha->sas_port[i]; 62 port = sas_ha->sas_port[i];
62 spin_lock(&port->phy_list_lock); 63 spin_lock(&port->phy_list_lock);
@@ -78,7 +79,7 @@ static void sas_form_port(struct asd_sas_phy *phy)
78 if (i >= sas_ha->num_phys) { 79 if (i >= sas_ha->num_phys) {
79 printk(KERN_NOTICE "%s: couldn't find a free port, bug?\n", 80 printk(KERN_NOTICE "%s: couldn't find a free port, bug?\n",
80 __FUNCTION__); 81 __FUNCTION__);
81 spin_unlock(&sas_ha->phy_port_lock); 82 spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags);
82 return; 83 return;
83 } 84 }
84 85
@@ -105,7 +106,7 @@ static void sas_form_port(struct asd_sas_phy *phy)
105 } else 106 } else
106 port->linkrate = max(port->linkrate, phy->linkrate); 107 port->linkrate = max(port->linkrate, phy->linkrate);
107 spin_unlock(&port->phy_list_lock); 108 spin_unlock(&port->phy_list_lock);
108 spin_unlock(&sas_ha->phy_port_lock); 109 spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags);
109 110
110 if (!port->port) { 111 if (!port->port) {
111 port->port = sas_port_alloc(phy->phy->dev.parent, port->id); 112 port->port = sas_port_alloc(phy->phy->dev.parent, port->id);
@@ -137,6 +138,7 @@ void sas_deform_port(struct asd_sas_phy *phy)
137 struct asd_sas_port *port = phy->port; 138 struct asd_sas_port *port = phy->port;
138 struct sas_internal *si = 139 struct sas_internal *si =
139 to_sas_internal(sas_ha->core.shost->transportt); 140 to_sas_internal(sas_ha->core.shost->transportt);
141 unsigned long flags;
140 142
141 if (!port) 143 if (!port)
142 return; /* done by a phy event */ 144 return; /* done by a phy event */
@@ -155,7 +157,7 @@ void sas_deform_port(struct asd_sas_phy *phy)
155 if (si->dft->lldd_port_deformed) 157 if (si->dft->lldd_port_deformed)
156 si->dft->lldd_port_deformed(phy); 158 si->dft->lldd_port_deformed(phy);
157 159
158 spin_lock(&sas_ha->phy_port_lock); 160 spin_lock_irqsave(&sas_ha->phy_port_lock, flags);
159 spin_lock(&port->phy_list_lock); 161 spin_lock(&port->phy_list_lock);
160 162
161 list_del_init(&phy->port_phy_el); 163 list_del_init(&phy->port_phy_el);
@@ -174,7 +176,7 @@ void sas_deform_port(struct asd_sas_phy *phy)
174 port->phy_mask = 0; 176 port->phy_mask = 0;
175 } 177 }
176 spin_unlock(&port->phy_list_lock); 178 spin_unlock(&port->phy_list_lock);
177 spin_unlock(&sas_ha->phy_port_lock); 179 spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags);
178 180
179 return; 181 return;
180} 182}
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index 22672d54aa27..897a5e2c55e4 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -34,6 +34,7 @@
34#include <scsi/scsi_transport_sas.h> 34#include <scsi/scsi_transport_sas.h>
35#include "../scsi_sas_internal.h" 35#include "../scsi_sas_internal.h"
36#include "../scsi_transport_api.h" 36#include "../scsi_transport_api.h"
37#include "../scsi_priv.h"
37 38
38#include <linux/err.h> 39#include <linux/err.h>
39#include <linux/blkdev.h> 40#include <linux/blkdev.h>
@@ -130,7 +131,7 @@ static enum task_attribute sas_scsi_get_task_attr(struct scsi_cmnd *cmd)
130 if (cmd->request && blk_rq_tagged(cmd->request)) { 131 if (cmd->request && blk_rq_tagged(cmd->request)) {
131 if (cmd->device->ordered_tags && 132 if (cmd->device->ordered_tags &&
132 (cmd->request->cmd_flags & REQ_HARDBARRIER)) 133 (cmd->request->cmd_flags & REQ_HARDBARRIER))
133 ta = TASK_ATTR_HOQ; 134 ta = TASK_ATTR_ORDERED;
134 } 135 }
135 return ta; 136 return ta;
136} 137}
@@ -281,6 +282,7 @@ enum task_disposition {
281 TASK_IS_ABORTED, 282 TASK_IS_ABORTED,
282 TASK_IS_AT_LU, 283 TASK_IS_AT_LU,
283 TASK_IS_NOT_AT_LU, 284 TASK_IS_NOT_AT_LU,
285 TASK_ABORT_FAILED,
284}; 286};
285 287
286static enum task_disposition sas_scsi_find_task(struct sas_task *task) 288static enum task_disposition sas_scsi_find_task(struct sas_task *task)
@@ -310,15 +312,6 @@ static enum task_disposition sas_scsi_find_task(struct sas_task *task)
310 spin_unlock_irqrestore(&core->task_queue_lock, flags); 312 spin_unlock_irqrestore(&core->task_queue_lock, flags);
311 } 313 }
312 314
313 spin_lock_irqsave(&task->task_state_lock, flags);
314 if (task->task_state_flags & SAS_TASK_INITIATOR_ABORTED) {
315 spin_unlock_irqrestore(&task->task_state_lock, flags);
316 SAS_DPRINTK("%s: task 0x%p already aborted\n",
317 __FUNCTION__, task);
318 return TASK_IS_ABORTED;
319 }
320 spin_unlock_irqrestore(&task->task_state_lock, flags);
321
322 for (i = 0; i < 5; i++) { 315 for (i = 0; i < 5; i++) {
323 SAS_DPRINTK("%s: aborting task 0x%p\n", __FUNCTION__, task); 316 SAS_DPRINTK("%s: aborting task 0x%p\n", __FUNCTION__, task);
324 res = si->dft->lldd_abort_task(task); 317 res = si->dft->lldd_abort_task(task);
@@ -340,15 +333,21 @@ static enum task_disposition sas_scsi_find_task(struct sas_task *task)
340 SAS_DPRINTK("%s: querying task 0x%p\n", 333 SAS_DPRINTK("%s: querying task 0x%p\n",
341 __FUNCTION__, task); 334 __FUNCTION__, task);
342 res = si->dft->lldd_query_task(task); 335 res = si->dft->lldd_query_task(task);
343 if (res == TMF_RESP_FUNC_SUCC) { 336 switch (res) {
337 case TMF_RESP_FUNC_SUCC:
344 SAS_DPRINTK("%s: task 0x%p at LU\n", 338 SAS_DPRINTK("%s: task 0x%p at LU\n",
345 __FUNCTION__, task); 339 __FUNCTION__, task);
346 return TASK_IS_AT_LU; 340 return TASK_IS_AT_LU;
347 } else if (res == TMF_RESP_FUNC_COMPLETE) { 341 case TMF_RESP_FUNC_COMPLETE:
348 SAS_DPRINTK("%s: task 0x%p not at LU\n", 342 SAS_DPRINTK("%s: task 0x%p not at LU\n",
349 __FUNCTION__, task); 343 __FUNCTION__, task);
350 return TASK_IS_NOT_AT_LU; 344 return TASK_IS_NOT_AT_LU;
351 } 345 case TMF_RESP_FUNC_FAILED:
346 SAS_DPRINTK("%s: task 0x%p failed to abort\n",
347 __FUNCTION__, task);
348 return TASK_ABORT_FAILED;
349 }
350
352 } 351 }
353 } 352 }
354 return res; 353 return res;
@@ -398,35 +397,113 @@ static int sas_recover_I_T(struct domain_device *dev)
398 return res; 397 return res;
399} 398}
400 399
401void sas_scsi_recover_host(struct Scsi_Host *shost) 400/* Find the sas_phy that's attached to this device */
401struct sas_phy *find_local_sas_phy(struct domain_device *dev)
402{
403 struct domain_device *pdev = dev->parent;
404 struct ex_phy *exphy = NULL;
405 int i;
406
407 /* Directly attached device */
408 if (!pdev)
409 return dev->port->phy;
410
411 /* Otherwise look in the expander */
412 for (i = 0; i < pdev->ex_dev.num_phys; i++)
413 if (!memcmp(dev->sas_addr,
414 pdev->ex_dev.ex_phy[i].attached_sas_addr,
415 SAS_ADDR_SIZE)) {
416 exphy = &pdev->ex_dev.ex_phy[i];
417 break;
418 }
419
420 BUG_ON(!exphy);
421 return exphy->phy;
422}
423
424/* Attempt to send a LUN reset message to a device */
425int sas_eh_device_reset_handler(struct scsi_cmnd *cmd)
426{
427 struct domain_device *dev = cmd_to_domain_dev(cmd);
428 struct sas_internal *i =
429 to_sas_internal(dev->port->ha->core.shost->transportt);
430 struct scsi_lun lun;
431 int res;
432
433 int_to_scsilun(cmd->device->lun, &lun);
434
435 if (!i->dft->lldd_lu_reset)
436 return FAILED;
437
438 res = i->dft->lldd_lu_reset(dev, lun.scsi_lun);
439 if (res == TMF_RESP_FUNC_SUCC || res == TMF_RESP_FUNC_COMPLETE)
440 return SUCCESS;
441
442 return FAILED;
443}
444
445/* Attempt to send a phy (bus) reset */
446int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd)
447{
448 struct domain_device *dev = cmd_to_domain_dev(cmd);
449 struct sas_phy *phy = find_local_sas_phy(dev);
450 int res;
451
452 res = sas_phy_reset(phy, 1);
453 if (res)
454 SAS_DPRINTK("Bus reset of %s failed 0x%x\n",
455 phy->dev.kobj.k_name,
456 res);
457 if (res == TMF_RESP_FUNC_SUCC || res == TMF_RESP_FUNC_COMPLETE)
458 return SUCCESS;
459
460 return FAILED;
461}
462
463/* Try to reset a device */
464static int try_to_reset_cmd_device(struct Scsi_Host *shost,
465 struct scsi_cmnd *cmd)
466{
467 int res;
468
469 if (!shost->hostt->eh_device_reset_handler)
470 goto try_bus_reset;
471
472 res = shost->hostt->eh_device_reset_handler(cmd);
473 if (res == SUCCESS)
474 return res;
475
476try_bus_reset:
477 if (shost->hostt->eh_bus_reset_handler)
478 return shost->hostt->eh_bus_reset_handler(cmd);
479
480 return FAILED;
481}
482
483static int sas_eh_handle_sas_errors(struct Scsi_Host *shost,
484 struct list_head *work_q,
485 struct list_head *done_q)
402{ 486{
403 struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
404 unsigned long flags;
405 LIST_HEAD(error_q);
406 struct scsi_cmnd *cmd, *n; 487 struct scsi_cmnd *cmd, *n;
407 enum task_disposition res = TASK_IS_DONE; 488 enum task_disposition res = TASK_IS_DONE;
408 int tmf_resp; 489 int tmf_resp, need_reset;
409 struct sas_internal *i = to_sas_internal(shost->transportt); 490 struct sas_internal *i = to_sas_internal(shost->transportt);
491 unsigned long flags;
492 struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
410 493
411 spin_lock_irqsave(shost->host_lock, flags);
412 list_splice_init(&shost->eh_cmd_q, &error_q);
413 spin_unlock_irqrestore(shost->host_lock, flags);
414
415 SAS_DPRINTK("Enter %s\n", __FUNCTION__);
416
417 /* All tasks on this list were marked SAS_TASK_STATE_ABORTED
418 * by sas_scsi_timed_out() callback.
419 */
420Again: 494Again:
421 SAS_DPRINTK("going over list...\n"); 495 list_for_each_entry_safe(cmd, n, work_q, eh_entry) {
422 list_for_each_entry_safe(cmd, n, &error_q, eh_entry) {
423 struct sas_task *task = TO_SAS_TASK(cmd); 496 struct sas_task *task = TO_SAS_TASK(cmd);
424 list_del_init(&cmd->eh_entry);
425 497
426 if (!task) { 498 if (!task)
427 SAS_DPRINTK("%s: taskless cmd?!\n", __FUNCTION__);
428 continue; 499 continue;
429 } 500
501 list_del_init(&cmd->eh_entry);
502
503 spin_lock_irqsave(&task->task_state_lock, flags);
504 need_reset = task->task_state_flags & SAS_TASK_NEED_DEV_RESET;
505 spin_unlock_irqrestore(&task->task_state_lock, flags);
506
430 SAS_DPRINTK("trying to find task 0x%p\n", task); 507 SAS_DPRINTK("trying to find task 0x%p\n", task);
431 res = sas_scsi_find_task(task); 508 res = sas_scsi_find_task(task);
432 509
@@ -437,11 +514,15 @@ Again:
437 SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__, 514 SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__,
438 task); 515 task);
439 task->task_done(task); 516 task->task_done(task);
517 if (need_reset)
518 try_to_reset_cmd_device(shost, cmd);
440 continue; 519 continue;
441 case TASK_IS_ABORTED: 520 case TASK_IS_ABORTED:
442 SAS_DPRINTK("%s: task 0x%p is aborted\n", 521 SAS_DPRINTK("%s: task 0x%p is aborted\n",
443 __FUNCTION__, task); 522 __FUNCTION__, task);
444 task->task_done(task); 523 task->task_done(task);
524 if (need_reset)
525 try_to_reset_cmd_device(shost, cmd);
445 continue; 526 continue;
446 case TASK_IS_AT_LU: 527 case TASK_IS_AT_LU:
447 SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task); 528 SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task);
@@ -452,11 +533,14 @@ Again:
452 SAS_ADDR(task->dev), 533 SAS_ADDR(task->dev),
453 cmd->device->lun); 534 cmd->device->lun);
454 task->task_done(task); 535 task->task_done(task);
455 sas_scsi_clear_queue_lu(&error_q, cmd); 536 if (need_reset)
537 try_to_reset_cmd_device(shost, cmd);
538 sas_scsi_clear_queue_lu(work_q, cmd);
456 goto Again; 539 goto Again;
457 } 540 }
458 /* fallthrough */ 541 /* fallthrough */
459 case TASK_IS_NOT_AT_LU: 542 case TASK_IS_NOT_AT_LU:
543 case TASK_ABORT_FAILED:
460 SAS_DPRINTK("task 0x%p is not at LU: I_T recover\n", 544 SAS_DPRINTK("task 0x%p is not at LU: I_T recover\n",
461 task); 545 task);
462 tmf_resp = sas_recover_I_T(task->dev); 546 tmf_resp = sas_recover_I_T(task->dev);
@@ -464,7 +548,9 @@ Again:
464 SAS_DPRINTK("I_T %016llx recovered\n", 548 SAS_DPRINTK("I_T %016llx recovered\n",
465 SAS_ADDR(task->dev->sas_addr)); 549 SAS_ADDR(task->dev->sas_addr));
466 task->task_done(task); 550 task->task_done(task);
467 sas_scsi_clear_queue_I_T(&error_q, task->dev); 551 if (need_reset)
552 try_to_reset_cmd_device(shost, cmd);
553 sas_scsi_clear_queue_I_T(work_q, task->dev);
468 goto Again; 554 goto Again;
469 } 555 }
470 /* Hammer time :-) */ 556 /* Hammer time :-) */
@@ -477,7 +563,9 @@ Again:
477 SAS_DPRINTK("clear nexus port:%d " 563 SAS_DPRINTK("clear nexus port:%d "
478 "succeeded\n", port->id); 564 "succeeded\n", port->id);
479 task->task_done(task); 565 task->task_done(task);
480 sas_scsi_clear_queue_port(&error_q, 566 if (need_reset)
567 try_to_reset_cmd_device(shost, cmd);
568 sas_scsi_clear_queue_port(work_q,
481 port); 569 port);
482 goto Again; 570 goto Again;
483 } 571 }
@@ -489,6 +577,8 @@ Again:
489 SAS_DPRINTK("clear nexus ha " 577 SAS_DPRINTK("clear nexus ha "
490 "succeeded\n"); 578 "succeeded\n");
491 task->task_done(task); 579 task->task_done(task);
580 if (need_reset)
581 try_to_reset_cmd_device(shost, cmd);
492 goto out; 582 goto out;
493 } 583 }
494 } 584 }
@@ -502,20 +592,54 @@ Again:
502 cmd->device->lun); 592 cmd->device->lun);
503 593
504 task->task_done(task); 594 task->task_done(task);
595 if (need_reset)
596 try_to_reset_cmd_device(shost, cmd);
505 goto clear_q; 597 goto clear_q;
506 } 598 }
507 } 599 }
508out: 600out:
509 scsi_eh_flush_done_q(&ha->eh_done_q); 601 return list_empty(work_q);
510 SAS_DPRINTK("--- Exit %s\n", __FUNCTION__);
511 return;
512clear_q: 602clear_q:
513 SAS_DPRINTK("--- Exit %s -- clear_q\n", __FUNCTION__); 603 SAS_DPRINTK("--- Exit %s -- clear_q\n", __FUNCTION__);
514 list_for_each_entry_safe(cmd, n, &error_q, eh_entry) { 604 list_for_each_entry_safe(cmd, n, work_q, eh_entry) {
515 struct sas_task *task = TO_SAS_TASK(cmd); 605 struct sas_task *task = TO_SAS_TASK(cmd);
516 list_del_init(&cmd->eh_entry); 606 list_del_init(&cmd->eh_entry);
517 task->task_done(task); 607 task->task_done(task);
518 } 608 }
609 return list_empty(work_q);
610}
611
612void sas_scsi_recover_host(struct Scsi_Host *shost)
613{
614 struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
615 unsigned long flags;
616 LIST_HEAD(eh_work_q);
617
618 spin_lock_irqsave(shost->host_lock, flags);
619 list_splice_init(&shost->eh_cmd_q, &eh_work_q);
620 spin_unlock_irqrestore(shost->host_lock, flags);
621
622 SAS_DPRINTK("Enter %s\n", __FUNCTION__);
623 /*
624 * Deal with commands that still have SAS tasks (i.e. they didn't
625 * complete via the normal sas_task completion mechanism)
626 */
627 if (sas_eh_handle_sas_errors(shost, &eh_work_q, &ha->eh_done_q))
628 goto out;
629
630 /*
631 * Now deal with SCSI commands that completed ok but have a an error
632 * code (and hopefully sense data) attached. This is roughly what
633 * scsi_unjam_host does, but we skip scsi_eh_abort_cmds because any
634 * command we see here has no sas_task and is thus unknown to the HA.
635 */
636 if (!scsi_eh_get_sense(&eh_work_q, &ha->eh_done_q))
637 scsi_eh_ready_devs(shost, &eh_work_q, &ha->eh_done_q);
638
639out:
640 scsi_eh_flush_done_q(&ha->eh_done_q);
641 SAS_DPRINTK("--- Exit %s\n", __FUNCTION__);
642 return;
519} 643}
520 644
521enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd) 645enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd)
@@ -524,24 +648,30 @@ enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd)
524 unsigned long flags; 648 unsigned long flags;
525 649
526 if (!task) { 650 if (!task) {
527 SAS_DPRINTK("command 0x%p, task 0x%p, gone: EH_HANDLED\n", 651 cmd->timeout_per_command /= 2;
528 cmd, task); 652 SAS_DPRINTK("command 0x%p, task 0x%p, gone: %s\n",
529 return EH_HANDLED; 653 cmd, task, (cmd->timeout_per_command ?
654 "EH_RESET_TIMER" : "EH_NOT_HANDLED"));
655 if (!cmd->timeout_per_command)
656 return EH_NOT_HANDLED;
657 return EH_RESET_TIMER;
530 } 658 }
531 659
532 spin_lock_irqsave(&task->task_state_lock, flags); 660 spin_lock_irqsave(&task->task_state_lock, flags);
533 if (task->task_state_flags & SAS_TASK_INITIATOR_ABORTED) { 661 BUG_ON(task->task_state_flags & SAS_TASK_STATE_ABORTED);
534 spin_unlock_irqrestore(&task->task_state_lock, flags);
535 SAS_DPRINTK("command 0x%p, task 0x%p, aborted by initiator: "
536 "EH_NOT_HANDLED\n", cmd, task);
537 return EH_NOT_HANDLED;
538 }
539 if (task->task_state_flags & SAS_TASK_STATE_DONE) { 662 if (task->task_state_flags & SAS_TASK_STATE_DONE) {
540 spin_unlock_irqrestore(&task->task_state_lock, flags); 663 spin_unlock_irqrestore(&task->task_state_lock, flags);
541 SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n", 664 SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n",
542 cmd, task); 665 cmd, task);
543 return EH_HANDLED; 666 return EH_HANDLED;
544 } 667 }
668 if (!(task->task_state_flags & SAS_TASK_AT_INITIATOR)) {
669 spin_unlock_irqrestore(&task->task_state_lock, flags);
670 SAS_DPRINTK("command 0x%p, task 0x%p, not at initiator: "
671 "EH_RESET_TIMER\n",
672 cmd, task);
673 return EH_RESET_TIMER;
674 }
545 task->task_state_flags |= SAS_TASK_STATE_ABORTED; 675 task->task_state_flags |= SAS_TASK_STATE_ABORTED;
546 spin_unlock_irqrestore(&task->task_state_lock, flags); 676 spin_unlock_irqrestore(&task->task_state_lock, flags);
547 677
@@ -557,8 +687,9 @@ struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy)
557 struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost); 687 struct sas_ha_struct *ha = SHOST_TO_SAS_HA(shost);
558 struct domain_device *found_dev = NULL; 688 struct domain_device *found_dev = NULL;
559 int i; 689 int i;
690 unsigned long flags;
560 691
561 spin_lock(&ha->phy_port_lock); 692 spin_lock_irqsave(&ha->phy_port_lock, flags);
562 for (i = 0; i < ha->num_phys; i++) { 693 for (i = 0; i < ha->num_phys; i++) {
563 struct asd_sas_port *port = ha->sas_port[i]; 694 struct asd_sas_port *port = ha->sas_port[i];
564 struct domain_device *dev; 695 struct domain_device *dev;
@@ -574,7 +705,7 @@ struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy)
574 spin_unlock(&port->dev_list_lock); 705 spin_unlock(&port->dev_list_lock);
575 } 706 }
576 found: 707 found:
577 spin_unlock(&ha->phy_port_lock); 708 spin_unlock_irqrestore(&ha->phy_port_lock, flags);
578 709
579 return found_dev; 710 return found_dev;
580} 711}
@@ -623,6 +754,8 @@ int sas_slave_configure(struct scsi_device *scsi_dev)
623 scsi_deactivate_tcq(scsi_dev, 1); 754 scsi_deactivate_tcq(scsi_dev, 1);
624 } 755 }
625 756
757 scsi_dev->allow_restart = 1;
758
626 return 0; 759 return 0;
627} 760}
628 761
@@ -799,46 +932,42 @@ void sas_shutdown_queue(struct sas_ha_struct *sas_ha)
799 spin_unlock_irqrestore(&core->task_queue_lock, flags); 932 spin_unlock_irqrestore(&core->task_queue_lock, flags);
800} 933}
801 934
802static int do_sas_task_abort(struct sas_task *task) 935/*
936 * Call the LLDD task abort routine directly. This function is intended for
937 * use by upper layers that need to tell the LLDD to abort a task.
938 */
939int __sas_task_abort(struct sas_task *task)
803{ 940{
804 struct scsi_cmnd *sc = task->uldd_task;
805 struct sas_internal *si = 941 struct sas_internal *si =
806 to_sas_internal(task->dev->port->ha->core.shost->transportt); 942 to_sas_internal(task->dev->port->ha->core.shost->transportt);
807 unsigned long flags; 943 unsigned long flags;
808 int res; 944 int res;
809 945
810 spin_lock_irqsave(&task->task_state_lock, flags); 946 spin_lock_irqsave(&task->task_state_lock, flags);
811 if (task->task_state_flags & SAS_TASK_STATE_ABORTED) { 947 if (task->task_state_flags & SAS_TASK_STATE_ABORTED ||
948 task->task_state_flags & SAS_TASK_STATE_DONE) {
812 spin_unlock_irqrestore(&task->task_state_lock, flags); 949 spin_unlock_irqrestore(&task->task_state_lock, flags);
813 SAS_DPRINTK("%s: Task %p already aborted.\n", __FUNCTION__, 950 SAS_DPRINTK("%s: Task %p already finished.\n", __FUNCTION__,
814 task); 951 task);
815 return 0; 952 return 0;
816 } 953 }
817 954 task->task_state_flags |= SAS_TASK_STATE_ABORTED;
818 task->task_state_flags |= SAS_TASK_INITIATOR_ABORTED;
819 if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
820 task->task_state_flags |= SAS_TASK_STATE_ABORTED;
821 spin_unlock_irqrestore(&task->task_state_lock, flags); 955 spin_unlock_irqrestore(&task->task_state_lock, flags);
822 956
823 if (!si->dft->lldd_abort_task) 957 if (!si->dft->lldd_abort_task)
824 return -ENODEV; 958 return -ENODEV;
825 959
826 res = si->dft->lldd_abort_task(task); 960 res = si->dft->lldd_abort_task(task);
961
962 spin_lock_irqsave(&task->task_state_lock, flags);
827 if ((task->task_state_flags & SAS_TASK_STATE_DONE) || 963 if ((task->task_state_flags & SAS_TASK_STATE_DONE) ||
828 (res == TMF_RESP_FUNC_COMPLETE)) 964 (res == TMF_RESP_FUNC_COMPLETE))
829 { 965 {
830 /* SMP commands don't have scsi_cmds(?) */ 966 spin_unlock_irqrestore(&task->task_state_lock, flags);
831 if (!sc) { 967 task->task_done(task);
832 task->task_done(task);
833 return 0;
834 }
835 scsi_req_abort_cmd(sc);
836 scsi_schedule_eh(sc->device->host);
837 return 0; 968 return 0;
838 } 969 }
839 970
840 spin_lock_irqsave(&task->task_state_lock, flags);
841 task->task_state_flags &= ~SAS_TASK_INITIATOR_ABORTED;
842 if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) 971 if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
843 task->task_state_flags &= ~SAS_TASK_STATE_ABORTED; 972 task->task_state_flags &= ~SAS_TASK_STATE_ABORTED;
844 spin_unlock_irqrestore(&task->task_state_lock, flags); 973 spin_unlock_irqrestore(&task->task_state_lock, flags);
@@ -846,17 +975,24 @@ static int do_sas_task_abort(struct sas_task *task)
846 return -EAGAIN; 975 return -EAGAIN;
847} 976}
848 977
849void sas_task_abort(struct work_struct *work) 978/*
979 * Tell an upper layer that it needs to initiate an abort for a given task.
980 * This should only ever be called by an LLDD.
981 */
982void sas_task_abort(struct sas_task *task)
850{ 983{
851 struct sas_task *task = 984 struct scsi_cmnd *sc = task->uldd_task;
852 container_of(work, struct sas_task, abort_work);
853 int i;
854 985
855 for (i = 0; i < 5; i++) 986 /* Escape for libsas internal commands */
856 if (!do_sas_task_abort(task)) 987 if (!sc) {
988 if (!del_timer(&task->timer))
857 return; 989 return;
990 task->timer.function(task->timer.data);
991 return;
992 }
858 993
859 SAS_DPRINTK("%s: Could not kill task!\n", __FUNCTION__); 994 scsi_req_abort_cmd(sc);
995 scsi_schedule_eh(sc->device->host);
860} 996}
861 997
862EXPORT_SYMBOL_GPL(sas_queuecommand); 998EXPORT_SYMBOL_GPL(sas_queuecommand);
@@ -866,5 +1002,9 @@ EXPORT_SYMBOL_GPL(sas_slave_destroy);
866EXPORT_SYMBOL_GPL(sas_change_queue_depth); 1002EXPORT_SYMBOL_GPL(sas_change_queue_depth);
867EXPORT_SYMBOL_GPL(sas_change_queue_type); 1003EXPORT_SYMBOL_GPL(sas_change_queue_type);
868EXPORT_SYMBOL_GPL(sas_bios_param); 1004EXPORT_SYMBOL_GPL(sas_bios_param);
1005EXPORT_SYMBOL_GPL(__sas_task_abort);
869EXPORT_SYMBOL_GPL(sas_task_abort); 1006EXPORT_SYMBOL_GPL(sas_task_abort);
870EXPORT_SYMBOL_GPL(sas_phy_reset); 1007EXPORT_SYMBOL_GPL(sas_phy_reset);
1008EXPORT_SYMBOL_GPL(sas_phy_enable);
1009EXPORT_SYMBOL_GPL(sas_eh_device_reset_handler);
1010EXPORT_SYMBOL_GPL(sas_eh_bus_reset_handler);