aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2012-01-12 20:57:35 -0500
committerJames Bottomley <JBottomley@Parallels.com>2012-02-29 16:33:02 -0500
commit354cf82980e2449e71fdaa3c6f170357ebd65467 (patch)
tree8300579ebb51e19e503437d5c1f5ce2fd5186f18
parenta692b0eec5efae382dfa800e8b4b083f172921a7 (diff)
[SCSI] libsas: let libata recover links that fail to transmit initial sig-fis
libsas fails to discover all sata devices in the domain. If a device fails negotiation and does not transmit a signature fis the link needs recovery. libata already understands how to manage slow to come up links, so treat these conditions as ata device attach events for the purposes of creating an ata_port. This allows libata to manage retrying link bring up. Rediscovery is modified to be careful about checking changes in dev_type. It looks like libsas leaks old devices if the sas address changes, but that's a fix for another patch. Acked-by: Jack Wang <jack_wang@usish.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/scsi/libsas/sas_ata.c71
-rw-r--r--drivers/scsi/libsas/sas_discover.c1
-rw-r--r--drivers/scsi/libsas/sas_expander.c178
-rw-r--r--drivers/scsi/libsas/sas_internal.h6
-rw-r--r--include/scsi/sas.h4
-rw-r--r--include/scsi/sas_ata.h8
6 files changed, 179 insertions, 89 deletions
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index ba1ebfe991d7..25008a42412f 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -278,26 +278,84 @@ static struct sas_internal *dev_to_sas_internal(struct domain_device *dev)
278 return to_sas_internal(dev->port->ha->core.shost->transportt); 278 return to_sas_internal(dev->port->ha->core.shost->transportt);
279} 279}
280 280
281static void sas_get_ata_command_set(struct domain_device *dev);
282
283int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy)
284{
285 if (phy->attached_tproto & SAS_PROTOCOL_STP)
286 dev->tproto = phy->attached_tproto;
287 if (phy->attached_sata_dev)
288 dev->tproto |= SATA_DEV;
289
290 if (phy->attached_dev_type == SATA_PENDING)
291 dev->dev_type = SATA_PENDING;
292 else {
293 int res;
294
295 dev->dev_type = SATA_DEV;
296 res = sas_get_report_phy_sata(dev->parent, phy->phy_id,
297 &dev->sata_dev.rps_resp);
298 if (res) {
299 SAS_DPRINTK("report phy sata to %016llx:0x%x returned "
300 "0x%x\n", SAS_ADDR(dev->parent->sas_addr),
301 phy->phy_id, res);
302 return res;
303 }
304 memcpy(dev->frame_rcvd, &dev->sata_dev.rps_resp.rps.fis,
305 sizeof(struct dev_to_host_fis));
306 /* TODO switch to ata_dev_classify() */
307 sas_get_ata_command_set(dev);
308 }
309 return 0;
310}
311
312static int sas_ata_clear_pending(struct domain_device *dev, struct ex_phy *phy)
313{
314 int res;
315
316 /* we weren't pending, so successfully end the reset sequence now */
317 if (dev->dev_type != SATA_PENDING)
318 return 1;
319
320 /* hmmm, if this succeeds do we need to repost the domain_device to the
321 * lldd so it can pick up new parameters?
322 */
323 res = sas_get_ata_info(dev, phy);
324 if (res)
325 return 0; /* retry */
326 else
327 return 1;
328}
329
281static int smp_ata_check_ready(struct ata_link *link) 330static int smp_ata_check_ready(struct ata_link *link)
282{ 331{
283 int res; 332 int res;
284 u8 addr[8];
285 struct ata_port *ap = link->ap; 333 struct ata_port *ap = link->ap;
286 struct domain_device *dev = ap->private_data; 334 struct domain_device *dev = ap->private_data;
287 struct domain_device *ex_dev = dev->parent; 335 struct domain_device *ex_dev = dev->parent;
288 struct sas_phy *phy = sas_get_local_phy(dev); 336 struct sas_phy *phy = sas_get_local_phy(dev);
337 struct ex_phy *ex_phy = &ex_dev->ex_dev.ex_phy[phy->number];
289 338
290 res = sas_get_phy_attached_sas_addr(ex_dev, phy->number, addr); 339 res = sas_ex_phy_discover(ex_dev, phy->number);
291 sas_put_local_phy(phy); 340 sas_put_local_phy(phy);
341
292 /* break the wait early if the expander is unreachable, 342 /* break the wait early if the expander is unreachable,
293 * otherwise keep polling 343 * otherwise keep polling
294 */ 344 */
295 if (res == -ECOMM) 345 if (res == -ECOMM)
296 return res; 346 return res;
297 if (res != SMP_RESP_FUNC_ACC || SAS_ADDR(addr) == 0) 347 if (res != SMP_RESP_FUNC_ACC)
298 return 0; 348 return 0;
299 else 349
300 return 1; 350 switch (ex_phy->attached_dev_type) {
351 case SATA_PENDING:
352 return 0;
353 case SAS_END_DEV:
354 if (ex_phy->attached_sata_dev)
355 return sas_ata_clear_pending(dev, ex_phy);
356 default:
357 return -ENODEV;
358 }
301} 359}
302 360
303static int local_ata_check_ready(struct ata_link *link) 361static int local_ata_check_ready(struct ata_link *link)
@@ -584,6 +642,9 @@ static void sas_get_ata_command_set(struct domain_device *dev)
584 struct dev_to_host_fis *fis = 642 struct dev_to_host_fis *fis =
585 (struct dev_to_host_fis *) dev->frame_rcvd; 643 (struct dev_to_host_fis *) dev->frame_rcvd;
586 644
645 if (dev->dev_type == SATA_PENDING)
646 return;
647
587 if ((fis->sector_count == 1 && /* ATA */ 648 if ((fis->sector_count == 1 && /* ATA */
588 fis->lbal == 1 && 649 fis->lbal == 1 &&
589 fis->lbam == 0 && 650 fis->lbam == 0 &&
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c
index c1ac99d25f5e..8bcfcaa7b2e1 100644
--- a/drivers/scsi/libsas/sas_discover.c
+++ b/drivers/scsi/libsas/sas_discover.c
@@ -48,6 +48,7 @@ void sas_init_dev(struct domain_device *dev)
48 case SATA_DEV: 48 case SATA_DEV:
49 case SATA_PM: 49 case SATA_PM:
50 case SATA_PM_PORT: 50 case SATA_PM_PORT:
51 case SATA_PENDING:
51 INIT_LIST_HEAD(&dev->sata_dev.children); 52 INIT_LIST_HEAD(&dev->sata_dev.children);
52 break; 53 break;
53 default: 54 default:
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index 4b2ecd35dc5a..7e2d3c4c6171 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -183,13 +183,27 @@ static char sas_route_char(struct domain_device *dev, struct ex_phy *phy)
183 } 183 }
184} 184}
185 185
186static void sas_set_ex_phy(struct domain_device *dev, int phy_id, 186static enum sas_dev_type to_dev_type(struct discover_resp *dr)
187 void *disc_resp)
188{ 187{
188 /* This is detecting a failure to transmit initial dev to host
189 * FIS as described in section J.5 of sas-2 r16
190 */
191 if (dr->attached_dev_type == NO_DEVICE && dr->attached_sata_dev &&
192 dr->linkrate >= SAS_LINK_RATE_1_5_GBPS)
193 return SATA_PENDING;
194 else
195 return dr->attached_dev_type;
196}
197
198static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)
199{
200 enum sas_dev_type dev_type;
201 enum sas_linkrate linkrate;
202 u8 sas_addr[SAS_ADDR_SIZE];
203 struct smp_resp *resp = rsp;
204 struct discover_resp *dr = &resp->disc;
189 struct expander_device *ex = &dev->ex_dev; 205 struct expander_device *ex = &dev->ex_dev;
190 struct ex_phy *phy = &ex->ex_phy[phy_id]; 206 struct ex_phy *phy = &ex->ex_phy[phy_id];
191 struct smp_resp *resp = disc_resp;
192 struct discover_resp *dr = &resp->disc;
193 struct sas_rphy *rphy = dev->rphy; 207 struct sas_rphy *rphy = dev->rphy;
194 bool new_phy = !phy->phy; 208 bool new_phy = !phy->phy;
195 char *type; 209 char *type;
@@ -213,8 +227,13 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id,
213 break; 227 break;
214 } 228 }
215 229
230 /* check if anything important changed to squelch debug */
231 dev_type = phy->attached_dev_type;
232 linkrate = phy->linkrate;
233 memcpy(sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE);
234
235 phy->attached_dev_type = to_dev_type(dr);
216 phy->phy_id = phy_id; 236 phy->phy_id = phy_id;
217 phy->attached_dev_type = dr->attached_dev_type;
218 phy->linkrate = dr->linkrate; 237 phy->linkrate = dr->linkrate;
219 phy->attached_sata_host = dr->attached_sata_host; 238 phy->attached_sata_host = dr->attached_sata_host;
220 phy->attached_sata_dev = dr->attached_sata_dev; 239 phy->attached_sata_dev = dr->attached_sata_dev;
@@ -229,7 +248,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id,
229 phy->last_da_index = -1; 248 phy->last_da_index = -1;
230 249
231 phy->phy->identify.sas_address = SAS_ADDR(phy->attached_sas_addr); 250 phy->phy->identify.sas_address = SAS_ADDR(phy->attached_sas_addr);
232 phy->phy->identify.device_type = phy->attached_dev_type; 251 phy->phy->identify.device_type = dr->attached_dev_type;
233 phy->phy->identify.initiator_port_protocols = phy->attached_iproto; 252 phy->phy->identify.initiator_port_protocols = phy->attached_iproto;
234 phy->phy->identify.target_port_protocols = phy->attached_tproto; 253 phy->phy->identify.target_port_protocols = phy->attached_tproto;
235 phy->phy->identify.phy_identifier = phy_id; 254 phy->phy->identify.phy_identifier = phy_id;
@@ -246,6 +265,9 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id,
246 } 265 }
247 266
248 switch (phy->attached_dev_type) { 267 switch (phy->attached_dev_type) {
268 case SATA_PENDING:
269 type = "stp pending";
270 break;
249 case NO_DEVICE: 271 case NO_DEVICE:
250 type = "no device"; 272 type = "no device";
251 break; 273 break;
@@ -270,6 +292,16 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id,
270 type = "unknown"; 292 type = "unknown";
271 } 293 }
272 294
295 /* this routine is polled by libata error recovery so filter
296 * unimportant messages
297 */
298 if (new_phy || phy->attached_dev_type != dev_type ||
299 phy->linkrate != linkrate ||
300 SAS_ADDR(phy->attached_sas_addr) != SAS_ADDR(sas_addr))
301 /* pass */;
302 else
303 return;
304
273 SAS_DPRINTK("ex %016llx phy%02d:%c:%X attached: %016llx (%s)\n", 305 SAS_DPRINTK("ex %016llx phy%02d:%c:%X attached: %016llx (%s)\n",
274 SAS_ADDR(dev->sas_addr), phy->phy_id, 306 SAS_ADDR(dev->sas_addr), phy->phy_id,
275 sas_route_char(dev, phy), phy->linkrate, 307 sas_route_char(dev, phy), phy->linkrate,
@@ -304,50 +336,25 @@ struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id)
304static int sas_ex_phy_discover_helper(struct domain_device *dev, u8 *disc_req, 336static int sas_ex_phy_discover_helper(struct domain_device *dev, u8 *disc_req,
305 u8 *disc_resp, int single) 337 u8 *disc_resp, int single)
306{ 338{
307 struct domain_device *ata_dev = sas_ex_to_ata(dev, single); 339 struct discover_resp *dr;
308 int i, res; 340 int res;
309 341
310 disc_req[9] = single; 342 disc_req[9] = single;
311 for (i = 1 ; i < 3; i++) {
312 struct discover_resp *dr;
313 343
314 res = smp_execute_task(dev, disc_req, DISCOVER_REQ_SIZE, 344 res = smp_execute_task(dev, disc_req, DISCOVER_REQ_SIZE,
315 disc_resp, DISCOVER_RESP_SIZE); 345 disc_resp, DISCOVER_RESP_SIZE);
316 if (res) 346 if (res)
317 return res; 347 return res;
318 dr = &((struct smp_resp *)disc_resp)->disc; 348 dr = &((struct smp_resp *)disc_resp)->disc;
319 if (memcmp(dev->sas_addr, dr->attached_sas_addr, 349 if (memcmp(dev->sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE) == 0) {
320 SAS_ADDR_SIZE) == 0) { 350 sas_printk("Found loopback topology, just ignore it!\n");
321 sas_printk("Found loopback topology, just ignore it!\n"); 351 return 0;
322 return 0;
323 }
324
325 /* This is detecting a failure to transmit initial
326 * dev to host FIS as described in section J.5 of
327 * sas-2 r16
328 */
329 if (!(dr->attached_dev_type == 0 &&
330 dr->attached_sata_dev))
331 break;
332
333 /* In order to generate the dev to host FIS, we send a
334 * link reset to the expander port. If a device was
335 * previously detected on this port we ask libata to
336 * manage the reset and link recovery.
337 */
338 if (ata_dev) {
339 sas_ata_schedule_reset(ata_dev);
340 break;
341 }
342 sas_smp_phy_control(dev, single, PHY_FUNC_LINK_RESET, NULL);
343 /* Wait for the reset to trigger the negotiation */
344 msleep(500);
345 } 352 }
346 sas_set_ex_phy(dev, single, disc_resp); 353 sas_set_ex_phy(dev, single, disc_resp);
347 return 0; 354 return 0;
348} 355}
349 356
350static int sas_ex_phy_discover(struct domain_device *dev, int single) 357int sas_ex_phy_discover(struct domain_device *dev, int single)
351{ 358{
352 struct expander_device *ex = &dev->ex_dev; 359 struct expander_device *ex = &dev->ex_dev;
353 int res = 0; 360 int res = 0;
@@ -652,9 +659,8 @@ int sas_smp_get_phy_events(struct sas_phy *phy)
652#define RPS_REQ_SIZE 16 659#define RPS_REQ_SIZE 16
653#define RPS_RESP_SIZE 60 660#define RPS_RESP_SIZE 60
654 661
655static int sas_get_report_phy_sata(struct domain_device *dev, 662int sas_get_report_phy_sata(struct domain_device *dev, int phy_id,
656 int phy_id, 663 struct smp_resp *rps_resp)
657 struct smp_resp *rps_resp)
658{ 664{
659 int res; 665 int res;
660 u8 *rps_req = alloc_smp_req(RPS_REQ_SIZE); 666 u8 *rps_req = alloc_smp_req(RPS_REQ_SIZE);
@@ -764,21 +770,9 @@ static struct domain_device *sas_ex_discover_end_dev(
764 770
765#ifdef CONFIG_SCSI_SAS_ATA 771#ifdef CONFIG_SCSI_SAS_ATA
766 if ((phy->attached_tproto & SAS_PROTOCOL_STP) || phy->attached_sata_dev) { 772 if ((phy->attached_tproto & SAS_PROTOCOL_STP) || phy->attached_sata_dev) {
767 child->dev_type = SATA_DEV; 773 res = sas_get_ata_info(child, phy);
768 if (phy->attached_tproto & SAS_PROTOCOL_STP) 774 if (res)
769 child->tproto = phy->attached_tproto;
770 if (phy->attached_sata_dev)
771 child->tproto |= SATA_DEV;
772 res = sas_get_report_phy_sata(parent, phy_id,
773 &child->sata_dev.rps_resp);
774 if (res) {
775 SAS_DPRINTK("report phy sata to %016llx:0x%x returned "
776 "0x%x\n", SAS_ADDR(parent->sas_addr),
777 phy_id, res);
778 goto out_free; 775 goto out_free;
779 }
780 memcpy(child->frame_rcvd, &child->sata_dev.rps_resp.rps.fis,
781 sizeof(struct dev_to_host_fis));
782 776
783 rphy = sas_end_device_alloc(phy->port); 777 rphy = sas_end_device_alloc(phy->port);
784 if (unlikely(!rphy)) 778 if (unlikely(!rphy))
@@ -993,7 +987,8 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id)
993 987
994 if (ex_phy->attached_dev_type != SAS_END_DEV && 988 if (ex_phy->attached_dev_type != SAS_END_DEV &&
995 ex_phy->attached_dev_type != FANOUT_DEV && 989 ex_phy->attached_dev_type != FANOUT_DEV &&
996 ex_phy->attached_dev_type != EDGE_DEV) { 990 ex_phy->attached_dev_type != EDGE_DEV &&
991 ex_phy->attached_dev_type != SATA_PENDING) {
997 SAS_DPRINTK("unknown device type(0x%x) attached to ex %016llx " 992 SAS_DPRINTK("unknown device type(0x%x) attached to ex %016llx "
998 "phy 0x%x\n", ex_phy->attached_dev_type, 993 "phy 0x%x\n", ex_phy->attached_dev_type,
999 SAS_ADDR(dev->sas_addr), 994 SAS_ADDR(dev->sas_addr),
@@ -1019,6 +1014,7 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id)
1019 1014
1020 switch (ex_phy->attached_dev_type) { 1015 switch (ex_phy->attached_dev_type) {
1021 case SAS_END_DEV: 1016 case SAS_END_DEV:
1017 case SATA_PENDING:
1022 child = sas_ex_discover_end_dev(dev, phy_id); 1018 child = sas_ex_discover_end_dev(dev, phy_id);
1023 break; 1019 break;
1024 case FANOUT_DEV: 1020 case FANOUT_DEV:
@@ -1688,8 +1684,8 @@ static int sas_get_phy_change_count(struct domain_device *dev,
1688 return res; 1684 return res;
1689} 1685}
1690 1686
1691int sas_get_phy_attached_sas_addr(struct domain_device *dev, int phy_id, 1687static int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id,
1692 u8 *attached_sas_addr) 1688 u8 *sas_addr, enum sas_dev_type *type)
1693{ 1689{
1694 int res; 1690 int res;
1695 struct smp_resp *disc_resp; 1691 struct smp_resp *disc_resp;
@@ -1701,10 +1697,11 @@ int sas_get_phy_attached_sas_addr(struct domain_device *dev, int phy_id,
1701 dr = &disc_resp->disc; 1697 dr = &disc_resp->disc;
1702 1698
1703 res = sas_get_phy_discover(dev, phy_id, disc_resp); 1699 res = sas_get_phy_discover(dev, phy_id, disc_resp);
1704 if (!res) { 1700 if (res == 0) {
1705 memcpy(attached_sas_addr,disc_resp->disc.attached_sas_addr,8); 1701 memcpy(sas_addr, disc_resp->disc.attached_sas_addr, 8);
1706 if (dr->attached_dev_type == 0) 1702 *type = to_dev_type(dr);
1707 memset(attached_sas_addr, 0, 8); 1703 if (*type == 0)
1704 memset(sas_addr, 0, 8);
1708 } 1705 }
1709 kfree(disc_resp); 1706 kfree(disc_resp);
1710 return res; 1707 return res;
@@ -1953,39 +1950,62 @@ out:
1953 return res; 1950 return res;
1954} 1951}
1955 1952
1953static bool dev_type_flutter(enum sas_dev_type new, enum sas_dev_type old)
1954{
1955 if (old == new)
1956 return true;
1957
1958 /* treat device directed resets as flutter, if we went
1959 * SAS_END_DEV to SATA_PENDING the link needs recovery
1960 */
1961 if ((old == SATA_PENDING && new == SAS_END_DEV) ||
1962 (old == SAS_END_DEV && new == SATA_PENDING))
1963 return true;
1964
1965 return false;
1966}
1967
1956static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last) 1968static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last)
1957{ 1969{
1958 struct expander_device *ex = &dev->ex_dev; 1970 struct expander_device *ex = &dev->ex_dev;
1959 struct ex_phy *phy = &ex->ex_phy[phy_id]; 1971 struct ex_phy *phy = &ex->ex_phy[phy_id];
1960 u8 attached_sas_addr[8]; 1972 enum sas_dev_type type = NO_DEVICE;
1973 u8 sas_addr[8];
1961 int res; 1974 int res;
1962 1975
1963 res = sas_get_phy_attached_sas_addr(dev, phy_id, attached_sas_addr); 1976 res = sas_get_phy_attached_dev(dev, phy_id, sas_addr, &type);
1964 switch (res) { 1977 switch (res) {
1965 case SMP_RESP_NO_PHY: 1978 case SMP_RESP_NO_PHY:
1966 phy->phy_state = PHY_NOT_PRESENT; 1979 phy->phy_state = PHY_NOT_PRESENT;
1967 sas_unregister_devs_sas_addr(dev, phy_id, last); 1980 sas_unregister_devs_sas_addr(dev, phy_id, last);
1968 goto out; break; 1981 return res;
1969 case SMP_RESP_PHY_VACANT: 1982 case SMP_RESP_PHY_VACANT:
1970 phy->phy_state = PHY_VACANT; 1983 phy->phy_state = PHY_VACANT;
1971 sas_unregister_devs_sas_addr(dev, phy_id, last); 1984 sas_unregister_devs_sas_addr(dev, phy_id, last);
1972 goto out; break; 1985 return res;
1973 case SMP_RESP_FUNC_ACC: 1986 case SMP_RESP_FUNC_ACC:
1974 break; 1987 break;
1975 } 1988 }
1976 1989
1977 if (SAS_ADDR(attached_sas_addr) == 0) { 1990 if (SAS_ADDR(sas_addr) == 0) {
1978 phy->phy_state = PHY_EMPTY; 1991 phy->phy_state = PHY_EMPTY;
1979 sas_unregister_devs_sas_addr(dev, phy_id, last); 1992 sas_unregister_devs_sas_addr(dev, phy_id, last);
1980 } else if (SAS_ADDR(attached_sas_addr) == 1993 return res;
1981 SAS_ADDR(phy->attached_sas_addr)) { 1994 } else if (SAS_ADDR(sas_addr) == SAS_ADDR(phy->attached_sas_addr) &&
1982 SAS_DPRINTK("ex %016llx phy 0x%x broadcast flutter\n", 1995 dev_type_flutter(type, phy->attached_dev_type)) {
1983 SAS_ADDR(dev->sas_addr), phy_id); 1996 struct domain_device *ata_dev = sas_ex_to_ata(dev, phy_id);
1997 char *action = "";
1998
1984 sas_ex_phy_discover(dev, phy_id); 1999 sas_ex_phy_discover(dev, phy_id);
1985 } else 2000
1986 res = sas_discover_new(dev, phy_id); 2001 if (ata_dev && phy->attached_dev_type == SATA_PENDING)
1987out: 2002 action = ", needs recovery";
1988 return res; 2003 SAS_DPRINTK("ex %016llx phy 0x%x broadcast flutter%s\n",
2004 SAS_ADDR(dev->sas_addr), phy_id, action);
2005 return res;
2006 }
2007
2008 return sas_discover_new(dev, phy_id);
1989} 2009}
1990 2010
1991/** 2011/**
diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h
index 7818c4673c3a..e028d7a44202 100644
--- a/drivers/scsi/libsas/sas_internal.h
+++ b/drivers/scsi/libsas/sas_internal.h
@@ -91,8 +91,9 @@ int sas_smp_get_phy_events(struct sas_phy *phy);
91void sas_device_set_phy(struct domain_device *dev, struct sas_port *port); 91void sas_device_set_phy(struct domain_device *dev, struct sas_port *port);
92struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy); 92struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy);
93struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id); 93struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id);
94int sas_get_phy_attached_sas_addr(struct domain_device *dev, int phy_id, 94int sas_ex_phy_discover(struct domain_device *dev, int single);
95 u8 *attached_sas_addr); 95int sas_get_report_phy_sata(struct domain_device *dev, int phy_id,
96 struct smp_resp *rps_resp);
96int sas_try_ata_reset(struct asd_sas_phy *phy); 97int sas_try_ata_reset(struct asd_sas_phy *phy);
97void sas_hae_reset(struct work_struct *work); 98void sas_hae_reset(struct work_struct *work);
98 99
@@ -122,6 +123,7 @@ static inline void sas_fill_in_rphy(struct domain_device *dev,
122 case SATA_DEV: 123 case SATA_DEV:
123 /* FIXME: need sata device type */ 124 /* FIXME: need sata device type */
124 case SAS_END_DEV: 125 case SAS_END_DEV:
126 case SATA_PENDING:
125 rphy->identify.device_type = SAS_END_DEVICE; 127 rphy->identify.device_type = SAS_END_DEVICE;
126 break; 128 break;
127 case EDGE_DEV: 129 case EDGE_DEV:
diff --git a/include/scsi/sas.h b/include/scsi/sas.h
index 3673d685e6ad..a577a833603d 100644
--- a/include/scsi/sas.h
+++ b/include/scsi/sas.h
@@ -89,8 +89,7 @@ enum sas_oob_mode {
89 SAS_OOB_MODE 89 SAS_OOB_MODE
90}; 90};
91 91
92/* See sas_discover.c if you plan on changing these. 92/* See sas_discover.c if you plan on changing these */
93 */
94enum sas_dev_type { 93enum sas_dev_type {
95 NO_DEVICE = 0, /* protocol */ 94 NO_DEVICE = 0, /* protocol */
96 SAS_END_DEV = 1, /* protocol */ 95 SAS_END_DEV = 1, /* protocol */
@@ -100,6 +99,7 @@ enum sas_dev_type {
100 SATA_DEV = 5, 99 SATA_DEV = 5,
101 SATA_PM = 7, 100 SATA_PM = 7,
102 SATA_PM_PORT= 8, 101 SATA_PM_PORT= 8,
102 SATA_PENDING = 9,
103}; 103};
104 104
105enum sas_protocol { 105enum sas_protocol {
diff --git a/include/scsi/sas_ata.h b/include/scsi/sas_ata.h
index cb724fd010f6..0ca2f8a6bc60 100644
--- a/include/scsi/sas_ata.h
+++ b/include/scsi/sas_ata.h
@@ -33,9 +33,10 @@
33static inline int dev_is_sata(struct domain_device *dev) 33static inline int dev_is_sata(struct domain_device *dev)
34{ 34{
35 return dev->dev_type == SATA_DEV || dev->dev_type == SATA_PM || 35 return dev->dev_type == SATA_DEV || dev->dev_type == SATA_PM ||
36 dev->dev_type == SATA_PM_PORT; 36 dev->dev_type == SATA_PM_PORT || dev->dev_type == SATA_PENDING;
37} 37}
38 38
39int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy);
39int sas_ata_init_host_and_port(struct domain_device *found_dev, 40int sas_ata_init_host_and_port(struct domain_device *found_dev,
40 struct scsi_target *starget); 41 struct scsi_target *starget);
41 42
@@ -82,6 +83,11 @@ static inline void sas_ata_schedule_reset(struct domain_device *dev)
82static inline void sas_ata_wait_eh(struct domain_device *dev) 83static inline void sas_ata_wait_eh(struct domain_device *dev)
83{ 84{
84} 85}
86
87static inline int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy)
88{
89 return 0;
90}
85#endif 91#endif
86 92
87#endif /* _SAS_ATA_H_ */ 93#endif /* _SAS_ATA_H_ */