aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci
diff options
context:
space:
mode:
authorDave Jiang <dave.jiang@intel.com>2011-05-04 21:22:33 -0400
committerDan Williams <dan.j.williams@intel.com>2011-07-03 07:04:46 -0400
commitd7b90fc3436fa6d5b5251eec3128386af1a4d7b8 (patch)
treecfaf1edede969b86d1b88a396eba97bde2432123 /drivers/scsi/isci
parentf700ad4331d55df729a36b2602c4abe2d855036f (diff)
isci: fixup SAS iaf protocols data structure
Moved the actual data structure that's read from the phy register to phy header. Removed the parsing of identify address frame protocol bits as that seemed not necessary and we can use existing information. Signed-off-by: Dave Jiang <dave.jiang@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/scsi/isci')
-rw-r--r--drivers/scsi/isci/core/intel_sas.h27
-rw-r--r--drivers/scsi/isci/core/scic_phy.h26
-rw-r--r--drivers/scsi/isci/core/scic_port.h4
-rw-r--r--drivers/scsi/isci/core/scic_sds_phy.c28
-rw-r--r--drivers/scsi/isci/core/scic_sds_phy.h9
-rw-r--r--drivers/scsi/isci/core/scic_sds_port.c97
-rw-r--r--drivers/scsi/isci/port.c6
7 files changed, 59 insertions, 138 deletions
diff --git a/drivers/scsi/isci/core/intel_sas.h b/drivers/scsi/isci/core/intel_sas.h
index 58bf1fb9b2f5..f2d5ca1c72ed 100644
--- a/drivers/scsi/isci/core/intel_sas.h
+++ b/drivers/scsi/isci/core/intel_sas.h
@@ -85,33 +85,6 @@ struct sci_sas_address {
85}; 85};
86 86
87/** 87/**
88 * struct sci_sas_identify_address_frame_protocols - This structure depicts the
89 * contents of bytes 2 and 3 in the SAS IDENTIFY ADDRESS FRAME (IAF).
90 *
91 * For specific information on each of these individual fields please reference
92 * the SAS specification Link layer section on address frames.
93 */
94struct sci_sas_identify_address_frame_protocols {
95 union {
96 struct {
97 u16 restricted1:1;
98 u16 smp_initiator:1;
99 u16 stp_initiator:1;
100 u16 ssp_initiator:1;
101 u16 reserved3:4;
102 u16 restricted2:1;
103 u16 smp_target:1;
104 u16 stp_target:1;
105 u16 ssp_target:1;
106 u16 reserved4:4;
107 } bits;
108
109 u16 all;
110 } u;
111
112};
113
114/**
115 * enum _SCI_SAS_TASK_ATTRIBUTE - This enumeration depicts the SAM/SAS 88 * enum _SCI_SAS_TASK_ATTRIBUTE - This enumeration depicts the SAM/SAS
116 * specification defined task attribute values for a command information 89 * specification defined task attribute values for a command information
117 * unit. 90 * unit.
diff --git a/drivers/scsi/isci/core/scic_phy.h b/drivers/scsi/isci/core/scic_phy.h
index 3f43e8d69c4f..451d7977bf6d 100644
--- a/drivers/scsi/isci/core/scic_phy.h
+++ b/drivers/scsi/isci/core/scic_phy.h
@@ -103,6 +103,26 @@ struct scic_phy_cap {
103 }; 103 };
104} __packed; 104} __packed;
105 105
106/* this data structure reflects the link layer transmit identification reg */
107struct scic_phy_proto {
108 union {
109 struct {
110 u16 _r_a:1;
111 u16 smp_iport:1;
112 u16 stp_iport:1;
113 u16 ssp_iport:1;
114 u16 _r_b:4;
115 u16 _r_c:1;
116 u16 smp_tport:1;
117 u16 stp_tport:1;
118 u16 ssp_tport:1;
119 u16 _r_d:4;
120 };
121 u16 all;
122 };
123} __packed;
124
125
106/** 126/**
107 * struct scic_phy_properties - This structure defines the properties common to 127 * struct scic_phy_properties - This structure defines the properties common to
108 * all phys that can be retrieved. 128 * all phys that can be retrieved.
@@ -124,16 +144,10 @@ struct scic_phy_properties {
124 enum sas_linkrate negotiated_link_rate; 144 enum sas_linkrate negotiated_link_rate;
125 145
126 /** 146 /**
127 * This field indicates the protocols supported by the phy.
128 */
129 struct sci_sas_identify_address_frame_protocols protocols;
130
131 /**
132 * This field specifies the index of the phy in relation to other 147 * This field specifies the index of the phy in relation to other
133 * phys within the controller. This index is zero relative. 148 * phys within the controller. This index is zero relative.
134 */ 149 */
135 u8 index; 150 u8 index;
136
137}; 151};
138 152
139/** 153/**
diff --git a/drivers/scsi/isci/core/scic_port.h b/drivers/scsi/isci/core/scic_port.h
index 56d05073f9c5..4ae9b6cdf04f 100644
--- a/drivers/scsi/isci/core/scic_port.h
+++ b/drivers/scsi/isci/core/scic_port.h
@@ -57,6 +57,7 @@
57#define _SCIC_PORT_H_ 57#define _SCIC_PORT_H_
58 58
59#include "sci_status.h" 59#include "sci_status.h"
60#include "scic_phy.h"
60#include "intel_sas.h" 61#include "intel_sas.h"
61 62
62struct scic_sds_port; 63struct scic_sds_port;
@@ -72,8 +73,7 @@ enum scic_port_not_ready_reason_code {
72 73
73struct scic_port_end_point_properties { 74struct scic_port_end_point_properties {
74 struct sci_sas_address sas_address; 75 struct sci_sas_address sas_address;
75 struct sci_sas_identify_address_frame_protocols protocols; 76 struct scic_phy_proto protocols;
76
77}; 77};
78 78
79struct scic_port_properties { 79struct scic_port_properties {
diff --git a/drivers/scsi/isci/core/scic_sds_phy.c b/drivers/scsi/isci/core/scic_sds_phy.c
index 4afdb422ab98..b9d6fc7e8ae0 100644
--- a/drivers/scsi/isci/core/scic_sds_phy.c
+++ b/drivers/scsi/isci/core/scic_sds_phy.c
@@ -442,37 +442,15 @@ void scic_sds_phy_get_attached_sas_address(struct scic_sds_phy *sci_phy,
442 memcpy(sas_address, iaf->sas_addr, SAS_ADDR_SIZE); 442 memcpy(sas_address, iaf->sas_addr, SAS_ADDR_SIZE);
443} 443}
444 444
445void scic_sds_phy_get_protocols( 445void scic_sds_phy_get_protocols(struct scic_sds_phy *sci_phy,
446 struct scic_sds_phy *sci_phy, 446 struct scic_phy_proto *protocols)
447 struct sci_sas_identify_address_frame_protocols *protocols)
448{ 447{
449 protocols->u.all = 448 protocols->all =
450 (u16)(readl(&sci_phy-> 449 (u16)(readl(&sci_phy->
451 link_layer_registers->transmit_identification) & 450 link_layer_registers->transmit_identification) &
452 0x0000FFFF); 451 0x0000FFFF);
453} 452}
454 453
455void scic_sds_phy_get_attached_phy_protocols(
456 struct scic_sds_phy *sci_phy,
457 struct sci_sas_identify_address_frame_protocols *protocols)
458{
459 protocols->u.all = 0;
460
461 if (sci_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
462 struct isci_phy *iphy = sci_phy->iphy;
463 struct sas_identify_frame *iaf;
464
465 iaf = &iphy->frame_rcvd.iaf;
466 memcpy(&protocols->u.all, &iaf->initiator_bits, 2);
467 } else if (sci_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA)
468 protocols->u.bits.stp_target = 1;
469}
470
471/*
472 * *****************************************************************************
473 * * SCIC SDS PHY Handler Redirects
474 * ***************************************************************************** */
475
476/** 454/**
477 * This method will attempt to start the phy object. This request is only valid 455 * This method will attempt to start the phy object. This request is only valid
478 * when the phy is in the stopped state 456 * when the phy is in the stopped state
diff --git a/drivers/scsi/isci/core/scic_sds_phy.h b/drivers/scsi/isci/core/scic_sds_phy.h
index e91f28316c00..b0cebdc669eb 100644
--- a/drivers/scsi/isci/core/scic_sds_phy.h
+++ b/drivers/scsi/isci/core/scic_sds_phy.h
@@ -57,6 +57,7 @@
57#define _SCIC_SDS_PHY_H_ 57#define _SCIC_SDS_PHY_H_
58 58
59#include "intel_sas.h" 59#include "intel_sas.h"
60#include "scic_phy.h"
60#include "scu_registers.h" 61#include "scu_registers.h"
61#include "sci_base_state_machine.h" 62#include "sci_base_state_machine.h"
62#include <scsi/libsas.h> 63#include <scsi/libsas.h>
@@ -438,11 +439,7 @@ void scic_sds_phy_get_attached_sas_address(
438 struct sci_sas_address *sas_address); 439 struct sci_sas_address *sas_address);
439 440
440void scic_sds_phy_get_protocols( 441void scic_sds_phy_get_protocols(
441 struct scic_sds_phy *this_phy, 442 struct scic_sds_phy *sci_phy,
442 struct sci_sas_identify_address_frame_protocols *protocols); 443 struct scic_phy_proto *protocols);
443
444void scic_sds_phy_get_attached_phy_protocols(
445 struct scic_sds_phy *this_phy,
446 struct sci_sas_identify_address_frame_protocols *protocols);
447 444
448#endif /* _SCIC_SDS_PHY_H_ */ 445#endif /* _SCIC_SDS_PHY_H_ */
diff --git a/drivers/scsi/isci/core/scic_sds_port.c b/drivers/scsi/isci/core/scic_sds_port.c
index 3697211e7ca9..05bc3bff4f6f 100644
--- a/drivers/scsi/isci/core/scic_sds_port.c
+++ b/drivers/scsi/isci/core/scic_sds_port.c
@@ -53,6 +53,7 @@
53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */ 54 */
55 55
56#include "sas.h"
56#include "intel_sas.h" 57#include "intel_sas.h"
57#include "scic_controller.h" 58#include "scic_controller.h"
58#include "scic_phy.h" 59#include "scic_phy.h"
@@ -362,33 +363,32 @@ void scic_sds_port_get_sas_address(
362 } 363 }
363} 364}
364 365
365/** 366/*
366 * This method will indicate which protocols are supported by this port. 367 * This function will indicate which protocols are supported by this port.
367 * @sci_port: a handle corresponding to the SAS port for which to return the 368 * @sci_port: a handle corresponding to the SAS port for which to return the
368 * supported protocols. 369 * supported protocols.
369 * @protocols: This parameter specifies a pointer to an IAF protocol field 370 * @protocols: This parameter specifies a pointer to a data structure
370 * structure into which the core will copy the protocol values for the port. 371 * which the core will copy the protocol values for the port from the
371 * The values are returned as part of a bit mask in order to allow for 372 * transmit_identification register.
372 * multi-protocol support.
373 *
374 */ 373 */
375static void scic_sds_port_get_protocols( 374static void
376 struct scic_sds_port *sci_port, 375scic_sds_port_get_protocols(struct scic_sds_port *sci_port,
377 struct sci_sas_identify_address_frame_protocols *protocols) 376 struct scic_phy_proto *protocols)
378{ 377{
379 u8 index; 378 u8 index;
380 379
381 protocols->u.all = 0; 380 protocols->all = 0;
382 381
383 for (index = 0; index < SCI_MAX_PHYS; index++) { 382 for (index = 0; index < SCI_MAX_PHYS; index++) {
384 if (sci_port->phy_table[index] != NULL) { 383 if (sci_port->phy_table[index] != NULL) {
385 scic_sds_phy_get_protocols(sci_port->phy_table[index], protocols); 384 scic_sds_phy_get_protocols(sci_port->phy_table[index],
385 protocols);
386 } 386 }
387 } 387 }
388} 388}
389 389
390/** 390/*
391 * This method requests the SAS address for the device directly attached to 391 * This function requests the SAS address for the device directly attached to
392 * this SAS port. 392 * this SAS port.
393 * @sci_port: a handle corresponding to the SAS port for which to return the 393 * @sci_port: a handle corresponding to the SAS port for which to return the
394 * SAS address. 394 * SAS address.
@@ -401,21 +401,20 @@ void scic_sds_port_get_attached_sas_address(
401 struct scic_sds_port *sci_port, 401 struct scic_sds_port *sci_port,
402 struct sci_sas_address *sas_address) 402 struct sci_sas_address *sas_address)
403{ 403{
404 struct sci_sas_identify_address_frame_protocols protocols; 404 struct scic_sds_phy *sci_phy;
405 struct scic_sds_phy *phy;
406 405
407 /* 406 /*
408 * Ensure that the phy is both part of the port and currently 407 * Ensure that the phy is both part of the port and currently
409 * connected to the remote end-point. */ 408 * connected to the remote end-point.
410 phy = scic_sds_port_get_a_connected_phy(sci_port); 409 */
411 if (phy != NULL) { 410 sci_phy = scic_sds_port_get_a_connected_phy(sci_port);
412 scic_sds_phy_get_attached_phy_protocols(phy, &protocols); 411 if (sci_phy) {
413 412 if (sci_phy->protocol != SCIC_SDS_PHY_PROTOCOL_SATA) {
414 if (!protocols.u.bits.stp_target) { 413 scic_sds_phy_get_attached_sas_address(sci_phy,
415 scic_sds_phy_get_attached_sas_address(phy, sas_address); 414 sas_address);
416 } else { 415 } else {
417 scic_sds_phy_get_sas_address(phy, sas_address); 416 scic_sds_phy_get_sas_address(sci_phy, sas_address);
418 sas_address->low += phy->phy_index; 417 sas_address->low += sci_phy->phy_index;
419 } 418 }
420 } else { 419 } else {
421 sas_address->high = 0; 420 sas_address->high = 0;
@@ -424,33 +423,6 @@ void scic_sds_port_get_attached_sas_address(
424} 423}
425 424
426/** 425/**
427 * This method will indicate which protocols are supported by this remote
428 * device.
429 * @sci_port: a handle corresponding to the SAS port for which to return the
430 * supported protocols.
431 * @protocols: This parameter specifies a pointer to an IAF protocol field
432 * structure into which the core will copy the protocol values for the port.
433 * The values are returned as part of a bit mask in order to allow for
434 * multi-protocol support.
435 *
436 */
437static void scic_sds_port_get_attached_protocols(
438 struct scic_sds_port *sci_port,
439 struct sci_sas_identify_address_frame_protocols *protocols)
440{
441 struct scic_sds_phy *phy;
442
443 /*
444 * Ensure that the phy is both part of the port and currently
445 * connected to the remote end-point. */
446 phy = scic_sds_port_get_a_connected_phy(sci_port);
447 if (phy != NULL)
448 scic_sds_phy_get_attached_phy_protocols(phy, protocols);
449 else
450 protocols->u.all = 0;
451}
452
453/**
454 * scic_sds_port_construct_dummy_rnc() - create dummy rnc for si workaround 426 * scic_sds_port_construct_dummy_rnc() - create dummy rnc for si workaround
455 * 427 *
456 * @sci_port: logical port on which we need to create the remote node context 428 * @sci_port: logical port on which we need to create the remote node context
@@ -595,7 +567,6 @@ enum sci_status scic_port_get_properties(
595 scic_sds_port_get_sas_address(port, &prop->local.sas_address); 567 scic_sds_port_get_sas_address(port, &prop->local.sas_address);
596 scic_sds_port_get_protocols(port, &prop->local.protocols); 568 scic_sds_port_get_protocols(port, &prop->local.protocols);
597 scic_sds_port_get_attached_sas_address(port, &prop->remote.sas_address); 569 scic_sds_port_get_attached_sas_address(port, &prop->remote.sas_address);
598 scic_sds_port_get_attached_protocols(port, &prop->remote.protocols);
599 570
600 return SCI_SUCCESS; 571 return SCI_SUCCESS;
601} 572}
@@ -655,14 +626,10 @@ static void scic_sds_port_activate_phy(struct scic_sds_port *sci_port,
655 struct scic_sds_phy *sci_phy, 626 struct scic_sds_phy *sci_phy,
656 bool do_notify_user) 627 bool do_notify_user)
657{ 628{
658 struct scic_sds_controller *scic = scic_sds_port_get_controller(sci_port); 629 struct scic_sds_controller *scic = sci_port->owning_controller;
659 struct sci_sas_identify_address_frame_protocols protocols;
660 struct isci_host *ihost = scic->ihost; 630 struct isci_host *ihost = scic->ihost;
661 631
662 scic_sds_phy_get_attached_phy_protocols(sci_phy, &protocols); 632 if (sci_phy->protocol != SCIC_SDS_PHY_PROTOCOL_SATA)
663
664 /* If this is sata port then the phy has already been resumed */
665 if (!protocols.u.bits.stp_target)
666 scic_sds_phy_resume(sci_phy); 633 scic_sds_phy_resume(sci_phy);
667 634
668 sci_port->active_phy_mask |= 1 << sci_phy->phy_index; 635 sci_port->active_phy_mask |= 1 << sci_phy->phy_index;
@@ -803,15 +770,9 @@ bool scic_sds_port_link_detected(
803 struct scic_sds_port *sci_port, 770 struct scic_sds_port *sci_port,
804 struct scic_sds_phy *sci_phy) 771 struct scic_sds_phy *sci_phy)
805{ 772{
806 struct sci_sas_identify_address_frame_protocols protocols; 773 if ((sci_port->logical_port_index != SCIC_SDS_DUMMY_PORT) &&
807 774 (sci_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA) &&
808 scic_sds_phy_get_attached_phy_protocols(sci_phy, &protocols); 775 scic_sds_port_is_wide(sci_port)) {
809
810 if (
811 (sci_port->logical_port_index != SCIC_SDS_DUMMY_PORT)
812 && (protocols.u.bits.stp_target)
813 && scic_sds_port_is_wide(sci_port)
814 ) {
815 scic_sds_port_invalid_link_up(sci_port, sci_phy); 776 scic_sds_port_invalid_link_up(sci_port, sci_phy);
816 777
817 return false; 778 return false;
diff --git a/drivers/scsi/isci/port.c b/drivers/scsi/isci/port.c
index 96a2002dadea..2decafbeb968 100644
--- a/drivers/scsi/isci/port.c
+++ b/drivers/scsi/isci/port.c
@@ -187,7 +187,7 @@ void isci_port_link_up(
187 187
188 scic_port_get_properties(port, &properties); 188 scic_port_get_properties(port, &properties);
189 189
190 if (properties.remote.protocols.u.bits.stp_target) { 190 if (phy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA) {
191 u64 attached_sas_address; 191 u64 attached_sas_address;
192 192
193 isci_phy->sas_phy.oob_mode = SATA_OOB_MODE; 193 isci_phy->sas_phy.oob_mode = SATA_OOB_MODE;
@@ -207,9 +207,7 @@ void isci_port_link_up(
207 207
208 memcpy(&isci_phy->sas_phy.attached_sas_addr, 208 memcpy(&isci_phy->sas_phy.attached_sas_addr,
209 &attached_sas_address, sizeof(attached_sas_address)); 209 &attached_sas_address, sizeof(attached_sas_address));
210 210 } else if (phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
211 } else if (properties.remote.protocols.u.bits.ssp_target ||
212 properties.remote.protocols.u.bits.smp_target) {
213 isci_phy->sas_phy.oob_mode = SAS_OOB_MODE; 211 isci_phy->sas_phy.oob_mode = SAS_OOB_MODE;
214 isci_phy->sas_phy.frame_rcvd_size = sizeof(struct sas_identify_frame); 212 isci_phy->sas_phy.frame_rcvd_size = sizeof(struct sas_identify_frame);
215 213