aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libsas
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2008-03-08 11:49:24 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-03-08 11:49:24 -0500
commit9446389ef612096704fdf18fa79bab423d4110f0 (patch)
tree3e4fda7270be58ae176d20d318e61fb115b325b5 /drivers/scsi/libsas
parentcdd0972945dbcb8ea24db365d9b0e100af2a27bb (diff)
parent84c6f6046c5a2189160a8f0dca8b90427bf690ea (diff)
Merge commit 'origin' into devel
Diffstat (limited to 'drivers/scsi/libsas')
-rw-r--r--drivers/scsi/libsas/sas_ata.c39
-rw-r--r--drivers/scsi/libsas/sas_port.c11
-rw-r--r--drivers/scsi/libsas/sas_scsi_host.c34
3 files changed, 23 insertions, 61 deletions
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index 7cd05b599a12..b0e5ac372a32 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -236,12 +236,12 @@ static void sas_ata_phy_reset(struct ata_port *ap)
236 struct domain_device *dev = ap->private_data; 236 struct domain_device *dev = ap->private_data;
237 struct sas_internal *i = 237 struct sas_internal *i =
238 to_sas_internal(dev->port->ha->core.shost->transportt); 238 to_sas_internal(dev->port->ha->core.shost->transportt);
239 int res = 0; 239 int res = TMF_RESP_FUNC_FAILED;
240 240
241 if (i->dft->lldd_I_T_nexus_reset) 241 if (i->dft->lldd_I_T_nexus_reset)
242 res = i->dft->lldd_I_T_nexus_reset(dev); 242 res = i->dft->lldd_I_T_nexus_reset(dev);
243 243
244 if (res) 244 if (res != TMF_RESP_FUNC_COMPLETE)
245 SAS_DPRINTK("%s: Unable to reset I T nexus?\n", __FUNCTION__); 245 SAS_DPRINTK("%s: Unable to reset I T nexus?\n", __FUNCTION__);
246 246
247 switch (dev->sata_dev.command_set) { 247 switch (dev->sata_dev.command_set) {
@@ -656,21 +656,6 @@ out:
656 return res; 656 return res;
657} 657}
658 658
659static void sas_sata_propagate_sas_addr(struct domain_device *dev)
660{
661 unsigned long flags;
662 struct asd_sas_port *port = dev->port;
663 struct asd_sas_phy *phy;
664
665 BUG_ON(dev->parent);
666
667 memcpy(port->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE);
668 spin_lock_irqsave(&port->phy_list_lock, flags);
669 list_for_each_entry(phy, &port->phy_list, port_phy_el)
670 memcpy(phy->attached_sas_addr, dev->sas_addr, SAS_ADDR_SIZE);
671 spin_unlock_irqrestore(&port->phy_list_lock, flags);
672}
673
674#define ATA_IDENTIFY_DEV 0xEC 659#define ATA_IDENTIFY_DEV 0xEC
675#define ATA_IDENTIFY_PACKET_DEV 0xA1 660#define ATA_IDENTIFY_PACKET_DEV 0xA1
676#define ATA_SET_FEATURES 0xEF 661#define ATA_SET_FEATURES 0xEF
@@ -728,26 +713,6 @@ static int sas_discover_sata_dev(struct domain_device *dev)
728 goto out_err; 713 goto out_err;
729 } 714 }
730cont1: 715cont1:
731 /* Get WWN */
732 if (dev->port->oob_mode != SATA_OOB_MODE) {
733 memcpy(dev->sas_addr, dev->sata_dev.rps_resp.rps.stp_sas_addr,
734 SAS_ADDR_SIZE);
735 } else if (dev->sata_dev.command_set == ATA_COMMAND_SET &&
736 (le16_to_cpu(dev->sata_dev.identify_device[108]) & 0xF000)
737 == 0x5000) {
738 int i;
739
740 for (i = 0; i < 4; i++) {
741 dev->sas_addr[2*i] =
742 (le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0xFF00) >> 8;
743 dev->sas_addr[2*i+1] =
744 le16_to_cpu(dev->sata_dev.identify_device[108+i]) & 0x00FF;
745 }
746 }
747 sas_hash_addr(dev->hashed_sas_addr, dev->sas_addr);
748 if (!dev->parent)
749 sas_sata_propagate_sas_addr(dev);
750
751 /* XXX Hint: register this SATA device with SATL. 716 /* XXX Hint: register this SATA device with SATL.
752 When this returns, dev->sata_dev->lu is alive and 717 When this returns, dev->sata_dev->lu is alive and
753 present. 718 present.
diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c
index e1e2d085c920..39ae68a3b0ef 100644
--- a/drivers/scsi/libsas/sas_port.c
+++ b/drivers/scsi/libsas/sas_port.c
@@ -92,9 +92,6 @@ static void sas_form_port(struct asd_sas_phy *phy)
92 if (!port->phy) 92 if (!port->phy)
93 port->phy = phy->phy; 93 port->phy = phy->phy;
94 94
95 SAS_DPRINTK("phy%d added to port%d, phy_mask:0x%x\n", phy->id,
96 port->id, port->phy_mask);
97
98 if (*(u64 *)port->attached_sas_addr == 0) { 95 if (*(u64 *)port->attached_sas_addr == 0) {
99 port->class = phy->class; 96 port->class = phy->class;
100 memcpy(port->attached_sas_addr, phy->attached_sas_addr, 97 memcpy(port->attached_sas_addr, phy->attached_sas_addr,
@@ -115,6 +112,11 @@ static void sas_form_port(struct asd_sas_phy *phy)
115 } 112 }
116 sas_port_add_phy(port->port, phy->phy); 113 sas_port_add_phy(port->port, phy->phy);
117 114
115 SAS_DPRINTK("%s added to %s, phy_mask:0x%x (%16llx)\n",
116 phy->phy->dev.bus_id,port->port->dev.bus_id,
117 port->phy_mask,
118 SAS_ADDR(port->attached_sas_addr));
119
118 if (port->port_dev) 120 if (port->port_dev)
119 port->port_dev->pathways = port->num_phys; 121 port->port_dev->pathways = port->num_phys;
120 122
@@ -255,12 +257,11 @@ void sas_porte_hard_reset(struct work_struct *work)
255static void sas_init_port(struct asd_sas_port *port, 257static void sas_init_port(struct asd_sas_port *port,
256 struct sas_ha_struct *sas_ha, int i) 258 struct sas_ha_struct *sas_ha, int i)
257{ 259{
260 memset(port, 0, sizeof(*port));
258 port->id = i; 261 port->id = i;
259 INIT_LIST_HEAD(&port->dev_list); 262 INIT_LIST_HEAD(&port->dev_list);
260 spin_lock_init(&port->phy_list_lock); 263 spin_lock_init(&port->phy_list_lock);
261 INIT_LIST_HEAD(&port->phy_list); 264 INIT_LIST_HEAD(&port->phy_list);
262 port->num_phys = 0;
263 port->phy_mask = 0;
264 port->ha = sas_ha; 265 port->ha = sas_ha;
265 266
266 spin_lock_init(&port->dev_list_lock); 267 spin_lock_init(&port->dev_list_lock);
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index 704ea06a6e50..1f8241563c6c 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -434,7 +434,7 @@ static int sas_recover_I_T(struct domain_device *dev)
434} 434}
435 435
436/* Find the sas_phy that's attached to this device */ 436/* Find the sas_phy that's attached to this device */
437static struct sas_phy *find_local_sas_phy(struct domain_device *dev) 437struct sas_phy *sas_find_local_phy(struct domain_device *dev)
438{ 438{
439 struct domain_device *pdev = dev->parent; 439 struct domain_device *pdev = dev->parent;
440 struct ex_phy *exphy = NULL; 440 struct ex_phy *exphy = NULL;
@@ -456,6 +456,7 @@ static struct sas_phy *find_local_sas_phy(struct domain_device *dev)
456 BUG_ON(!exphy); 456 BUG_ON(!exphy);
457 return exphy->phy; 457 return exphy->phy;
458} 458}
459EXPORT_SYMBOL_GPL(sas_find_local_phy);
459 460
460/* Attempt to send a LUN reset message to a device */ 461/* Attempt to send a LUN reset message to a device */
461int sas_eh_device_reset_handler(struct scsi_cmnd *cmd) 462int sas_eh_device_reset_handler(struct scsi_cmnd *cmd)
@@ -482,7 +483,7 @@ int sas_eh_device_reset_handler(struct scsi_cmnd *cmd)
482int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd) 483int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd)
483{ 484{
484 struct domain_device *dev = cmd_to_domain_dev(cmd); 485 struct domain_device *dev = cmd_to_domain_dev(cmd);
485 struct sas_phy *phy = find_local_sas_phy(dev); 486 struct sas_phy *phy = sas_find_local_phy(dev);
486 int res; 487 int res;
487 488
488 res = sas_phy_reset(phy, 1); 489 res = sas_phy_reset(phy, 1);
@@ -497,10 +498,10 @@ int sas_eh_bus_reset_handler(struct scsi_cmnd *cmd)
497} 498}
498 499
499/* Try to reset a device */ 500/* Try to reset a device */
500static int try_to_reset_cmd_device(struct Scsi_Host *shost, 501static int try_to_reset_cmd_device(struct scsi_cmnd *cmd)
501 struct scsi_cmnd *cmd)
502{ 502{
503 int res; 503 int res;
504 struct Scsi_Host *shost = cmd->device->host;
504 505
505 if (!shost->hostt->eh_device_reset_handler) 506 if (!shost->hostt->eh_device_reset_handler)
506 goto try_bus_reset; 507 goto try_bus_reset;
@@ -540,6 +541,12 @@ Again:
540 need_reset = task->task_state_flags & SAS_TASK_NEED_DEV_RESET; 541 need_reset = task->task_state_flags & SAS_TASK_NEED_DEV_RESET;
541 spin_unlock_irqrestore(&task->task_state_lock, flags); 542 spin_unlock_irqrestore(&task->task_state_lock, flags);
542 543
544 if (need_reset) {
545 SAS_DPRINTK("%s: task 0x%p requests reset\n",
546 __FUNCTION__, task);
547 goto reset;
548 }
549
543 SAS_DPRINTK("trying to find task 0x%p\n", task); 550 SAS_DPRINTK("trying to find task 0x%p\n", task);
544 res = sas_scsi_find_task(task); 551 res = sas_scsi_find_task(task);
545 552
@@ -550,18 +557,15 @@ Again:
550 SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__, 557 SAS_DPRINTK("%s: task 0x%p is done\n", __FUNCTION__,
551 task); 558 task);
552 sas_eh_finish_cmd(cmd); 559 sas_eh_finish_cmd(cmd);
553 if (need_reset)
554 try_to_reset_cmd_device(shost, cmd);
555 continue; 560 continue;
556 case TASK_IS_ABORTED: 561 case TASK_IS_ABORTED:
557 SAS_DPRINTK("%s: task 0x%p is aborted\n", 562 SAS_DPRINTK("%s: task 0x%p is aborted\n",
558 __FUNCTION__, task); 563 __FUNCTION__, task);
559 sas_eh_finish_cmd(cmd); 564 sas_eh_finish_cmd(cmd);
560 if (need_reset)
561 try_to_reset_cmd_device(shost, cmd);
562 continue; 565 continue;
563 case TASK_IS_AT_LU: 566 case TASK_IS_AT_LU:
564 SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task); 567 SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task);
568 reset:
565 tmf_resp = sas_recover_lu(task->dev, cmd); 569 tmf_resp = sas_recover_lu(task->dev, cmd);
566 if (tmf_resp == TMF_RESP_FUNC_COMPLETE) { 570 if (tmf_resp == TMF_RESP_FUNC_COMPLETE) {
567 SAS_DPRINTK("dev %016llx LU %x is " 571 SAS_DPRINTK("dev %016llx LU %x is "
@@ -569,8 +573,6 @@ Again:
569 SAS_ADDR(task->dev), 573 SAS_ADDR(task->dev),
570 cmd->device->lun); 574 cmd->device->lun);
571 sas_eh_finish_cmd(cmd); 575 sas_eh_finish_cmd(cmd);
572 if (need_reset)
573 try_to_reset_cmd_device(shost, cmd);
574 sas_scsi_clear_queue_lu(work_q, cmd); 576 sas_scsi_clear_queue_lu(work_q, cmd);
575 goto Again; 577 goto Again;
576 } 578 }
@@ -581,15 +583,15 @@ Again:
581 task); 583 task);
582 tmf_resp = sas_recover_I_T(task->dev); 584 tmf_resp = sas_recover_I_T(task->dev);
583 if (tmf_resp == TMF_RESP_FUNC_COMPLETE) { 585 if (tmf_resp == TMF_RESP_FUNC_COMPLETE) {
586 struct domain_device *dev = task->dev;
584 SAS_DPRINTK("I_T %016llx recovered\n", 587 SAS_DPRINTK("I_T %016llx recovered\n",
585 SAS_ADDR(task->dev->sas_addr)); 588 SAS_ADDR(task->dev->sas_addr));
586 sas_eh_finish_cmd(cmd); 589 sas_eh_finish_cmd(cmd);
587 if (need_reset) 590 sas_scsi_clear_queue_I_T(work_q, dev);
588 try_to_reset_cmd_device(shost, cmd);
589 sas_scsi_clear_queue_I_T(work_q, task->dev);
590 goto Again; 591 goto Again;
591 } 592 }
592 /* Hammer time :-) */ 593 /* Hammer time :-) */
594 try_to_reset_cmd_device(cmd);
593 if (i->dft->lldd_clear_nexus_port) { 595 if (i->dft->lldd_clear_nexus_port) {
594 struct asd_sas_port *port = task->dev->port; 596 struct asd_sas_port *port = task->dev->port;
595 SAS_DPRINTK("clearing nexus for port:%d\n", 597 SAS_DPRINTK("clearing nexus for port:%d\n",
@@ -599,8 +601,6 @@ Again:
599 SAS_DPRINTK("clear nexus port:%d " 601 SAS_DPRINTK("clear nexus port:%d "
600 "succeeded\n", port->id); 602 "succeeded\n", port->id);
601 sas_eh_finish_cmd(cmd); 603 sas_eh_finish_cmd(cmd);
602 if (need_reset)
603 try_to_reset_cmd_device(shost, cmd);
604 sas_scsi_clear_queue_port(work_q, 604 sas_scsi_clear_queue_port(work_q,
605 port); 605 port);
606 goto Again; 606 goto Again;
@@ -613,8 +613,6 @@ Again:
613 SAS_DPRINTK("clear nexus ha " 613 SAS_DPRINTK("clear nexus ha "
614 "succeeded\n"); 614 "succeeded\n");
615 sas_eh_finish_cmd(cmd); 615 sas_eh_finish_cmd(cmd);
616 if (need_reset)
617 try_to_reset_cmd_device(shost, cmd);
618 goto clear_q; 616 goto clear_q;
619 } 617 }
620 } 618 }
@@ -628,8 +626,6 @@ Again:
628 cmd->device->lun); 626 cmd->device->lun);
629 627
630 sas_eh_finish_cmd(cmd); 628 sas_eh_finish_cmd(cmd);
631 if (need_reset)
632 try_to_reset_cmd_device(shost, cmd);
633 goto clear_q; 629 goto clear_q;
634 } 630 }
635 } 631 }