1/* 2 * SAS Transport Layer for MPT (Message Passing Technology) based controllers 3 * 4 * This code is based on drivers/scsi/mpt2sas/mpt2_transport.c 5 * Copyright (C) 2007-2010 LSI Corporation 6 * (mailto:DL-MPTFusionLinux@lsi.com) 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License 10 * as published by the Free Software Foundation; either version 2 11 * of the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * NO WARRANTY 19 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR 20 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT 21 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, 22 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is 23 * solely responsible for determining the appropriateness of using and 24 * distributing the Program and assumes all risks associated with its 25 * exercise of rights under this Agreement, including but not limited to 26 * the risks and costs of program errors, damage to or loss of data, 27 * programs or equipment, and unavailability or interruption of operations. 28 29 * DISCLAIMER OF LIABILITY 30 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY 31 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND 33 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 34 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 35 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED 36 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES 37 38 * You should have received a copy of the GNU General Public License 39 * along with this program; if not, write to the Free Software 40 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 41 * USA. 42 */ 43 44#include <linux/module.h> 45#include <linux/kernel.h> 46#include <linux/init.h> 47#include <linux/errno.h> 48#include <linux/sched.h> 49#include <linux/workqueue.h> 50#include <linux/delay.h> 51#include <linux/pci.h> 52#include <linux/slab.h> 53 54#include <scsi/scsi.h> 55#include <scsi/scsi_cmnd.h> 56#include <scsi/scsi_device.h> 57#include <scsi/scsi_host.h> 58#include <scsi/scsi_transport_sas.h> 59#include <scsi/scsi_dbg.h> 60 61#include "mpt2sas_base.h" 62/** 63 * _transport_sas_node_find_by_sas_address - sas node search 64 * @ioc: per adapter object 65 * @sas_address: sas address of expander or sas host 66 * Context: Calling function should acquire ioc->sas_node_lock. 67 * 68 * Search for either hba phys or expander device based on handle, then returns 69 * the sas_node object. 70 */ 71static struct _sas_node * 72_transport_sas_node_find_by_sas_address(struct MPT2SAS_ADAPTER *ioc, 73 u64 sas_address) 74{ 75 if (ioc->sas_hba.sas_address == sas_address) 76 return &ioc->sas_hba; 77 else 78 return mpt2sas_scsih_expander_find_by_sas_address(ioc, 79 sas_address); 80} 81 82/** 83 * _transport_convert_phy_link_rate - 84 * @link_rate: link rate returned from mpt firmware 85 * 86 * Convert link_rate from mpi fusion into sas_transport form. 87 */ 88static enum sas_linkrate 89_transport_convert_phy_link_rate(u8 link_rate) 90{ 91 enum sas_linkrate rc; 92 93 switch (link_rate) { 94 case MPI2_SAS_NEG_LINK_RATE_1_5: 95 rc = SAS_LINK_RATE_1_5_GBPS; 96 break; 97 case MPI2_SAS_NEG_LINK_RATE_3_0: 98 rc = SAS_LINK_RATE_3_0_GBPS; 99 break; 100 case MPI2_SAS_NEG_LINK_RATE_6_0: 101 rc = SAS_LINK_RATE_6_0_GBPS; 102 break; 103 case MPI2_SAS_NEG_LINK_RATE_PHY_DISABLED: 104 rc = SAS_PHY_DISABLED; 105 break; 106 case MPI2_SAS_NEG_LINK_RATE_NEGOTIATION_FAILED: 107 rc = SAS_LINK_RATE_FAILED; 108 break; 109 case MPI2_SAS_NEG_LINK_RATE_PORT_SELECTOR: 110 rc = SAS_SATA_PORT_SELECTOR; 111 break; 112 case MPI2_SAS_NEG_LINK_RATE_SMP_RESET_IN_PROGRESS: 113 rc = SAS_PHY_RESET_IN_PROGRESS; 114 break; 115 default: 116 case MPI2_SAS_NEG_LINK_RATE_SATA_OOB_COMPLETE: 117 case MPI2_SAS_NEG_LINK_RATE_UNKNOWN_LINK_RATE: 118 rc = SAS_LINK_RATE_UNKNOWN; 119 break; 120 } 121 return rc; 122} 123 124/** 125 * _transport_set_identify - set identify for phys and end devices 126 * @ioc: per adapter object 127 * @handle: device handle 128 * @identify: sas identify info 129 * 130 * Populates sas identify info. 131 * 132 * Returns 0 for success, non-zero for failure. 133 */ 134static int 135_transport_set_identify(struct MPT2SAS_ADAPTER *ioc, u16 handle, 136 struct sas_identify *identify) 137{ 138 Mpi2SasDevicePage0_t sas_device_pg0; 139 Mpi2ConfigReply_t mpi_reply; 140 u32 device_info; 141 u32 ioc_status; 142 143 if (ioc->shost_recovery || ioc->pci_error_recovery) { 144 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", 145 __func__, ioc->name); 146 return -EFAULT; 147 } 148 149 if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, 150 MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { 151 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 152 153 ioc->name, __FILE__, __LINE__, __func__); 154 return -ENXIO; 155 } 156 157 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 158 MPI2_IOCSTATUS_MASK; 159 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 160 printk(MPT2SAS_ERR_FMT "handle(0x%04x), ioc_status(0x%04x)" 161 "\nfailure at %s:%d/%s()!\n", ioc->name, handle, ioc_status, 162 __FILE__, __LINE__, __func__); 163 return -EIO; 164 } 165 166 memset(identify, 0, sizeof(*identify)); 167 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo); 168 169 /* sas_address */ 170 identify->sas_address = le64_to_cpu(sas_device_pg0.SASAddress); 171 172 /* device_type */ 173 switch (device_info & MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) { 174 case MPI2_SAS_DEVICE_INFO_NO_DEVICE: 175 identify->device_type = SAS_PHY_UNUSED; 176 break; 177 case MPI2_SAS_DEVICE_INFO_END_DEVICE: 178 identify->device_type = SAS_END_DEVICE; 179 break; 180 case MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER: 181 identify->device_type = SAS_EDGE_EXPANDER_DEVICE; 182 break; 183 case MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER: 184 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE; 185 break; 186 } 187 188 /* initiator_port_protocols */ 189 if (device_info & MPI2_SAS_DEVICE_INFO_SSP_INITIATOR) 190 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP; 191 if (device_info & MPI2_SAS_DEVICE_INFO_STP_INITIATOR) 192 identify->initiator_port_protocols |= SAS_PROTOCOL_STP; 193 if (device_info & MPI2_SAS_DEVICE_INFO_SMP_INITIATOR) 194 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP; 195 if (device_info & MPI2_SAS_DEVICE_INFO_SATA_HOST) 196 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA; 197 198 /* target_port_protocols */ 199 if (device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET) 200 identify->target_port_protocols |= SAS_PROTOCOL_SSP; 201 if (device_info & MPI2_SAS_DEVICE_INFO_STP_TARGET) 202 identify->target_port_protocols |= SAS_PROTOCOL_STP; 203 if (device_info & MPI2_SAS_DEVICE_INFO_SMP_TARGET) 204 identify->target_port_protocols |= SAS_PROTOCOL_SMP; 205 if (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) 206 identify->target_port_protocols |= SAS_PROTOCOL_SATA; 207 208 return 0; 209} 210 211/** 212 * mpt2sas_transport_done - internal transport layer callback handler. 213 * @ioc: per adapter object 214 * @smid: system request message index 215 * @msix_index: MSIX table index supplied by the OS 216 * @reply: reply message frame(lower 32bit addr) 217 * 218 * Callback handler when sending internal generated transport cmds. 219 * The callback index passed is `ioc->transport_cb_idx` 220 * 221 * Return 1 meaning mf should be freed from _base_interrupt 222 * 0 means the mf is freed from this function. 223 */ 224u8 225mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, 226 u32 reply) 227{ 228 MPI2DefaultReply_t *mpi_reply; 229 230 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); 231 if (ioc->transport_cmds.status == MPT2_CMD_NOT_USED) 232 return 1; 233 if (ioc->transport_cmds.smid != smid) 234 return 1; 235 ioc->transport_cmds.status |= MPT2_CMD_COMPLETE; 236 if (mpi_reply) { 237 memcpy(ioc->transport_cmds.reply, mpi_reply, 238 mpi_reply->MsgLength*4); 239 ioc->transport_cmds.status |= MPT2_CMD_REPLY_VALID; 240 } 241 ioc->transport_cmds.status &= ~MPT2_CMD_PENDING; 242 complete(&ioc->transport_cmds.done); 243 return 1; 244} 245 246/* report manufacture request structure */ 247struct rep_manu_request{ 248 u8 smp_frame_type; 249 u8 function; 250 u8 reserved; 251 u8 request_length; 252}; 253 254/* report manufacture reply structure */ 255struct rep_manu_reply{ 256 u8 smp_frame_type; /* 0x41 */ 257 u8 function; /* 0x01 */ 258 u8 function_result; 259 u8 response_length; 260 u16 expander_change_count; 261 u8 reserved0[2]; 262 u8 sas_format; 263 u8 reserved2[3]; 264 u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN]; 265 u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN]; 266 u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN]; 267 u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN]; 268 u16 component_id; 269 u8 component_revision_id; 270 u8 reserved3; 271 u8 vendor_specific[8]; 272}; 273 274/** 275 * _transport_expander_report_manufacture - obtain SMP report_manufacture 276 * @ioc: per adapter object 277 * @sas_address: expander sas address 278 * @edev: the sas_expander_device object 279 * 280 * Fills in the sas_expander_device object when SMP port is created. 281 * 282 * Returns 0 for success, non-zero for failure. 283 */ 284static int 285_transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc, 286 u64 sas_address, struct sas_expander_device *edev) 287{ 288 Mpi2SmpPassthroughRequest_t *mpi_request; 289 Mpi2SmpPassthroughReply_t *mpi_reply; 290 struct rep_manu_reply *manufacture_reply; 291 struct rep_manu_request *manufacture_request; 292 int rc; 293 u16 smid; 294 u32 ioc_state; 295 unsigned long timeleft; 296 void *psge; 297 u32 sgl_flags; 298 u8 issue_reset = 0; 299 void *data_out = NULL; 300 dma_addr_t data_out_dma; 301 u32 sz; 302 u16 wait_state_count; 303 304 if (ioc->shost_recovery || ioc->pci_error_recovery) { 305 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", 306 __func__, ioc->name); 307 return -EFAULT; 308 } 309 310 mutex_lock(&ioc->transport_cmds.mutex); 311 312 if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) { 313 printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n", 314 ioc->name, __func__); 315 rc = -EAGAIN; 316 goto out; 317 } 318 ioc->transport_cmds.status = MPT2_CMD_PENDING; 319 320 wait_state_count = 0; 321 ioc_state = mpt2sas_base_get_iocstate(ioc, 1); 322 while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { 323 if (wait_state_count++ == 10) { 324 printk(MPT2SAS_ERR_FMT 325 "%s: failed due to ioc not operational\n", 326 ioc->name, __func__); 327 rc = -EFAULT; 328 goto out; 329 } 330 ssleep(1); 331 ioc_state = mpt2sas_base_get_iocstate(ioc, 1); 332 printk(MPT2SAS_INFO_FMT "%s: waiting for " 333 "operational state(count=%d)\n", ioc->name, 334 __func__, wait_state_count); 335 } 336 if (wait_state_count) 337 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n", 338 ioc->name, __func__); 339 340 smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx); 341 if (!smid) { 342 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 343 ioc->name, __func__); 344 rc = -EAGAIN; 345 goto out; 346 } 347 348 rc = 0; 349 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); 350 ioc->transport_cmds.smid = smid; 351 352 sz = sizeof(struct rep_manu_request) + sizeof(struct rep_manu_reply); 353 data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma); 354 355 if (!data_out) { 356 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, 357 __LINE__, __func__); 358 rc = -ENOMEM; 359 mpt2sas_base_free_smid(ioc, smid); 360 goto out; 361 } 362 363 manufacture_request = data_out; 364 manufacture_request->smp_frame_type = 0x40; 365 manufacture_request->function = 1; 366 manufacture_request->reserved = 0; 367 manufacture_request->request_length = 0; 368 369 memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); 370 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; 371 mpi_request->PhysicalPort = 0xFF; 372 mpi_request->VF_ID = 0; /* TODO */ 373 mpi_request->VP_ID = 0; 374 mpi_request->SASAddress = cpu_to_le64(sas_address); 375 mpi_request->RequestDataLength = 376 cpu_to_le16(sizeof(struct rep_manu_request)); 377 psge = &mpi_request->SGL; 378 379 /* WRITE sgel first */ 380 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 381 MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC); 382 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; 383 ioc->base_add_sg_single(psge, sgl_flags | 384 sizeof(struct rep_manu_request), data_out_dma); 385 386 /* incr sgel */ 387 psge += ioc->sge_size; 388 389 /* READ sgel last */ 390 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 391 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | 392 MPI2_SGE_FLAGS_END_OF_LIST); 393 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; 394 ioc->base_add_sg_single(psge, sgl_flags | 395 sizeof(struct rep_manu_reply), data_out_dma + 396 sizeof(struct rep_manu_request)); 397 398 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "report_manufacture - " 399 "send to sas_addr(0x%016llx)\n", ioc->name, 400 (unsigned long long)sas_address)); 401 init_completion(&ioc->transport_cmds.done); 402 mpt2sas_base_put_smid_default(ioc, smid); 403 timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done, 404 10*HZ); 405 406 if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) { 407 printk(MPT2SAS_ERR_FMT "%s: timeout\n", 408 ioc->name, __func__); 409 _debug_dump_mf(mpi_request, 410 sizeof(Mpi2SmpPassthroughRequest_t)/4); 411 if (!(ioc->transport_cmds.status & MPT2_CMD_RESET)) 412 issue_reset = 1; 413 goto issue_host_reset; 414 } 415 416 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "report_manufacture - " 417 "complete\n", ioc->name)); 418 419 if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) { 420 u8 *tmp; 421 422 mpi_reply = ioc->transport_cmds.reply; 423 424 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT 425 "report_manufacture - reply data transfer size(%d)\n", 426 ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength))); 427 428 if (le16_to_cpu(mpi_reply->ResponseDataLength) != 429 sizeof(struct rep_manu_reply)) 430 goto out; 431 432 manufacture_reply = data_out + sizeof(struct rep_manu_request); 433 strncpy(edev->vendor_id, manufacture_reply->vendor_id, 434 SAS_EXPANDER_VENDOR_ID_LEN); 435 strncpy(edev->product_id, manufacture_reply->product_id, 436 SAS_EXPANDER_PRODUCT_ID_LEN); 437 strncpy(edev->product_rev, manufacture_reply->product_rev, 438 SAS_EXPANDER_PRODUCT_REV_LEN); 439 edev->level = manufacture_reply->sas_format & 1; 440 if (edev->level) { 441 strncpy(edev->component_vendor_id, 442 manufacture_reply->component_vendor_id, 443 SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN); 444 tmp = (u8 *)&manufacture_reply->component_id; 445 edev->component_id = tmp[0] << 8 | tmp[1]; 446 edev->component_revision_id = 447 manufacture_reply->component_revision_id; 448 } 449 } else 450 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT 451 "report_manufacture - no reply\n", ioc->name)); 452 453 issue_host_reset: 454 if (issue_reset) 455 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, 456 FORCE_BIG_HAMMER); 457 out: 458 ioc->transport_cmds.status = MPT2_CMD_NOT_USED; 459 if (data_out) 460 pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma); 461 462 mutex_unlock(&ioc->transport_cmds.mutex); 463 return rc; 464} 465 466/** 467 * _transport_delete_port - helper function to removing a port 468 * @ioc: per adapter object 469 * @mpt2sas_port: mpt2sas per port object 470 * 471 * Returns nothing. 472 */ 473static void 474_transport_delete_port(struct MPT2SAS_ADAPTER *ioc, 475 struct _sas_port *mpt2sas_port) 476{ 477 u64 sas_address = mpt2sas_port->remote_identify.sas_address; 478 enum sas_device_type device_type = 479 mpt2sas_port->remote_identify.device_type; 480 481 dev_printk(KERN_INFO, &mpt2sas_port->port->dev, 482 "remove: sas_addr(0x%016llx)\n", 483 (unsigned long long) sas_address); 484 485 ioc->logging_level |= MPT_DEBUG_TRANSPORT; 486 if (device_type == SAS_END_DEVICE) 487 mpt2sas_device_remove(ioc, sas_address); 488 else if (device_type == SAS_EDGE_EXPANDER_DEVICE || 489 device_type == SAS_FANOUT_EXPANDER_DEVICE) 490 mpt2sas_expander_remove(ioc, sas_address); 491 ioc->logging_level &= ~MPT_DEBUG_TRANSPORT; 492} 493 494/** 495 * _transport_delete_phy - helper function to removing single phy from port 496 * @ioc: per adapter object 497 * @mpt2sas_port: mpt2sas per port object 498 * @mpt2sas_phy: mpt2sas per phy object 499 * 500 * Returns nothing. 501 */ 502static void 503_transport_delete_phy(struct MPT2SAS_ADAPTER *ioc, 504 struct _sas_port *mpt2sas_port, struct _sas_phy *mpt2sas_phy) 505{ 506 u64 sas_address = mpt2sas_port->remote_identify.sas_address; 507 508 dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev, 509 "remove: sas_addr(0x%016llx), phy(%d)\n", 510 (unsigned long long) sas_address, mpt2sas_phy->phy_id); 511 512 list_del(&mpt2sas_phy->port_siblings); 513 mpt2sas_port->num_phys--; 514 sas_port_delete_phy(mpt2sas_port->port, mpt2sas_phy->phy); 515 mpt2sas_phy->phy_belongs_to_port = 0; 516} 517 518/** 519 * _transport_add_phy - helper function to adding single phy to port 520 * @ioc: per adapter object 521 * @mpt2sas_port: mpt2sas per port object 522 * @mpt2sas_phy: mpt2sas per phy object 523 * 524 * Returns nothing. 525 */ 526static void 527_transport_add_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_port *mpt2sas_port, 528 struct _sas_phy *mpt2sas_phy) 529{ 530 u64 sas_address = mpt2sas_port->remote_identify.sas_address; 531 532 dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev, 533 "add: sas_addr(0x%016llx), phy(%d)\n", (unsigned long long) 534 sas_address, mpt2sas_phy->phy_id); 535 536 list_add_tail(&mpt2sas_phy->port_siblings, &mpt2sas_port->phy_list); 537 mpt2sas_port->num_phys++; 538 sas_port_add_phy(mpt2sas_port->port, mpt2sas_phy->phy); 539 mpt2sas_phy->phy_belongs_to_port = 1; 540} 541 542/** 543 * _transport_add_phy_to_an_existing_port - adding new phy to existing port 544 * @ioc: per adapter object 545 * @sas_node: sas node object (either expander or sas host) 546 * @mpt2sas_phy: mpt2sas per phy object 547 * @sas_address: sas address of device/expander were phy needs to be added to 548 * 549 * Returns nothing. 550 */ 551static void 552_transport_add_phy_to_an_existing_port(struct MPT2SAS_ADAPTER *ioc, 553struct _sas_node *sas_node, struct _sas_phy *mpt2sas_phy, u64 sas_address) 554{ 555 struct _sas_port *mpt2sas_port; 556 struct _sas_phy *phy_srch; 557 558 if (mpt2sas_phy->phy_belongs_to_port == 1) 559 return; 560 561 list_for_each_entry(mpt2sas_port, &sas_node->sas_port_list, 562 port_list) { 563 if (mpt2sas_port->remote_identify.sas_address != 564 sas_address) 565 continue; 566 list_for_each_entry(phy_srch, &mpt2sas_port->phy_list, 567 port_siblings) { 568 if (phy_srch == mpt2sas_phy) 569 return; 570 } 571 _transport_add_phy(ioc, mpt2sas_port, mpt2sas_phy); 572 return; 573 } 574 575} 576 577/** 578 * _transport_del_phy_from_an_existing_port - delete phy from existing port 579 * @ioc: per adapter object 580 * @sas_node: sas node object (either expander or sas host) 581 * @mpt2sas_phy: mpt2sas per phy object 582 * 583 * Returns nothing. 584 */ 585static void 586_transport_del_phy_from_an_existing_port(struct MPT2SAS_ADAPTER *ioc, 587 struct _sas_node *sas_node, struct _sas_phy *mpt2sas_phy) 588{ 589 struct _sas_port *mpt2sas_port, *next; 590 struct _sas_phy *phy_srch; 591 592 if (mpt2sas_phy->phy_belongs_to_port == 0) 593 return; 594 595 list_for_each_entry_safe(mpt2sas_port, next, &sas_node->sas_port_list, 596 port_list) { 597 list_for_each_entry(phy_srch, &mpt2sas_port->phy_list, 598 port_siblings) { 599 if (phy_srch != mpt2sas_phy) 600 continue; 601 if (mpt2sas_port->num_phys == 1) 602 _transport_delete_port(ioc, mpt2sas_port); 603 else 604 _transport_delete_phy(ioc, mpt2sas_port, 605 mpt2sas_phy); 606 return; 607 } 608 } 609} 610 611/** 612 * _transport_sanity_check - sanity check when adding a new port 613 * @ioc: per adapter object 614 * @sas_node: sas node object (either expander or sas host) 615 * @sas_address: sas address of device being added 616 * 617 * See the explanation above from _transport_delete_duplicate_port 618 */ 619static void 620_transport_sanity_check(struct MPT2SAS_ADAPTER *ioc, struct _sas_node *sas_node, 621 u64 sas_address) 622{ 623 int i; 624 625 for (i = 0; i < sas_node->num_phys; i++) { 626 if (sas_node->phy[i].remote_identify.sas_address != sas_address) 627 continue; 628 if (sas_node->phy[i].phy_belongs_to_port == 1) 629 _transport_del_phy_from_an_existing_port(ioc, sas_node, 630 &sas_node->phy[i]); 631 } 632} 633 634/** 635 * mpt2sas_transport_port_add - insert port to the list 636 * @ioc: per adapter object 637 * @handle: handle of attached device 638 * @sas_address: sas address of parent expander or sas host 639 * Context: This function will acquire ioc->sas_node_lock. 640 * 641 * Adding new port object to the sas_node->sas_port_list. 642 * 643 * Returns mpt2sas_port. 644 */ 645struct _sas_port * 646mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle, 647 u64 sas_address) 648{ 649 struct _sas_phy *mpt2sas_phy, *next; 650 struct _sas_port *mpt2sas_port; 651 unsigned long flags; 652 struct _sas_node *sas_node; 653 struct sas_rphy *rphy; 654 int i; 655 struct sas_port *port; 656 657 mpt2sas_port = kzalloc(sizeof(struct _sas_port), 658 GFP_KERNEL); 659 if (!mpt2sas_port) { 660 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 661 ioc->name, __FILE__, __LINE__, __func__); 662 return NULL; 663 } 664 665 INIT_LIST_HEAD(&mpt2sas_port->port_list); 666 INIT_LIST_HEAD(&mpt2sas_port->phy_list); 667 spin_lock_irqsave(&ioc->sas_node_lock, flags); 668 sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address); 669 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 670 671 if (!sas_node) { 672 printk(MPT2SAS_ERR_FMT "%s: Could not find " 673 "parent sas_address(0x%016llx)!\n", ioc->name, 674 __func__, (unsigned long long)sas_address); 675 goto out_fail; 676 } 677 678 if ((_transport_set_identify(ioc, handle, 679 &mpt2sas_port->remote_identify))) { 680 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 681 ioc->name, __FILE__, __LINE__, __func__); 682 goto out_fail; 683 } 684 685 if (mpt2sas_port->remote_identify.device_type == SAS_PHY_UNUSED) { 686 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 687 ioc->name, __FILE__, __LINE__, __func__); 688 goto out_fail; 689 } 690 691 _transport_sanity_check(ioc, sas_node, 692 mpt2sas_port->remote_identify.sas_address); 693 694 for (i = 0; i < sas_node->num_phys; i++) { 695 if (sas_node->phy[i].remote_identify.sas_address != 696 mpt2sas_port->remote_identify.sas_address) 697 continue; 698 list_add_tail(&sas_node->phy[i].port_siblings, 699 &mpt2sas_port->phy_list); 700 mpt2sas_port->num_phys++; 701 } 702 703 if (!mpt2sas_port->num_phys) { 704 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 705 ioc->name, __FILE__, __LINE__, __func__); 706 goto out_fail; 707 } 708 709 port = sas_port_alloc_num(sas_node->parent_dev); 710 if ((sas_port_add(port))) { 711 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 712 ioc->name, __FILE__, __LINE__, __func__); 713 goto out_fail; 714 } 715 716 list_for_each_entry(mpt2sas_phy, &mpt2sas_port->phy_list, 717 port_siblings) { 718 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) 719 dev_printk(KERN_INFO, &port->dev, "add: handle(0x%04x)" 720 ", sas_addr(0x%016llx), phy(%d)\n", handle, 721 (unsigned long long) 722 mpt2sas_port->remote_identify.sas_address, 723 mpt2sas_phy->phy_id); 724 sas_port_add_phy(port, mpt2sas_phy->phy); 725 mpt2sas_phy->phy_belongs_to_port = 1; 726 } 727 728 mpt2sas_port->port = port; 729 if (mpt2sas_port->remote_identify.device_type == SAS_END_DEVICE) 730 rphy = sas_end_device_alloc(port); 731 else 732 rphy = sas_expander_alloc(port, 733 mpt2sas_port->remote_identify.device_type); 734 735 rphy->identify = mpt2sas_port->remote_identify; 736 if ((sas_rphy_add(rphy))) { 737 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 738 ioc->name, __FILE__, __LINE__, __func__); 739 } 740 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) 741 dev_printk(KERN_INFO, &rphy->dev, "add: handle(0x%04x), " 742 "sas_addr(0x%016llx)\n", handle, 743 (unsigned long long) 744 mpt2sas_port->remote_identify.sas_address); 745 mpt2sas_port->rphy = rphy; 746 spin_lock_irqsave(&ioc->sas_node_lock, flags); 747 list_add_tail(&mpt2sas_port->port_list, &sas_node->sas_port_list); 748 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 749 750 /* fill in report manufacture */ 751 if (mpt2sas_port->remote_identify.device_type == 752 MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER || 753 mpt2sas_port->remote_identify.device_type == 754 MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER) 755 _transport_expander_report_manufacture(ioc, 756 mpt2sas_port->remote_identify.sas_address, 757 rphy_to_expander_device(rphy)); 758 759 return mpt2sas_port; 760 761 out_fail: 762 list_for_each_entry_safe(mpt2sas_phy, next, &mpt2sas_port->phy_list, 763 port_siblings) 764 list_del(&mpt2sas_phy->port_siblings); 765 kfree(mpt2sas_port); 766 return NULL; 767} 768 769/** 770 * mpt2sas_transport_port_remove - remove port from the list 771 * @ioc: per adapter object 772 * @sas_address: sas address of attached device 773 * @sas_address_parent: sas address of parent expander or sas host 774 * Context: This function will acquire ioc->sas_node_lock. 775 * 776 * Removing object and freeing associated memory from the 777 * ioc->sas_port_list. 778 * 779 * Return nothing. 780 */ 781void 782mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, 783 u64 sas_address_parent) 784{ 785 int i; 786 unsigned long flags; 787 struct _sas_port *mpt2sas_port, *next; 788 struct _sas_node *sas_node; 789 u8 found = 0; 790 struct _sas_phy *mpt2sas_phy, *next_phy; 791 792 spin_lock_irqsave(&ioc->sas_node_lock, flags); 793 sas_node = _transport_sas_node_find_by_sas_address(ioc, 794 sas_address_parent); 795 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 796 if (!sas_node) 797 return; 798 list_for_each_entry_safe(mpt2sas_port, next, &sas_node->sas_port_list, 799 port_list) { 800 if (mpt2sas_port->remote_identify.sas_address != sas_address) 801 continue; 802 found = 1; 803 list_del(&mpt2sas_port->port_list); 804 goto out; 805 } 806 out: 807 if (!found) 808 return; 809 810 for (i = 0; i < sas_node->num_phys; i++) { 811 if (sas_node->phy[i].remote_identify.sas_address == sas_address) 812 memset(&sas_node->phy[i].remote_identify, 0 , 813 sizeof(struct sas_identify)); 814 } 815 816 list_for_each_entry_safe(mpt2sas_phy, next_phy, 817 &mpt2sas_port->phy_list, port_siblings) { 818 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) 819 dev_printk(KERN_INFO, &mpt2sas_port->port->dev, 820 "remove: sas_addr(0x%016llx), phy(%d)\n", 821 (unsigned long long) 822 mpt2sas_port->remote_identify.sas_address, 823 mpt2sas_phy->phy_id); 824 mpt2sas_phy->phy_belongs_to_port = 0; 825 sas_port_delete_phy(mpt2sas_port->port, mpt2sas_phy->phy); 826 list_del(&mpt2sas_phy->port_siblings); 827 } 828 sas_port_delete(mpt2sas_port->port); 829 kfree(mpt2sas_port); 830} 831 832/** 833 * mpt2sas_transport_add_host_phy - report sas_host phy to transport 834 * @ioc: per adapter object 835 * @mpt2sas_phy: mpt2sas per phy object 836 * @phy_pg0: sas phy page 0 837 * @parent_dev: parent device class object 838 * 839 * Returns 0 for success, non-zero for failure. 840 */ 841int 842mpt2sas_transport_add_host_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy 843 *mpt2sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev) 844{ 845 struct sas_phy *phy; 846 int phy_index = mpt2sas_phy->phy_id; 847 848 849 INIT_LIST_HEAD(&mpt2sas_phy->port_siblings); 850 phy = sas_phy_alloc(parent_dev, phy_index); 851 if (!phy) { 852 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 853 ioc->name, __FILE__, __LINE__, __func__); 854 return -1; 855 } 856 if ((_transport_set_identify(ioc, mpt2sas_phy->handle, 857 &mpt2sas_phy->identify))) { 858 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 859 ioc->name, __FILE__, __LINE__, __func__); 860 return -1; 861 } 862 phy->identify = mpt2sas_phy->identify; 863 mpt2sas_phy->attached_handle = le16_to_cpu(phy_pg0.AttachedDevHandle); 864 if (mpt2sas_phy->attached_handle) 865 _transport_set_identify(ioc, mpt2sas_phy->attached_handle, 866 &mpt2sas_phy->remote_identify); 867 phy->identify.phy_identifier = mpt2sas_phy->phy_id; 868 phy->negotiated_linkrate = _transport_convert_phy_link_rate( 869 phy_pg0.NegotiatedLinkRate & MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL); 870 phy->minimum_linkrate_hw = _transport_convert_phy_link_rate( 871 phy_pg0.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK); 872 phy->maximum_linkrate_hw = _transport_convert_phy_link_rate( 873 phy_pg0.HwLinkRate >> 4); 874 phy->minimum_linkrate = _transport_convert_phy_link_rate( 875 phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK); 876 phy->maximum_linkrate = _transport_convert_phy_link_rate( 877 phy_pg0.ProgrammedLinkRate >> 4); 878 879 if ((sas_phy_add(phy))) { 880 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 881 ioc->name, __FILE__, __LINE__, __func__); 882 sas_phy_free(phy); 883 return -1; 884 } 885 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) 886 dev_printk(KERN_INFO, &phy->dev, 887 "add: handle(0x%04x), sas_addr(0x%016llx)\n" 888 "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n", 889 mpt2sas_phy->handle, (unsigned long long) 890 mpt2sas_phy->identify.sas_address, 891 mpt2sas_phy->attached_handle, 892 (unsigned long long) 893 mpt2sas_phy->remote_identify.sas_address); 894 mpt2sas_phy->phy = phy; 895 return 0; 896} 897 898 899/** 900 * mpt2sas_transport_add_expander_phy - report expander phy to transport 901 * @ioc: per adapter object 902 * @mpt2sas_phy: mpt2sas per phy object 903 * @expander_pg1: expander page 1 904 * @parent_dev: parent device class object 905 * 906 * Returns 0 for success, non-zero for failure. 907 */ 908int 909mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy 910 *mpt2sas_phy, Mpi2ExpanderPage1_t expander_pg1, struct device *parent_dev) 911{ 912 struct sas_phy *phy; 913 int phy_index = mpt2sas_phy->phy_id; 914 915 INIT_LIST_HEAD(&mpt2sas_phy->port_siblings); 916 phy = sas_phy_alloc(parent_dev, phy_index); 917 if (!phy) { 918 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 919 ioc->name, __FILE__, __LINE__, __func__); 920 return -1; 921 } 922 if ((_transport_set_identify(ioc, mpt2sas_phy->handle, 923 &mpt2sas_phy->identify))) { 924 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 925 ioc->name, __FILE__, __LINE__, __func__); 926 return -1; 927 } 928 phy->identify = mpt2sas_phy->identify; 929 mpt2sas_phy->attached_handle = 930 le16_to_cpu(expander_pg1.AttachedDevHandle); 931 if (mpt2sas_phy->attached_handle) 932 _transport_set_identify(ioc, mpt2sas_phy->attached_handle, 933 &mpt2sas_phy->remote_identify); 934 phy->identify.phy_identifier = mpt2sas_phy->phy_id; 935 phy->negotiated_linkrate = _transport_convert_phy_link_rate( 936 expander_pg1.NegotiatedLinkRate & 937 MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL); 938 phy->minimum_linkrate_hw = _transport_convert_phy_link_rate( 939 expander_pg1.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK); 940 phy->maximum_linkrate_hw = _transport_convert_phy_link_rate( 941 expander_pg1.HwLinkRate >> 4); 942 phy->minimum_linkrate = _transport_convert_phy_link_rate( 943 expander_pg1.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK); 944 phy->maximum_linkrate = _transport_convert_phy_link_rate( 945 expander_pg1.ProgrammedLinkRate >> 4); 946 947 if ((sas_phy_add(phy))) { 948 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 949 ioc->name, __FILE__, __LINE__, __func__); 950 sas_phy_free(phy); 951 return -1; 952 } 953 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) 954 dev_printk(KERN_INFO, &phy->dev, 955 "add: handle(0x%04x), sas_addr(0x%016llx)\n" 956 "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n", 957 mpt2sas_phy->handle, (unsigned long long) 958 mpt2sas_phy->identify.sas_address, 959 mpt2sas_phy->attached_handle, 960 (unsigned long long) 961 mpt2sas_phy->remote_identify.sas_address); 962 mpt2sas_phy->phy = phy; 963 return 0; 964} 965 966/** 967 * mpt2sas_transport_update_links - refreshing phy link changes 968 * @ioc: per adapter object 969 * @sas_address: sas address of parent expander or sas host 970 * @handle: attached device handle 971 * @phy_numberv: phy number 972 * @link_rate: new link rate 973 * 974 * Returns nothing. 975 */ 976void 977mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc, 978 u64 sas_address, u16 handle, u8 phy_number, u8 link_rate) 979{ 980 unsigned long flags; 981 struct _sas_node *sas_node; 982 struct _sas_phy *mpt2sas_phy; 983 984 if (ioc->shost_recovery || ioc->pci_error_recovery) 985 return; 986 987 spin_lock_irqsave(&ioc->sas_node_lock, flags); 988 sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address); 989 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 990 if (!sas_node) 991 return; 992 993 mpt2sas_phy = &sas_node->phy[phy_number]; 994 mpt2sas_phy->attached_handle = handle; 995 if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) { 996 _transport_set_identify(ioc, handle, 997 &mpt2sas_phy->remote_identify); 998 _transport_add_phy_to_an_existing_port(ioc, sas_node, 999 mpt2sas_phy, mpt2sas_phy->remote_identify.sas_address); 1000 } else 1001 memset(&mpt2sas_phy->remote_identify, 0 , sizeof(struct 1002 sas_identify)); 1003 1004 if (mpt2sas_phy->phy) 1005 mpt2sas_phy->phy->negotiated_linkrate = 1006 _transport_convert_phy_link_rate(link_rate); 1007 1008 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) 1009 dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev, 1010 "refresh: parent sas_addr(0x%016llx),\n" 1011 "\tlink_rate(0x%02x), phy(%d)\n" 1012 "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n", 1013 (unsigned long long)sas_address, 1014 link_rate, phy_number, handle, (unsigned long long) 1015 mpt2sas_phy->remote_identify.sas_address); 1016} 1017 1018static inline void * 1019phy_to_ioc(struct sas_phy *phy) 1020{ 1021 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); 1022 return shost_priv(shost); 1023} 1024 1025static inline void * 1026rphy_to_ioc(struct sas_rphy *rphy) 1027{ 1028 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent); 1029 return shost_priv(shost); 1030} 1031 1032 1033/* report phy error log structure */ 1034struct phy_error_log_request{ 1035 u8 smp_frame_type; /* 0x40 */ 1036 u8 function; /* 0x11 */ 1037 u8 allocated_response_length; 1038 u8 request_length; /* 02 */ 1039 u8 reserved_1[5]; 1040 u8 phy_identifier; 1041 u8 reserved_2[2]; 1042}; 1043 1044/* report phy error log reply structure */ 1045struct phy_error_log_reply{ 1046 u8 smp_frame_type; /* 0x41 */ 1047 u8 function; /* 0x11 */ 1048 u8 function_result; 1049 u8 response_length; 1050 __be16 expander_change_count; 1051 u8 reserved_1[3]; 1052 u8 phy_identifier; 1053 u8 reserved_2[2]; 1054 __be32 invalid_dword; 1055 __be32 running_disparity_error; 1056 __be32 loss_of_dword_sync; 1057 __be32 phy_reset_problem; 1058}; 1059 1060/** 1061 * _transport_get_expander_phy_error_log - return expander counters 1062 * @ioc: per adapter object 1063 * @phy: The sas phy object 1064 * 1065 * Returns 0 for success, non-zero for failure. 1066 * 1067 */ 1068static int 1069_transport_get_expander_phy_error_log(struct MPT2SAS_ADAPTER *ioc, 1070 struct sas_phy *phy) 1071{ 1072 Mpi2SmpPassthroughRequest_t *mpi_request; 1073 Mpi2SmpPassthroughReply_t *mpi_reply; 1074 struct phy_error_log_request *phy_error_log_request; 1075 struct phy_error_log_reply *phy_error_log_reply; 1076 int rc; 1077 u16 smid; 1078 u32 ioc_state; 1079 unsigned long timeleft; 1080 void *psge; 1081 u32 sgl_flags; 1082 u8 issue_reset = 0; 1083 void *data_out = NULL; 1084 dma_addr_t data_out_dma; 1085 u32 sz; 1086 u16 wait_state_count; 1087 1088 if (ioc->shost_recovery || ioc->pci_error_recovery) { 1089 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", 1090 __func__, ioc->name); 1091 return -EFAULT; 1092 } 1093 1094 mutex_lock(&ioc->transport_cmds.mutex); 1095 1096 if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) { 1097 printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n", 1098 ioc->name, __func__); 1099 rc = -EAGAIN; 1100 goto out; 1101 } 1102 ioc->transport_cmds.status = MPT2_CMD_PENDING; 1103 1104 wait_state_count = 0; 1105 ioc_state = mpt2sas_base_get_iocstate(ioc, 1); 1106 while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { 1107 if (wait_state_count++ == 10) { 1108 printk(MPT2SAS_ERR_FMT 1109 "%s: failed due to ioc not operational\n", 1110 ioc->name, __func__); 1111 rc = -EFAULT; 1112 goto out; 1113 } 1114 ssleep(1); 1115 ioc_state = mpt2sas_base_get_iocstate(ioc, 1); 1116 printk(MPT2SAS_INFO_FMT "%s: waiting for " 1117 "operational state(count=%d)\n", ioc->name, 1118 __func__, wait_state_count); 1119 } 1120 if (wait_state_count) 1121 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n", 1122 ioc->name, __func__); 1123 1124 smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx); 1125 if (!smid) { 1126 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 1127 ioc->name, __func__); 1128 rc = -EAGAIN; 1129 goto out; 1130 } 1131 1132 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); 1133 ioc->transport_cmds.smid = smid; 1134 1135 sz = sizeof(struct phy_error_log_request) + 1136 sizeof(struct phy_error_log_reply); 1137 data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma); 1138 if (!data_out) { 1139 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, 1140 __LINE__, __func__); 1141 rc = -ENOMEM; 1142 mpt2sas_base_free_smid(ioc, smid); 1143 goto out; 1144 } 1145 1146 rc = -EINVAL; 1147 memset(data_out, 0, sz); 1148 phy_error_log_request = data_out; 1149 phy_error_log_request->smp_frame_type = 0x40; 1150 phy_error_log_request->function = 0x11; 1151 phy_error_log_request->request_length = 2; 1152 phy_error_log_request->allocated_response_length = 0; 1153 phy_error_log_request->phy_identifier = phy->number; 1154 1155 memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); 1156 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; 1157 mpi_request->PhysicalPort = 0xFF; 1158 mpi_request->VF_ID = 0; /* TODO */ 1159 mpi_request->VP_ID = 0; 1160 mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address); 1161 mpi_request->RequestDataLength = 1162 cpu_to_le16(sizeof(struct phy_error_log_request)); 1163 psge = &mpi_request->SGL; 1164 1165 /* WRITE sgel first */ 1166 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 1167 MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC); 1168 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; 1169 ioc->base_add_sg_single(psge, sgl_flags | 1170 sizeof(struct phy_error_log_request), data_out_dma); 1171 1172 /* incr sgel */ 1173 psge += ioc->sge_size; 1174 1175 /* READ sgel last */ 1176 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 1177 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | 1178 MPI2_SGE_FLAGS_END_OF_LIST); 1179 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; 1180 ioc->base_add_sg_single(psge, sgl_flags | 1181 sizeof(struct phy_error_log_reply), data_out_dma + 1182 sizeof(struct phy_error_log_request)); 1183 1184 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_error_log - " 1185 "send to sas_addr(0x%016llx), phy(%d)\n", ioc->name, 1186 (unsigned long long)phy->identify.sas_address, phy->number)); 1187 init_completion(&ioc->transport_cmds.done); 1188 mpt2sas_base_put_smid_default(ioc, smid); 1189 timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done, 1190 10*HZ); 1191 1192 if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) { 1193 printk(MPT2SAS_ERR_FMT "%s: timeout\n", 1194 ioc->name, __func__); 1195 _debug_dump_mf(mpi_request, 1196 sizeof(Mpi2SmpPassthroughRequest_t)/4); 1197 if (!(ioc->transport_cmds.status & MPT2_CMD_RESET)) 1198 issue_reset = 1; 1199 goto issue_host_reset; 1200 } 1201 1202 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_error_log - " 1203 "complete\n", ioc->name)); 1204 1205 if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) { 1206 1207 mpi_reply = ioc->transport_cmds.reply; 1208 1209 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT 1210 "phy_error_log - reply data transfer size(%d)\n", 1211 ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength))); 1212 1213 if (le16_to_cpu(mpi_reply->ResponseDataLength) != 1214 sizeof(struct phy_error_log_reply)) 1215 goto out; 1216 1217 phy_error_log_reply = data_out + 1218 sizeof(struct phy_error_log_request); 1219 1220 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT 1221 "phy_error_log - function_result(%d)\n", 1222 ioc->name, phy_error_log_reply->function_result)); 1223 1224 phy->invalid_dword_count = 1225 be32_to_cpu(phy_error_log_reply->invalid_dword); 1226 phy->running_disparity_error_count = 1227 be32_to_cpu(phy_error_log_reply->running_disparity_error); 1228 phy->loss_of_dword_sync_count = 1229 be32_to_cpu(phy_error_log_reply->loss_of_dword_sync); 1230 phy->phy_reset_problem_count = 1231 be32_to_cpu(phy_error_log_reply->phy_reset_problem); 1232 rc = 0; 1233 } else 1234 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT 1235 "phy_error_log - no reply\n", ioc->name)); 1236 1237 issue_host_reset: 1238 if (issue_reset) 1239 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, 1240 FORCE_BIG_HAMMER); 1241 out: 1242 ioc->transport_cmds.status = MPT2_CMD_NOT_USED; 1243 if (data_out) 1244 pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma); 1245 1246 mutex_unlock(&ioc->transport_cmds.mutex); 1247 return rc; 1248} 1249 1250/** 1251 * _transport_get_linkerrors - return phy counters for both hba and expanders 1252 * @phy: The sas phy object 1253 * 1254 * Returns 0 for success, non-zero for failure. 1255 * 1256 */ 1257static int 1258_transport_get_linkerrors(struct sas_phy *phy) 1259{ 1260 struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy); 1261 unsigned long flags; 1262 Mpi2ConfigReply_t mpi_reply; 1263 Mpi2SasPhyPage1_t phy_pg1; 1264 1265 spin_lock_irqsave(&ioc->sas_node_lock, flags); 1266 if (_transport_sas_node_find_by_sas_address(ioc, 1267 phy->identify.sas_address) == NULL) { 1268 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 1269 return -EINVAL; 1270 } 1271 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 1272 1273 if (phy->identify.sas_address != ioc->sas_hba.sas_address) 1274 return _transport_get_expander_phy_error_log(ioc, phy); 1275 1276 /* get hba phy error logs */ 1277 if ((mpt2sas_config_get_phy_pg1(ioc, &mpi_reply, &phy_pg1, 1278 phy->number))) { 1279 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1280 ioc->name, __FILE__, __LINE__, __func__); 1281 return -ENXIO; 1282 } 1283 1284 if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) 1285 printk(MPT2SAS_INFO_FMT "phy(%d), ioc_status" 1286 "(0x%04x), loginfo(0x%08x)\n", ioc->name, 1287 phy->number, le16_to_cpu(mpi_reply.IOCStatus), 1288 le32_to_cpu(mpi_reply.IOCLogInfo)); 1289 1290 phy->invalid_dword_count = le32_to_cpu(phy_pg1.InvalidDwordCount); 1291 phy->running_disparity_error_count = 1292 le32_to_cpu(phy_pg1.RunningDisparityErrorCount); 1293 phy->loss_of_dword_sync_count = 1294 le32_to_cpu(phy_pg1.LossDwordSynchCount); 1295 phy->phy_reset_problem_count = 1296 le32_to_cpu(phy_pg1.PhyResetProblemCount); 1297 return 0; 1298} 1299 1300/** 1301 * _transport_get_enclosure_identifier - 1302 * @phy: The sas phy object 1303 * 1304 * Obtain the enclosure logical id for an expander. 1305 * Returns 0 for success, non-zero for failure. 1306 */ 1307static int 1308_transport_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier) 1309{ 1310 struct MPT2SAS_ADAPTER *ioc = rphy_to_ioc(rphy); 1311 struct _sas_device *sas_device; 1312 unsigned long flags; 1313 1314 spin_lock_irqsave(&ioc->sas_device_lock, flags); 1315 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, 1316 rphy->identify.sas_address); 1317 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 1318 1319 if (!sas_device) 1320 return -ENXIO; 1321 1322 *identifier = sas_device->enclosure_logical_id; 1323 return 0; 1324} 1325 1326/** 1327 * _transport_get_bay_identifier - 1328 * @phy: The sas phy object 1329 * 1330 * Returns the slot id for a device that resides inside an enclosure. 1331 */ 1332static int 1333_transport_get_bay_identifier(struct sas_rphy *rphy) 1334{ 1335 struct MPT2SAS_ADAPTER *ioc = rphy_to_ioc(rphy); 1336 struct _sas_device *sas_device; 1337 unsigned long flags; 1338 1339 spin_lock_irqsave(&ioc->sas_device_lock, flags); 1340 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, 1341 rphy->identify.sas_address); 1342 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 1343 1344 if (!sas_device) 1345 return -ENXIO; 1346 1347 return sas_device->slot; 1348} 1349 1350/* phy control request structure */ 1351struct phy_control_request{ 1352 u8 smp_frame_type; /* 0x40 */ 1353 u8 function; /* 0x91 */ 1354 u8 allocated_response_length; 1355 u8 request_length; /* 0x09 */ 1356 u16 expander_change_count; 1357 u8 reserved_1[3]; 1358 u8 phy_identifier; 1359 u8 phy_operation; 1360 u8 reserved_2[13]; 1361 u64 attached_device_name; 1362 u8 programmed_min_physical_link_rate; 1363 u8 programmed_max_physical_link_rate; 1364 u8 reserved_3[6]; 1365}; 1366 1367/* phy control reply structure */ 1368struct phy_control_reply{ 1369 u8 smp_frame_type; /* 0x41 */ 1370 u8 function; /* 0x11 */ 1371 u8 function_result; 1372 u8 response_length; 1373}; 1374 1375#define SMP_PHY_CONTROL_LINK_RESET (0x01) 1376#define SMP_PHY_CONTROL_HARD_RESET (0x02) 1377#define SMP_PHY_CONTROL_DISABLE (0x03) 1378 1379/** 1380 * _transport_expander_phy_control - expander phy control 1381 * @ioc: per adapter object 1382 * @phy: The sas phy object 1383 * 1384 * Returns 0 for success, non-zero for failure. 1385 * 1386 */ 1387static int 1388_transport_expander_phy_control(struct MPT2SAS_ADAPTER *ioc, 1389 struct sas_phy *phy, u8 phy_operation) 1390{ 1391 Mpi2SmpPassthroughRequest_t *mpi_request; 1392 Mpi2SmpPassthroughReply_t *mpi_reply; 1393 struct phy_control_request *phy_control_request; 1394 struct phy_control_reply *phy_control_reply; 1395 int rc; 1396 u16 smid; 1397 u32 ioc_state; 1398 unsigned long timeleft; 1399 void *psge; 1400 u32 sgl_flags; 1401 u8 issue_reset = 0; 1402 void *data_out = NULL; 1403 dma_addr_t data_out_dma; 1404 u32 sz; 1405 u16 wait_state_count; 1406 1407 if (ioc->shost_recovery) { 1408 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", 1409 __func__, ioc->name); 1410 return -EFAULT; 1411 } 1412 1413 mutex_lock(&ioc->transport_cmds.mutex); 1414 1415 if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) { 1416 printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n", 1417 ioc->name, __func__); 1418 rc = -EAGAIN; 1419 goto out; 1420 } 1421 ioc->transport_cmds.status = MPT2_CMD_PENDING; 1422 1423 wait_state_count = 0; 1424 ioc_state = mpt2sas_base_get_iocstate(ioc, 1); 1425 while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { 1426 if (wait_state_count++ == 10) { 1427 printk(MPT2SAS_ERR_FMT 1428 "%s: failed due to ioc not operational\n", 1429 ioc->name, __func__); 1430 rc = -EFAULT; 1431 goto out; 1432 } 1433 ssleep(1); 1434 ioc_state = mpt2sas_base_get_iocstate(ioc, 1); 1435 printk(MPT2SAS_INFO_FMT "%s: waiting for " 1436 "operational state(count=%d)\n", ioc->name, 1437 __func__, wait_state_count); 1438 } 1439 if (wait_state_count) 1440 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n", 1441 ioc->name, __func__); 1442 1443 smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx); 1444 if (!smid) { 1445 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 1446 ioc->name, __func__); 1447 rc = -EAGAIN; 1448 goto out; 1449 } 1450 1451 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); 1452 ioc->transport_cmds.smid = smid; 1453 1454 sz = sizeof(struct phy_control_request) + 1455 sizeof(struct phy_control_reply); 1456 data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma); 1457 if (!data_out) { 1458 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, 1459 __LINE__, __func__); 1460 rc = -ENOMEM; 1461 mpt2sas_base_free_smid(ioc, smid); 1462 goto out; 1463 } 1464 1465 rc = -EINVAL; 1466 memset(data_out, 0, sz); 1467 phy_control_request = data_out; 1468 phy_control_request->smp_frame_type = 0x40; 1469 phy_control_request->function = 0x91; 1470 phy_control_request->request_length = 9; 1471 phy_control_request->allocated_response_length = 0; 1472 phy_control_request->phy_identifier = phy->number; 1473 phy_control_request->phy_operation = phy_operation; 1474 phy_control_request->programmed_min_physical_link_rate = 1475 phy->minimum_linkrate << 4; 1476 phy_control_request->programmed_max_physical_link_rate = 1477 phy->maximum_linkrate << 4; 1478 1479 memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); 1480 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; 1481 mpi_request->PhysicalPort = 0xFF; 1482 mpi_request->VF_ID = 0; /* TODO */ 1483 mpi_request->VP_ID = 0; 1484 mpi_request->SASAddress = cpu_to_le64(phy->identify.sas_address); 1485 mpi_request->RequestDataLength = 1486 cpu_to_le16(sizeof(struct phy_error_log_request)); 1487 psge = &mpi_request->SGL; 1488 1489 /* WRITE sgel first */ 1490 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 1491 MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC); 1492 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; 1493 ioc->base_add_sg_single(psge, sgl_flags | 1494 sizeof(struct phy_control_request), data_out_dma); 1495 1496 /* incr sgel */ 1497 psge += ioc->sge_size; 1498 1499 /* READ sgel last */ 1500 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 1501 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | 1502 MPI2_SGE_FLAGS_END_OF_LIST); 1503 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; 1504 ioc->base_add_sg_single(psge, sgl_flags | 1505 sizeof(struct phy_control_reply), data_out_dma + 1506 sizeof(struct phy_control_request)); 1507 1508 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_control - " 1509 "send to sas_addr(0x%016llx), phy(%d), opcode(%d)\n", ioc->name, 1510 (unsigned long long)phy->identify.sas_address, phy->number, 1511 phy_operation)); 1512 1513 init_completion(&ioc->transport_cmds.done); 1514 mpt2sas_base_put_smid_default(ioc, smid); 1515 timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done, 1516 10*HZ); 1517 1518 if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) { 1519 printk(MPT2SAS_ERR_FMT "%s: timeout\n", 1520 ioc->name, __func__); 1521 _debug_dump_mf(mpi_request, 1522 sizeof(Mpi2SmpPassthroughRequest_t)/4); 1523 if (!(ioc->transport_cmds.status & MPT2_CMD_RESET)) 1524 issue_reset = 1; 1525 goto issue_host_reset; 1526 } 1527 1528 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_control - " 1529 "complete\n", ioc->name)); 1530 1531 if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) { 1532 1533 mpi_reply = ioc->transport_cmds.reply; 1534 1535 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT 1536 "phy_control - reply data transfer size(%d)\n", 1537 ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength))); 1538 1539 if (le16_to_cpu(mpi_reply->ResponseDataLength) != 1540 sizeof(struct phy_control_reply)) 1541 goto out; 1542 1543 phy_control_reply = data_out + 1544 sizeof(struct phy_control_request); 1545 1546 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT 1547 "phy_control - function_result(%d)\n", 1548 ioc->name, phy_control_reply->function_result)); 1549 1550 rc = 0; 1551 } else 1552 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT 1553 "phy_control - no reply\n", ioc->name)); 1554 1555 issue_host_reset: 1556 if (issue_reset) 1557 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, 1558 FORCE_BIG_HAMMER); 1559 out: 1560 ioc->transport_cmds.status = MPT2_CMD_NOT_USED; 1561 if (data_out) 1562 pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma); 1563 1564 mutex_unlock(&ioc->transport_cmds.mutex); 1565 return rc; 1566} 1567 1568/** 1569 * _transport_phy_reset - 1570 * @phy: The sas phy object 1571 * @hard_reset: 1572 * 1573 * Returns 0 for success, non-zero for failure. 1574 */ 1575static int 1576_transport_phy_reset(struct sas_phy *phy, int hard_reset) 1577{ 1578 struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy); 1579 Mpi2SasIoUnitControlReply_t mpi_reply; 1580 Mpi2SasIoUnitControlRequest_t mpi_request; 1581 unsigned long flags; 1582 1583 spin_lock_irqsave(&ioc->sas_node_lock, flags); 1584 if (_transport_sas_node_find_by_sas_address(ioc, 1585 phy->identify.sas_address) == NULL) { 1586 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 1587 return -EINVAL; 1588 } 1589 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 1590 1591 /* handle expander phys */ 1592 if (phy->identify.sas_address != ioc->sas_hba.sas_address) 1593 return _transport_expander_phy_control(ioc, phy, 1594 (hard_reset == 1) ? SMP_PHY_CONTROL_HARD_RESET : 1595 SMP_PHY_CONTROL_LINK_RESET); 1596 1597 /* handle hba phys */ 1598 memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlReply_t)); 1599 mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; 1600 mpi_request.Operation = hard_reset ? 1601 MPI2_SAS_OP_PHY_HARD_RESET : MPI2_SAS_OP_PHY_LINK_RESET; 1602 mpi_request.PhyNum = phy->number; 1603 1604 if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply, &mpi_request))) { 1605 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1606 ioc->name, __FILE__, __LINE__, __func__); 1607 return -ENXIO; 1608 } 1609 1610 if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) 1611 printk(MPT2SAS_INFO_FMT "phy(%d), ioc_status" 1612 "(0x%04x), loginfo(0x%08x)\n", ioc->name, 1613 phy->number, le16_to_cpu(mpi_reply.IOCStatus), 1614 le32_to_cpu(mpi_reply.IOCLogInfo)); 1615 1616 return 0; 1617} 1618 1619/** 1620 * _transport_phy_enable - enable/disable phys 1621 * @phy: The sas phy object 1622 * @enable: enable phy when true 1623 * 1624 * Only support sas_host direct attached phys. 1625 * Returns 0 for success, non-zero for failure. 1626 */ 1627static int 1628_transport_phy_enable(struct sas_phy *phy, int enable) 1629{ 1630 struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy); 1631 Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL; 1632 Mpi2ConfigReply_t mpi_reply; 1633 u16 ioc_status; 1634 u16 sz; 1635 int rc = 0; 1636 unsigned long flags; 1637 1638 spin_lock_irqsave(&ioc->sas_node_lock, flags); 1639 if (_transport_sas_node_find_by_sas_address(ioc, 1640 phy->identify.sas_address) == NULL) { 1641 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 1642 return -EINVAL; 1643 } 1644 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 1645 1646 /* handle expander phys */ 1647 if (phy->identify.sas_address != ioc->sas_hba.sas_address) 1648 return _transport_expander_phy_control(ioc, phy, 1649 (enable == 1) ? SMP_PHY_CONTROL_LINK_RESET : 1650 SMP_PHY_CONTROL_DISABLE); 1651 1652 /* handle hba phys */ 1653 1654 /* sas_iounit page 1 */ 1655 sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys * 1656 sizeof(Mpi2SasIOUnit1PhyData_t)); 1657 sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL); 1658 if (!sas_iounit_pg1) { 1659 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1660 ioc->name, __FILE__, __LINE__, __func__); 1661 rc = -ENOMEM; 1662 goto out; 1663 } 1664 if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply, 1665 sas_iounit_pg1, sz))) { 1666 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1667 ioc->name, __FILE__, __LINE__, __func__); 1668 rc = -ENXIO; 1669 goto out; 1670 } 1671 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 1672 MPI2_IOCSTATUS_MASK; 1673 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 1674 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1675 ioc->name, __FILE__, __LINE__, __func__); 1676 rc = -EIO; 1677 goto out; 1678 } 1679 1680 if (enable) 1681 sas_iounit_pg1->PhyData[phy->number].PhyFlags 1682 &= ~MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE; 1683 else 1684 sas_iounit_pg1->PhyData[phy->number].PhyFlags 1685 |= MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE; 1686 1687 mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, sz); 1688 1689 /* link reset */ 1690 if (enable) 1691 _transport_phy_reset(phy, 0); 1692 1693 out: 1694 kfree(sas_iounit_pg1); 1695 return rc; 1696} 1697 1698/** 1699 * _transport_phy_speed - set phy min/max link rates 1700 * @phy: The sas phy object 1701 * @rates: rates defined in sas_phy_linkrates 1702 * 1703 * Only support sas_host direct attached phys. 1704 * Returns 0 for success, non-zero for failure. 1705 */ 1706static int 1707_transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates) 1708{ 1709 struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy); 1710 Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL; 1711 Mpi2SasPhyPage0_t phy_pg0; 1712 Mpi2ConfigReply_t mpi_reply; 1713 u16 ioc_status; 1714 u16 sz; 1715 int i; 1716 int rc = 0; 1717 unsigned long flags; 1718 1719 spin_lock_irqsave(&ioc->sas_node_lock, flags); 1720 if (_transport_sas_node_find_by_sas_address(ioc, 1721 phy->identify.sas_address) == NULL) { 1722 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 1723 return -EINVAL; 1724 } 1725 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 1726 1727 if (!rates->minimum_linkrate) 1728 rates->minimum_linkrate = phy->minimum_linkrate; 1729 else if (rates->minimum_linkrate < phy->minimum_linkrate_hw) 1730 rates->minimum_linkrate = phy->minimum_linkrate_hw; 1731 1732 if (!rates->maximum_linkrate) 1733 rates->maximum_linkrate = phy->maximum_linkrate; 1734 else if (rates->maximum_linkrate > phy->maximum_linkrate_hw) 1735 rates->maximum_linkrate = phy->maximum_linkrate_hw; 1736 1737 /* handle expander phys */ 1738 if (phy->identify.sas_address != ioc->sas_hba.sas_address) { 1739 phy->minimum_linkrate = rates->minimum_linkrate; 1740 phy->maximum_linkrate = rates->maximum_linkrate; 1741 return _transport_expander_phy_control(ioc, phy, 1742 SMP_PHY_CONTROL_LINK_RESET); 1743 } 1744 1745 /* handle hba phys */ 1746 1747 /* sas_iounit page 1 */ 1748 sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys * 1749 sizeof(Mpi2SasIOUnit1PhyData_t)); 1750 sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL); 1751 if (!sas_iounit_pg1) { 1752 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1753 ioc->name, __FILE__, __LINE__, __func__); 1754 rc = -ENOMEM; 1755 goto out; 1756 } 1757 if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply, 1758 sas_iounit_pg1, sz))) { 1759 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1760 ioc->name, __FILE__, __LINE__, __func__); 1761 rc = -ENXIO; 1762 goto out; 1763 } 1764 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 1765 MPI2_IOCSTATUS_MASK; 1766 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 1767 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1768 ioc->name, __FILE__, __LINE__, __func__); 1769 rc = -EIO; 1770 goto out; 1771 } 1772 1773 for (i = 0; i < ioc->sas_hba.num_phys; i++) { 1774 if (phy->number != i) { 1775 sas_iounit_pg1->PhyData[i].MaxMinLinkRate = 1776 (ioc->sas_hba.phy[i].phy->minimum_linkrate + 1777 (ioc->sas_hba.phy[i].phy->maximum_linkrate << 4)); 1778 } else { 1779 sas_iounit_pg1->PhyData[i].MaxMinLinkRate = 1780 (rates->minimum_linkrate + 1781 (rates->maximum_linkrate << 4)); 1782 } 1783 } 1784 1785 if (mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, 1786 sz)) { 1787 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1788 ioc->name, __FILE__, __LINE__, __func__); 1789 rc = -ENXIO; 1790 goto out; 1791 } 1792 1793 /* link reset */ 1794 _transport_phy_reset(phy, 0); 1795 1796 /* read phy page 0, then update the rates in the sas transport phy */ 1797 if (!mpt2sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0, 1798 phy->number)) { 1799 phy->minimum_linkrate = _transport_convert_phy_link_rate( 1800 phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK); 1801 phy->maximum_linkrate = _transport_convert_phy_link_rate( 1802 phy_pg0.ProgrammedLinkRate >> 4); 1803 phy->negotiated_linkrate = _transport_convert_phy_link_rate( 1804 phy_pg0.NegotiatedLinkRate & 1805 MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL); 1806 } 1807 1808 out: 1809 kfree(sas_iounit_pg1); 1810 return rc; 1811} 1812 1813 1814/** 1815 * _transport_smp_handler - transport portal for smp passthru 1816 * @shost: shost object 1817 * @rphy: sas transport rphy object 1818 * @req: 1819 * 1820 * This used primarily for smp_utils. 1821 * Example: 1822 * smp_rep_general /sys/class/bsg/expander-5:0 1823 */ 1824static int 1825_transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, 1826 struct request *req) 1827{ 1828 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); 1829 Mpi2SmpPassthroughRequest_t *mpi_request; 1830 Mpi2SmpPassthroughReply_t *mpi_reply; 1831 int rc; 1832 u16 smid; 1833 u32 ioc_state; 1834 unsigned long timeleft; 1835 void *psge; 1836 u32 sgl_flags; 1837 u8 issue_reset = 0; 1838 dma_addr_t dma_addr_in = 0; 1839 dma_addr_t dma_addr_out = 0; 1840 u16 wait_state_count; 1841 struct request *rsp = req->next_rq; 1842 1843 if (!rsp) { 1844 printk(MPT2SAS_ERR_FMT "%s: the smp response space is " 1845 "missing\n", ioc->name, __func__); 1846 return -EINVAL; 1847 } 1848 1849 /* do we need to support multiple segments? */ 1850 if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) { 1851 printk(MPT2SAS_ERR_FMT "%s: multiple segments req %u %u, " 1852 "rsp %u %u\n", ioc->name, __func__, req->bio->bi_vcnt, 1853 blk_rq_bytes(req), rsp->bio->bi_vcnt, blk_rq_bytes(rsp)); 1854 return -EINVAL; 1855 } 1856 1857 if (ioc->shost_recovery) { 1858 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", 1859 __func__, ioc->name); 1860 return -EFAULT; 1861 } 1862 1863 rc = mutex_lock_interruptible(&ioc->transport_cmds.mutex); 1864 if (rc) 1865 return rc; 1866 1867 if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) { 1868 printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n", ioc->name, 1869 __func__); 1870 rc = -EAGAIN; 1871 goto out; 1872 } 1873 ioc->transport_cmds.status = MPT2_CMD_PENDING; 1874 1875 wait_state_count = 0; 1876 ioc_state = mpt2sas_base_get_iocstate(ioc, 1); 1877 while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { 1878 if (wait_state_count++ == 10) { 1879 printk(MPT2SAS_ERR_FMT 1880 "%s: failed due to ioc not operational\n", 1881 ioc->name, __func__); 1882 rc = -EFAULT; 1883 goto out; 1884 } 1885 ssleep(1); 1886 ioc_state = mpt2sas_base_get_iocstate(ioc, 1); 1887 printk(MPT2SAS_INFO_FMT "%s: waiting for " 1888 "operational state(count=%d)\n", ioc->name, 1889 __func__, wait_state_count); 1890 } 1891 if (wait_state_count) 1892 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n", 1893 ioc->name, __func__); 1894 1895 smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx); 1896 if (!smid) { 1897 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 1898 ioc->name, __func__); 1899 rc = -EAGAIN; 1900 goto out; 1901 } 1902 1903 rc = 0; 1904 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); 1905 ioc->transport_cmds.smid = smid; 1906 1907 memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); 1908 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; 1909 mpi_request->PhysicalPort = 0xFF; 1910 mpi_request->VF_ID = 0; /* TODO */ 1911 mpi_request->VP_ID = 0; 1912 mpi_request->SASAddress = (rphy) ? 1913 cpu_to_le64(rphy->identify.sas_address) : 1914 cpu_to_le64(ioc->sas_hba.sas_address); 1915 mpi_request->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4); 1916 psge = &mpi_request->SGL; 1917 1918 /* WRITE sgel first */ 1919 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 1920 MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC); 1921 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; 1922 dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio), 1923 blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL); 1924 if (!dma_addr_out) { 1925 mpt2sas_base_free_smid(ioc, smid); 1926 goto unmap; 1927 } 1928 1929 ioc->base_add_sg_single(psge, sgl_flags | (blk_rq_bytes(req) - 4), 1930 dma_addr_out); 1931 1932 /* incr sgel */ 1933 psge += ioc->sge_size; 1934 1935 /* READ sgel last */ 1936 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 1937 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | 1938 MPI2_SGE_FLAGS_END_OF_LIST); 1939 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; 1940 dma_addr_in = pci_map_single(ioc->pdev, bio_data(rsp->bio), 1941 blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL); 1942 if (!dma_addr_in) { 1943 mpt2sas_base_free_smid(ioc, smid); 1944 goto unmap; 1945 } 1946 1947 ioc->base_add_sg_single(psge, sgl_flags | (blk_rq_bytes(rsp) + 4), 1948 dma_addr_in); 1949 1950 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "%s - " 1951 "sending smp request\n", ioc->name, __func__)); 1952 1953 init_completion(&ioc->transport_cmds.done); 1954 mpt2sas_base_put_smid_default(ioc, smid); 1955 timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done, 1956 10*HZ); 1957 1958 if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) { 1959 printk(MPT2SAS_ERR_FMT "%s : timeout\n", 1960 __func__, ioc->name); 1961 _debug_dump_mf(mpi_request, 1962 sizeof(Mpi2SmpPassthroughRequest_t)/4); 1963 if (!(ioc->transport_cmds.status & MPT2_CMD_RESET)) 1964 issue_reset = 1; 1965 goto issue_host_reset; 1966 } 1967 1968 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "%s - " 1969 "complete\n", ioc->name, __func__)); 1970 1971 if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) { 1972 1973 mpi_reply = ioc->transport_cmds.reply; 1974 1975 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT 1976 "%s - reply data transfer size(%d)\n", 1977 ioc->name, __func__, 1978 le16_to_cpu(mpi_reply->ResponseDataLength))); 1979 1980 memcpy(req->sense, mpi_reply, sizeof(*mpi_reply)); 1981 req->sense_len = sizeof(*mpi_reply); 1982 req->resid_len = 0; 1983 rsp->resid_len -= 1984 le16_to_cpu(mpi_reply->ResponseDataLength); 1985 } else { 1986 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT 1987 "%s - no reply\n", ioc->name, __func__)); 1988 rc = -ENXIO; 1989 } 1990 1991 issue_host_reset: 1992 if (issue_reset) { 1993 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, 1994 FORCE_BIG_HAMMER); 1995 rc = -ETIMEDOUT; 1996 } 1997 1998 unmap: 1999 if (dma_addr_out) 2000 pci_unmap_single(ioc->pdev, dma_addr_out, blk_rq_bytes(req), 2001 PCI_DMA_BIDIRECTIONAL); 2002 if (dma_addr_in) 2003 pci_unmap_single(ioc->pdev, dma_addr_in, blk_rq_bytes(rsp), 2004 PCI_DMA_BIDIRECTIONAL); 2005 2006 out: 2007 ioc->transport_cmds.status = MPT2_CMD_NOT_USED; 2008 mutex_unlock(&ioc->transport_cmds.mutex); 2009 return rc; 2010} 2011 2012struct sas_function_template mpt2sas_transport_functions = { 2013 .get_linkerrors = _transport_get_linkerrors, 2014 .get_enclosure_identifier = _transport_get_enclosure_identifier, 2015 .get_bay_identifier = _transport_get_bay_identifier, 2016 .phy_reset = _transport_phy_reset, 2017 .phy_enable = _transport_phy_enable, 2018 .set_phy_speed = _transport_phy_speed, 2019 .smp_handler = _transport_smp_handler, 2020}; 2021 2022struct scsi_transport_template *mpt2sas_transport_template; 2023