diff options
author | Dave Jiang <dave.jiang@intel.com> | 2011-05-04 21:22:33 -0400 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-07-03 07:04:46 -0400 |
commit | d7b90fc3436fa6d5b5251eec3128386af1a4d7b8 (patch) | |
tree | cfaf1edede969b86d1b88a396eba97bde2432123 /drivers/scsi/isci | |
parent | f700ad4331d55df729a36b2602c4abe2d855036f (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.h | 27 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_phy.h | 26 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_port.h | 4 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_phy.c | 28 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_phy.h | 9 | ||||
-rw-r--r-- | drivers/scsi/isci/core/scic_sds_port.c | 97 | ||||
-rw-r--r-- | drivers/scsi/isci/port.c | 6 |
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 | */ | ||
94 | struct 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 */ | ||
107 | struct 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 | ||
62 | struct scic_sds_port; | 63 | struct scic_sds_port; |
@@ -72,8 +73,7 @@ enum scic_port_not_ready_reason_code { | |||
72 | 73 | ||
73 | struct scic_port_end_point_properties { | 74 | struct 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 | ||
79 | struct scic_port_properties { | 79 | struct 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 | ||
445 | void scic_sds_phy_get_protocols( | 445 | void 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 | ||
455 | void 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 | ||
440 | void scic_sds_phy_get_protocols( | 441 | void 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 | |||
444 | void 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 | */ |
375 | static void scic_sds_port_get_protocols( | 374 | static void |
376 | struct scic_sds_port *sci_port, | 375 | scic_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 | */ | ||
437 | static 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 | ||