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 u64 *sas_address_le; 303 u16 wait_state_count; 304 305 if (ioc->shost_recovery || ioc->pci_error_recovery) { 306 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", 307 __func__, ioc->name); 308 return -EFAULT; 309 } 310 311 mutex_lock(&ioc->transport_cmds.mutex); 312 313 if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) { 314 printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n", 315 ioc->name, __func__); 316 rc = -EAGAIN; 317 goto out; 318 } 319 ioc->transport_cmds.status = MPT2_CMD_PENDING; 320 321 wait_state_count = 0; 322 ioc_state = mpt2sas_base_get_iocstate(ioc, 1); 323 while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { 324 if (wait_state_count++ == 10) { 325 printk(MPT2SAS_ERR_FMT 326 "%s: failed due to ioc not operational\n", 327 ioc->name, __func__); 328 rc = -EFAULT; 329 goto out; 330 } 331 ssleep(1); 332 ioc_state = mpt2sas_base_get_iocstate(ioc, 1); 333 printk(MPT2SAS_INFO_FMT "%s: waiting for " 334 "operational state(count=%d)\n", ioc->name, 335 __func__, wait_state_count); 336 } 337 if (wait_state_count) 338 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n", 339 ioc->name, __func__); 340 341 smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx); 342 if (!smid) { 343 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 344 ioc->name, __func__); 345 rc = -EAGAIN; 346 goto out; 347 } 348 349 rc = 0; 350 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); 351 ioc->transport_cmds.smid = smid; 352 353 sz = sizeof(struct rep_manu_request) + sizeof(struct rep_manu_reply); 354 data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma); 355 356 if (!data_out) { 357 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, 358 __LINE__, __func__); 359 rc = -ENOMEM; 360 mpt2sas_base_free_smid(ioc, smid); 361 goto out; 362 } 363 364 manufacture_request = data_out; 365 manufacture_request->smp_frame_type = 0x40; 366 manufacture_request->function = 1; 367 manufacture_request->reserved = 0; 368 manufacture_request->request_length = 0; 369 370 memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); 371 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; 372 mpi_request->PhysicalPort = 0xFF; 373 mpi_request->VF_ID = 0; /* TODO */ 374 mpi_request->VP_ID = 0; 375 sas_address_le = (u64 *)&mpi_request->SASAddress; 376 *sas_address_le = cpu_to_le64(sas_address); 377 mpi_request->RequestDataLength = 378 cpu_to_le16(sizeof(struct rep_manu_request)); 379 psge = &mpi_request->SGL; 380 381 /* WRITE sgel first */ 382 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 383 MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC); 384 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; 385 ioc->base_add_sg_single(psge, sgl_flags | 386 sizeof(struct rep_manu_request), data_out_dma); 387 388 /* incr sgel */ 389 psge += ioc->sge_size; 390 391 /* READ sgel last */ 392 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 393 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | 394 MPI2_SGE_FLAGS_END_OF_LIST); 395 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; 396 ioc->base_add_sg_single(psge, sgl_flags | 397 sizeof(struct rep_manu_reply), data_out_dma + 398 sizeof(struct rep_manu_request)); 399 400 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "report_manufacture - " 401 "send to sas_addr(0x%016llx)\n", ioc->name, 402 (unsigned long long)sas_address)); 403 mpt2sas_base_put_smid_default(ioc, smid); 404 init_completion(&ioc->transport_cmds.done); 405 timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done, 406 10*HZ); 407 408 if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) { 409 printk(MPT2SAS_ERR_FMT "%s: timeout\n", 410 ioc->name, __func__); 411 _debug_dump_mf(mpi_request, 412 sizeof(Mpi2SmpPassthroughRequest_t)/4); 413 if (!(ioc->transport_cmds.status & MPT2_CMD_RESET)) 414 issue_reset = 1; 415 goto issue_host_reset; 416 } 417 418 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "report_manufacture - " 419 "complete\n", ioc->name)); 420 421 if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) { 422 u8 *tmp; 423 424 mpi_reply = ioc->transport_cmds.reply; 425 426 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT 427 "report_manufacture - reply data transfer size(%d)\n", 428 ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength))); 429 430 if (le16_to_cpu(mpi_reply->ResponseDataLength) != 431 sizeof(struct rep_manu_reply)) 432 goto out; 433 434 manufacture_reply = data_out + sizeof(struct rep_manu_request); 435 strncpy(edev->vendor_id, manufacture_reply->vendor_id, 436 SAS_EXPANDER_VENDOR_ID_LEN); 437 strncpy(edev->product_id, manufacture_reply->product_id, 438 SAS_EXPANDER_PRODUCT_ID_LEN); 439 strncpy(edev->product_rev, manufacture_reply->product_rev, 440 SAS_EXPANDER_PRODUCT_REV_LEN); 441 edev->level = manufacture_reply->sas_format & 1; 442 if (edev->level) { 443 strncpy(edev->component_vendor_id, 444 manufacture_reply->component_vendor_id, 445 SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN); 446 tmp = (u8 *)&manufacture_reply->component_id; 447 edev->component_id = tmp[0] << 8 | tmp[1]; 448 edev->component_revision_id = 449 manufacture_reply->component_revision_id; 450 } 451 } else 452 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT 453 "report_manufacture - no reply\n", ioc->name)); 454 455 issue_host_reset: 456 if (issue_reset) 457 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, 458 FORCE_BIG_HAMMER); 459 out: 460 ioc->transport_cmds.status = MPT2_CMD_NOT_USED; 461 if (data_out) 462 pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma); 463 464 mutex_unlock(&ioc->transport_cmds.mutex); 465 return rc; 466} 467 468 469/** 470 * _transport_delete_duplicate_port - (see below description) 471 * @ioc: per adapter object 472 * @sas_node: sas node object (either expander or sas host) 473 * @sas_address: sas address of device being added 474 * @phy_num: phy number 475 * 476 * This function is called when attempting to add a new port that is claiming 477 * the same phy resources already in use by another port. If we don't release 478 * the claimed phy resources, the sas transport layer will hang from the BUG 479 * in sas_port_add_phy. 480 * 481 * The reason we would hit this issue is becuase someone is changing the 482 * sas address of a device on the fly, meanwhile controller firmware sends 483 * EVENTs out of order when removing the previous instance of the device. 484 */ 485static void 486_transport_delete_duplicate_port(struct MPT2SAS_ADAPTER *ioc, 487 struct _sas_node *sas_node, u64 sas_address, int phy_num) 488{ 489 struct _sas_port *mpt2sas_port, *mpt2sas_port_duplicate; 490 struct _sas_phy *mpt2sas_phy; 491 492 printk(MPT2SAS_ERR_FMT "new device located at sas_addr(0x%016llx), " 493 "phy_id(%d)\n", ioc->name, (unsigned long long)sas_address, 494 phy_num); 495 496 mpt2sas_port_duplicate = NULL; 497 list_for_each_entry(mpt2sas_port, &sas_node->sas_port_list, port_list) { 498 dev_printk(KERN_ERR, &mpt2sas_port->port->dev, 499 "existing device at sas_addr(0x%016llx), num_phys(%d)\n", 500 (unsigned long long) 501 mpt2sas_port->remote_identify.sas_address, 502 mpt2sas_port->num_phys); 503 list_for_each_entry(mpt2sas_phy, &mpt2sas_port->phy_list, 504 port_siblings) { 505 dev_printk(KERN_ERR, &mpt2sas_phy->phy->dev, 506 "phy_number(%d)\n", mpt2sas_phy->phy_id); 507 if (mpt2sas_phy->phy_id == phy_num) 508 mpt2sas_port_duplicate = mpt2sas_port; 509 } 510 } 511 512 if (!mpt2sas_port_duplicate) 513 return; 514 515 dev_printk(KERN_ERR, &mpt2sas_port_duplicate->port->dev, 516 "deleting duplicate device at sas_addr(0x%016llx), phy(%d)!!!!\n", 517 (unsigned long long) 518 mpt2sas_port_duplicate->remote_identify.sas_address, phy_num); 519 ioc->logging_level |= MPT_DEBUG_TRANSPORT; 520 mpt2sas_transport_port_remove(ioc, 521 mpt2sas_port_duplicate->remote_identify.sas_address, 522 sas_node->sas_address); 523 ioc->logging_level &= ~MPT_DEBUG_TRANSPORT; 524} 525 526/** 527 * _transport_sanity_check - sanity check when adding a new port 528 * @ioc: per adapter object 529 * @sas_node: sas node object (either expander or sas host) 530 * @sas_address: sas address of device being added 531 * 532 * See the explanation above from _transport_delete_duplicate_port 533 */ 534static void 535_transport_sanity_check(struct MPT2SAS_ADAPTER *ioc, struct _sas_node *sas_node, 536 u64 sas_address) 537{ 538 int i; 539 540 for (i = 0; i < sas_node->num_phys; i++) 541 if (sas_node->phy[i].remote_identify.sas_address == sas_address) 542 if (sas_node->phy[i].phy_belongs_to_port) 543 _transport_delete_duplicate_port(ioc, sas_node, 544 sas_address, i); 545} 546 547/** 548 * mpt2sas_transport_port_add - insert port to the list 549 * @ioc: per adapter object 550 * @handle: handle of attached device 551 * @sas_address: sas address of parent expander or sas host 552 * Context: This function will acquire ioc->sas_node_lock. 553 * 554 * Adding new port object to the sas_node->sas_port_list. 555 * 556 * Returns mpt2sas_port. 557 */ 558struct _sas_port * 559mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, u16 handle, 560 u64 sas_address) 561{ 562 struct _sas_phy *mpt2sas_phy, *next; 563 struct _sas_port *mpt2sas_port; 564 unsigned long flags; 565 struct _sas_node *sas_node; 566 struct sas_rphy *rphy; 567 int i; 568 struct sas_port *port; 569 570 mpt2sas_port = kzalloc(sizeof(struct _sas_port), 571 GFP_KERNEL); 572 if (!mpt2sas_port) { 573 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 574 ioc->name, __FILE__, __LINE__, __func__); 575 return NULL; 576 } 577 578 INIT_LIST_HEAD(&mpt2sas_port->port_list); 579 INIT_LIST_HEAD(&mpt2sas_port->phy_list); 580 spin_lock_irqsave(&ioc->sas_node_lock, flags); 581 sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address); 582 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 583 584 if (!sas_node) { 585 printk(MPT2SAS_ERR_FMT "%s: Could not find " 586 "parent sas_address(0x%016llx)!\n", ioc->name, 587 __func__, (unsigned long long)sas_address); 588 goto out_fail; 589 } 590 591 if ((_transport_set_identify(ioc, handle, 592 &mpt2sas_port->remote_identify))) { 593 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 594 ioc->name, __FILE__, __LINE__, __func__); 595 goto out_fail; 596 } 597 598 if (mpt2sas_port->remote_identify.device_type == SAS_PHY_UNUSED) { 599 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 600 ioc->name, __FILE__, __LINE__, __func__); 601 goto out_fail; 602 } 603 604 _transport_sanity_check(ioc, sas_node, 605 mpt2sas_port->remote_identify.sas_address); 606 607 for (i = 0; i < sas_node->num_phys; i++) { 608 if (sas_node->phy[i].remote_identify.sas_address != 609 mpt2sas_port->remote_identify.sas_address) 610 continue; 611 list_add_tail(&sas_node->phy[i].port_siblings, 612 &mpt2sas_port->phy_list); 613 mpt2sas_port->num_phys++; 614 } 615 616 if (!mpt2sas_port->num_phys) { 617 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 618 ioc->name, __FILE__, __LINE__, __func__); 619 goto out_fail; 620 } 621 622 port = sas_port_alloc_num(sas_node->parent_dev); 623 if ((sas_port_add(port))) { 624 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 625 ioc->name, __FILE__, __LINE__, __func__); 626 goto out_fail; 627 } 628 629 list_for_each_entry(mpt2sas_phy, &mpt2sas_port->phy_list, 630 port_siblings) { 631 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) 632 dev_printk(KERN_INFO, &port->dev, "add: handle(0x%04x)" 633 ", sas_addr(0x%016llx), phy(%d)\n", handle, 634 (unsigned long long) 635 mpt2sas_port->remote_identify.sas_address, 636 mpt2sas_phy->phy_id); 637 sas_port_add_phy(port, mpt2sas_phy->phy); 638 mpt2sas_phy->phy_belongs_to_port = 1; 639 } 640 641 mpt2sas_port->port = port; 642 if (mpt2sas_port->remote_identify.device_type == SAS_END_DEVICE) 643 rphy = sas_end_device_alloc(port); 644 else 645 rphy = sas_expander_alloc(port, 646 mpt2sas_port->remote_identify.device_type); 647 648 rphy->identify = mpt2sas_port->remote_identify; 649 if ((sas_rphy_add(rphy))) { 650 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 651 ioc->name, __FILE__, __LINE__, __func__); 652 } 653 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) 654 dev_printk(KERN_INFO, &rphy->dev, "add: handle(0x%04x), " 655 "sas_addr(0x%016llx)\n", handle, 656 (unsigned long long) 657 mpt2sas_port->remote_identify.sas_address); 658 mpt2sas_port->rphy = rphy; 659 spin_lock_irqsave(&ioc->sas_node_lock, flags); 660 list_add_tail(&mpt2sas_port->port_list, &sas_node->sas_port_list); 661 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 662 663 /* fill in report manufacture */ 664 if (mpt2sas_port->remote_identify.device_type == 665 MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER || 666 mpt2sas_port->remote_identify.device_type == 667 MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER) 668 _transport_expander_report_manufacture(ioc, 669 mpt2sas_port->remote_identify.sas_address, 670 rphy_to_expander_device(rphy)); 671 672 return mpt2sas_port; 673 674 out_fail: 675 list_for_each_entry_safe(mpt2sas_phy, next, &mpt2sas_port->phy_list, 676 port_siblings) 677 list_del(&mpt2sas_phy->port_siblings); 678 kfree(mpt2sas_port); 679 return NULL; 680} 681 682/** 683 * mpt2sas_transport_port_remove - remove port from the list 684 * @ioc: per adapter object 685 * @sas_address: sas address of attached device 686 * @sas_address_parent: sas address of parent expander or sas host 687 * Context: This function will acquire ioc->sas_node_lock. 688 * 689 * Removing object and freeing associated memory from the 690 * ioc->sas_port_list. 691 * 692 * Return nothing. 693 */ 694void 695mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, 696 u64 sas_address_parent) 697{ 698 int i; 699 unsigned long flags; 700 struct _sas_port *mpt2sas_port, *next; 701 struct _sas_node *sas_node; 702 u8 found = 0; 703 struct _sas_phy *mpt2sas_phy, *next_phy; 704 705 spin_lock_irqsave(&ioc->sas_node_lock, flags); 706 sas_node = _transport_sas_node_find_by_sas_address(ioc, 707 sas_address_parent); 708 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 709 if (!sas_node) 710 return; 711 list_for_each_entry_safe(mpt2sas_port, next, &sas_node->sas_port_list, 712 port_list) { 713 if (mpt2sas_port->remote_identify.sas_address != sas_address) 714 continue; 715 found = 1; 716 list_del(&mpt2sas_port->port_list); 717 goto out; 718 } 719 out: 720 if (!found) 721 return; 722 723 for (i = 0; i < sas_node->num_phys; i++) { 724 if (sas_node->phy[i].remote_identify.sas_address == sas_address) 725 memset(&sas_node->phy[i].remote_identify, 0 , 726 sizeof(struct sas_identify)); 727 } 728 729 list_for_each_entry_safe(mpt2sas_phy, next_phy, 730 &mpt2sas_port->phy_list, port_siblings) { 731 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) 732 dev_printk(KERN_INFO, &mpt2sas_port->port->dev, 733 "remove: sas_addr(0x%016llx), phy(%d)\n", 734 (unsigned long long) 735 mpt2sas_port->remote_identify.sas_address, 736 mpt2sas_phy->phy_id); 737 mpt2sas_phy->phy_belongs_to_port = 0; 738 sas_port_delete_phy(mpt2sas_port->port, mpt2sas_phy->phy); 739 list_del(&mpt2sas_phy->port_siblings); 740 } 741 sas_port_delete(mpt2sas_port->port); 742 kfree(mpt2sas_port); 743} 744 745/** 746 * mpt2sas_transport_add_host_phy - report sas_host phy to transport 747 * @ioc: per adapter object 748 * @mpt2sas_phy: mpt2sas per phy object 749 * @phy_pg0: sas phy page 0 750 * @parent_dev: parent device class object 751 * 752 * Returns 0 for success, non-zero for failure. 753 */ 754int 755mpt2sas_transport_add_host_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy 756 *mpt2sas_phy, Mpi2SasPhyPage0_t phy_pg0, struct device *parent_dev) 757{ 758 struct sas_phy *phy; 759 int phy_index = mpt2sas_phy->phy_id; 760 761 762 INIT_LIST_HEAD(&mpt2sas_phy->port_siblings); 763 phy = sas_phy_alloc(parent_dev, phy_index); 764 if (!phy) { 765 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 766 ioc->name, __FILE__, __LINE__, __func__); 767 return -1; 768 } 769 if ((_transport_set_identify(ioc, mpt2sas_phy->handle, 770 &mpt2sas_phy->identify))) { 771 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 772 ioc->name, __FILE__, __LINE__, __func__); 773 return -1; 774 } 775 phy->identify = mpt2sas_phy->identify; 776 mpt2sas_phy->attached_handle = le16_to_cpu(phy_pg0.AttachedDevHandle); 777 if (mpt2sas_phy->attached_handle) 778 _transport_set_identify(ioc, mpt2sas_phy->attached_handle, 779 &mpt2sas_phy->remote_identify); 780 phy->identify.phy_identifier = mpt2sas_phy->phy_id; 781 phy->negotiated_linkrate = _transport_convert_phy_link_rate( 782 phy_pg0.NegotiatedLinkRate & MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL); 783 phy->minimum_linkrate_hw = _transport_convert_phy_link_rate( 784 phy_pg0.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK); 785 phy->maximum_linkrate_hw = _transport_convert_phy_link_rate( 786 phy_pg0.HwLinkRate >> 4); 787 phy->minimum_linkrate = _transport_convert_phy_link_rate( 788 phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK); 789 phy->maximum_linkrate = _transport_convert_phy_link_rate( 790 phy_pg0.ProgrammedLinkRate >> 4); 791 792 if ((sas_phy_add(phy))) { 793 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 794 ioc->name, __FILE__, __LINE__, __func__); 795 sas_phy_free(phy); 796 return -1; 797 } 798 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) 799 dev_printk(KERN_INFO, &phy->dev, 800 "add: handle(0x%04x), sas_addr(0x%016llx)\n" 801 "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n", 802 mpt2sas_phy->handle, (unsigned long long) 803 mpt2sas_phy->identify.sas_address, 804 mpt2sas_phy->attached_handle, 805 (unsigned long long) 806 mpt2sas_phy->remote_identify.sas_address); 807 mpt2sas_phy->phy = phy; 808 return 0; 809} 810 811 812/** 813 * mpt2sas_transport_add_expander_phy - report expander phy to transport 814 * @ioc: per adapter object 815 * @mpt2sas_phy: mpt2sas per phy object 816 * @expander_pg1: expander page 1 817 * @parent_dev: parent device class object 818 * 819 * Returns 0 for success, non-zero for failure. 820 */ 821int 822mpt2sas_transport_add_expander_phy(struct MPT2SAS_ADAPTER *ioc, struct _sas_phy 823 *mpt2sas_phy, Mpi2ExpanderPage1_t expander_pg1, struct device *parent_dev) 824{ 825 struct sas_phy *phy; 826 int phy_index = mpt2sas_phy->phy_id; 827 828 INIT_LIST_HEAD(&mpt2sas_phy->port_siblings); 829 phy = sas_phy_alloc(parent_dev, phy_index); 830 if (!phy) { 831 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 832 ioc->name, __FILE__, __LINE__, __func__); 833 return -1; 834 } 835 if ((_transport_set_identify(ioc, mpt2sas_phy->handle, 836 &mpt2sas_phy->identify))) { 837 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 838 ioc->name, __FILE__, __LINE__, __func__); 839 return -1; 840 } 841 phy->identify = mpt2sas_phy->identify; 842 mpt2sas_phy->attached_handle = 843 le16_to_cpu(expander_pg1.AttachedDevHandle); 844 if (mpt2sas_phy->attached_handle) 845 _transport_set_identify(ioc, mpt2sas_phy->attached_handle, 846 &mpt2sas_phy->remote_identify); 847 phy->identify.phy_identifier = mpt2sas_phy->phy_id; 848 phy->negotiated_linkrate = _transport_convert_phy_link_rate( 849 expander_pg1.NegotiatedLinkRate & 850 MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL); 851 phy->minimum_linkrate_hw = _transport_convert_phy_link_rate( 852 expander_pg1.HwLinkRate & MPI2_SAS_HWRATE_MIN_RATE_MASK); 853 phy->maximum_linkrate_hw = _transport_convert_phy_link_rate( 854 expander_pg1.HwLinkRate >> 4); 855 phy->minimum_linkrate = _transport_convert_phy_link_rate( 856 expander_pg1.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK); 857 phy->maximum_linkrate = _transport_convert_phy_link_rate( 858 expander_pg1.ProgrammedLinkRate >> 4); 859 860 if ((sas_phy_add(phy))) { 861 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 862 ioc->name, __FILE__, __LINE__, __func__); 863 sas_phy_free(phy); 864 return -1; 865 } 866 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) 867 dev_printk(KERN_INFO, &phy->dev, 868 "add: handle(0x%04x), sas_addr(0x%016llx)\n" 869 "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n", 870 mpt2sas_phy->handle, (unsigned long long) 871 mpt2sas_phy->identify.sas_address, 872 mpt2sas_phy->attached_handle, 873 (unsigned long long) 874 mpt2sas_phy->remote_identify.sas_address); 875 mpt2sas_phy->phy = phy; 876 return 0; 877} 878 879/** 880 * mpt2sas_transport_update_links - refreshing phy link changes 881 * @ioc: per adapter object 882 * @sas_address: sas address of parent expander or sas host 883 * @handle: attached device handle 884 * @phy_numberv: phy number 885 * @link_rate: new link rate 886 * 887 * Returns nothing. 888 */ 889void 890mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc, 891 u64 sas_address, u16 handle, u8 phy_number, u8 link_rate) 892{ 893 unsigned long flags; 894 struct _sas_node *sas_node; 895 struct _sas_phy *mpt2sas_phy; 896 897 if (ioc->shost_recovery || ioc->pci_error_recovery) 898 return; 899 900 spin_lock_irqsave(&ioc->sas_node_lock, flags); 901 sas_node = _transport_sas_node_find_by_sas_address(ioc, sas_address); 902 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 903 if (!sas_node) 904 return; 905 906 mpt2sas_phy = &sas_node->phy[phy_number]; 907 mpt2sas_phy->attached_handle = handle; 908 if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) 909 _transport_set_identify(ioc, handle, 910 &mpt2sas_phy->remote_identify); 911 else 912 memset(&mpt2sas_phy->remote_identify, 0 , sizeof(struct 913 sas_identify)); 914 915 if (mpt2sas_phy->phy) 916 mpt2sas_phy->phy->negotiated_linkrate = 917 _transport_convert_phy_link_rate(link_rate); 918 919 if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) 920 dev_printk(KERN_INFO, &mpt2sas_phy->phy->dev, 921 "refresh: parent sas_addr(0x%016llx),\n" 922 "\tlink_rate(0x%02x), phy(%d)\n" 923 "\tattached_handle(0x%04x), sas_addr(0x%016llx)\n", 924 (unsigned long long)sas_address, 925 link_rate, phy_number, handle, (unsigned long long) 926 mpt2sas_phy->remote_identify.sas_address); 927} 928 929static inline void * 930phy_to_ioc(struct sas_phy *phy) 931{ 932 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent); 933 return shost_priv(shost); 934} 935 936static inline void * 937rphy_to_ioc(struct sas_rphy *rphy) 938{ 939 struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent); 940 return shost_priv(shost); 941} 942 943 944/* report phy error log structure */ 945struct phy_error_log_request{ 946 u8 smp_frame_type; /* 0x40 */ 947 u8 function; /* 0x11 */ 948 u8 allocated_response_length; 949 u8 request_length; /* 02 */ 950 u8 reserved_1[5]; 951 u8 phy_identifier; 952 u8 reserved_2[2]; 953}; 954 955/* report phy error log reply structure */ 956struct phy_error_log_reply{ 957 u8 smp_frame_type; /* 0x41 */ 958 u8 function; /* 0x11 */ 959 u8 function_result; 960 u8 response_length; 961 u16 expander_change_count; 962 u8 reserved_1[3]; 963 u8 phy_identifier; 964 u8 reserved_2[2]; 965 u32 invalid_dword; 966 u32 running_disparity_error; 967 u32 loss_of_dword_sync; 968 u32 phy_reset_problem; 969}; 970 971/** 972 * _transport_get_expander_phy_error_log - return expander counters 973 * @ioc: per adapter object 974 * @phy: The sas phy object 975 * 976 * Returns 0 for success, non-zero for failure. 977 * 978 */ 979static int 980_transport_get_expander_phy_error_log(struct MPT2SAS_ADAPTER *ioc, 981 struct sas_phy *phy) 982{ 983 Mpi2SmpPassthroughRequest_t *mpi_request; 984 Mpi2SmpPassthroughReply_t *mpi_reply; 985 struct phy_error_log_request *phy_error_log_request; 986 struct phy_error_log_reply *phy_error_log_reply; 987 int rc; 988 u16 smid; 989 u32 ioc_state; 990 unsigned long timeleft; 991 void *psge; 992 u32 sgl_flags; 993 u8 issue_reset = 0; 994 void *data_out = NULL; 995 dma_addr_t data_out_dma; 996 u32 sz; 997 u64 *sas_address_le; 998 u16 wait_state_count; 999 1000 if (ioc->shost_recovery || ioc->pci_error_recovery) { 1001 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", 1002 __func__, ioc->name); 1003 return -EFAULT; 1004 } 1005 1006 mutex_lock(&ioc->transport_cmds.mutex); 1007 1008 if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) { 1009 printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n", 1010 ioc->name, __func__); 1011 rc = -EAGAIN; 1012 goto out; 1013 } 1014 ioc->transport_cmds.status = MPT2_CMD_PENDING; 1015 1016 wait_state_count = 0; 1017 ioc_state = mpt2sas_base_get_iocstate(ioc, 1); 1018 while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { 1019 if (wait_state_count++ == 10) { 1020 printk(MPT2SAS_ERR_FMT 1021 "%s: failed due to ioc not operational\n", 1022 ioc->name, __func__); 1023 rc = -EFAULT; 1024 goto out; 1025 } 1026 ssleep(1); 1027 ioc_state = mpt2sas_base_get_iocstate(ioc, 1); 1028 printk(MPT2SAS_INFO_FMT "%s: waiting for " 1029 "operational state(count=%d)\n", ioc->name, 1030 __func__, wait_state_count); 1031 } 1032 if (wait_state_count) 1033 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n", 1034 ioc->name, __func__); 1035 1036 smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx); 1037 if (!smid) { 1038 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 1039 ioc->name, __func__); 1040 rc = -EAGAIN; 1041 goto out; 1042 } 1043 1044 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); 1045 ioc->transport_cmds.smid = smid; 1046 1047 sz = sizeof(struct phy_error_log_request) + 1048 sizeof(struct phy_error_log_reply); 1049 data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma); 1050 if (!data_out) { 1051 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, 1052 __LINE__, __func__); 1053 rc = -ENOMEM; 1054 mpt2sas_base_free_smid(ioc, smid); 1055 goto out; 1056 } 1057 1058 rc = -EINVAL; 1059 memset(data_out, 0, sz); 1060 phy_error_log_request = data_out; 1061 phy_error_log_request->smp_frame_type = 0x40; 1062 phy_error_log_request->function = 0x11; 1063 phy_error_log_request->request_length = 2; 1064 phy_error_log_request->allocated_response_length = 0; 1065 phy_error_log_request->phy_identifier = phy->number; 1066 1067 memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); 1068 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; 1069 mpi_request->PhysicalPort = 0xFF; 1070 mpi_request->VF_ID = 0; /* TODO */ 1071 mpi_request->VP_ID = 0; 1072 sas_address_le = (u64 *)&mpi_request->SASAddress; 1073 *sas_address_le = cpu_to_le64(phy->identify.sas_address); 1074 mpi_request->RequestDataLength = 1075 cpu_to_le16(sizeof(struct phy_error_log_request)); 1076 psge = &mpi_request->SGL; 1077 1078 /* WRITE sgel first */ 1079 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 1080 MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC); 1081 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; 1082 ioc->base_add_sg_single(psge, sgl_flags | 1083 sizeof(struct phy_error_log_request), data_out_dma); 1084 1085 /* incr sgel */ 1086 psge += ioc->sge_size; 1087 1088 /* READ sgel last */ 1089 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 1090 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | 1091 MPI2_SGE_FLAGS_END_OF_LIST); 1092 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; 1093 ioc->base_add_sg_single(psge, sgl_flags | 1094 sizeof(struct phy_error_log_reply), data_out_dma + 1095 sizeof(struct phy_error_log_request)); 1096 1097 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_error_log - " 1098 "send to sas_addr(0x%016llx), phy(%d)\n", ioc->name, 1099 (unsigned long long)phy->identify.sas_address, phy->number)); 1100 mpt2sas_base_put_smid_default(ioc, smid); 1101 init_completion(&ioc->transport_cmds.done); 1102 timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done, 1103 10*HZ); 1104 1105 if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) { 1106 printk(MPT2SAS_ERR_FMT "%s: timeout\n", 1107 ioc->name, __func__); 1108 _debug_dump_mf(mpi_request, 1109 sizeof(Mpi2SmpPassthroughRequest_t)/4); 1110 if (!(ioc->transport_cmds.status & MPT2_CMD_RESET)) 1111 issue_reset = 1; 1112 goto issue_host_reset; 1113 } 1114 1115 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_error_log - " 1116 "complete\n", ioc->name)); 1117 1118 if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) { 1119 1120 mpi_reply = ioc->transport_cmds.reply; 1121 1122 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT 1123 "phy_error_log - reply data transfer size(%d)\n", 1124 ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength))); 1125 1126 if (le16_to_cpu(mpi_reply->ResponseDataLength) != 1127 sizeof(struct phy_error_log_reply)) 1128 goto out; 1129 1130 phy_error_log_reply = data_out + 1131 sizeof(struct phy_error_log_request); 1132 1133 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT 1134 "phy_error_log - function_result(%d)\n", 1135 ioc->name, phy_error_log_reply->function_result)); 1136 1137 phy->invalid_dword_count = 1138 be32_to_cpu(phy_error_log_reply->invalid_dword); 1139 phy->running_disparity_error_count = 1140 be32_to_cpu(phy_error_log_reply->running_disparity_error); 1141 phy->loss_of_dword_sync_count = 1142 be32_to_cpu(phy_error_log_reply->loss_of_dword_sync); 1143 phy->phy_reset_problem_count = 1144 be32_to_cpu(phy_error_log_reply->phy_reset_problem); 1145 rc = 0; 1146 } else 1147 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT 1148 "phy_error_log - no reply\n", ioc->name)); 1149 1150 issue_host_reset: 1151 if (issue_reset) 1152 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, 1153 FORCE_BIG_HAMMER); 1154 out: 1155 ioc->transport_cmds.status = MPT2_CMD_NOT_USED; 1156 if (data_out) 1157 pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma); 1158 1159 mutex_unlock(&ioc->transport_cmds.mutex); 1160 return rc; 1161} 1162 1163/** 1164 * _transport_get_linkerrors - return phy counters for both hba and expanders 1165 * @phy: The sas phy object 1166 * 1167 * Returns 0 for success, non-zero for failure. 1168 * 1169 */ 1170static int 1171_transport_get_linkerrors(struct sas_phy *phy) 1172{ 1173 struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy); 1174 unsigned long flags; 1175 Mpi2ConfigReply_t mpi_reply; 1176 Mpi2SasPhyPage1_t phy_pg1; 1177 1178 spin_lock_irqsave(&ioc->sas_node_lock, flags); 1179 if (_transport_sas_node_find_by_sas_address(ioc, 1180 phy->identify.sas_address) == NULL) { 1181 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 1182 return -EINVAL; 1183 } 1184 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 1185 1186 if (phy->identify.sas_address != ioc->sas_hba.sas_address) 1187 return _transport_get_expander_phy_error_log(ioc, phy); 1188 1189 /* get hba phy error logs */ 1190 if ((mpt2sas_config_get_phy_pg1(ioc, &mpi_reply, &phy_pg1, 1191 phy->number))) { 1192 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1193 ioc->name, __FILE__, __LINE__, __func__); 1194 return -ENXIO; 1195 } 1196 1197 if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) 1198 printk(MPT2SAS_INFO_FMT "phy(%d), ioc_status" 1199 "(0x%04x), loginfo(0x%08x)\n", ioc->name, 1200 phy->number, le16_to_cpu(mpi_reply.IOCStatus), 1201 le32_to_cpu(mpi_reply.IOCLogInfo)); 1202 1203 phy->invalid_dword_count = le32_to_cpu(phy_pg1.InvalidDwordCount); 1204 phy->running_disparity_error_count = 1205 le32_to_cpu(phy_pg1.RunningDisparityErrorCount); 1206 phy->loss_of_dword_sync_count = 1207 le32_to_cpu(phy_pg1.LossDwordSynchCount); 1208 phy->phy_reset_problem_count = 1209 le32_to_cpu(phy_pg1.PhyResetProblemCount); 1210 return 0; 1211} 1212 1213/** 1214 * _transport_get_enclosure_identifier - 1215 * @phy: The sas phy object 1216 * 1217 * Obtain the enclosure logical id for an expander. 1218 * Returns 0 for success, non-zero for failure. 1219 */ 1220static int 1221_transport_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier) 1222{ 1223 struct MPT2SAS_ADAPTER *ioc = rphy_to_ioc(rphy); 1224 struct _sas_device *sas_device; 1225 unsigned long flags; 1226 1227 spin_lock_irqsave(&ioc->sas_device_lock, flags); 1228 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, 1229 rphy->identify.sas_address); 1230 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 1231 1232 if (!sas_device) 1233 return -ENXIO; 1234 1235 *identifier = sas_device->enclosure_logical_id; 1236 return 0; 1237} 1238 1239/** 1240 * _transport_get_bay_identifier - 1241 * @phy: The sas phy object 1242 * 1243 * Returns the slot id for a device that resides inside an enclosure. 1244 */ 1245static int 1246_transport_get_bay_identifier(struct sas_rphy *rphy) 1247{ 1248 struct MPT2SAS_ADAPTER *ioc = rphy_to_ioc(rphy); 1249 struct _sas_device *sas_device; 1250 unsigned long flags; 1251 1252 spin_lock_irqsave(&ioc->sas_device_lock, flags); 1253 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, 1254 rphy->identify.sas_address); 1255 spin_unlock_irqrestore(&ioc->sas_device_lock, flags); 1256 1257 if (!sas_device) 1258 return -ENXIO; 1259 1260 return sas_device->slot; 1261} 1262 1263/* phy control request structure */ 1264struct phy_control_request{ 1265 u8 smp_frame_type; /* 0x40 */ 1266 u8 function; /* 0x91 */ 1267 u8 allocated_response_length; 1268 u8 request_length; /* 0x09 */ 1269 u16 expander_change_count; 1270 u8 reserved_1[3]; 1271 u8 phy_identifier; 1272 u8 phy_operation; 1273 u8 reserved_2[13]; 1274 u64 attached_device_name; 1275 u8 programmed_min_physical_link_rate; 1276 u8 programmed_max_physical_link_rate; 1277 u8 reserved_3[6]; 1278}; 1279 1280/* phy control reply structure */ 1281struct phy_control_reply{ 1282 u8 smp_frame_type; /* 0x41 */ 1283 u8 function; /* 0x11 */ 1284 u8 function_result; 1285 u8 response_length; 1286}; 1287 1288#define SMP_PHY_CONTROL_LINK_RESET (0x01) 1289#define SMP_PHY_CONTROL_HARD_RESET (0x02) 1290#define SMP_PHY_CONTROL_DISABLE (0x03) 1291 1292/** 1293 * _transport_expander_phy_control - expander phy control 1294 * @ioc: per adapter object 1295 * @phy: The sas phy object 1296 * 1297 * Returns 0 for success, non-zero for failure. 1298 * 1299 */ 1300static int 1301_transport_expander_phy_control(struct MPT2SAS_ADAPTER *ioc, 1302 struct sas_phy *phy, u8 phy_operation) 1303{ 1304 Mpi2SmpPassthroughRequest_t *mpi_request; 1305 Mpi2SmpPassthroughReply_t *mpi_reply; 1306 struct phy_control_request *phy_control_request; 1307 struct phy_control_reply *phy_control_reply; 1308 int rc; 1309 u16 smid; 1310 u32 ioc_state; 1311 unsigned long timeleft; 1312 void *psge; 1313 u32 sgl_flags; 1314 u8 issue_reset = 0; 1315 void *data_out = NULL; 1316 dma_addr_t data_out_dma; 1317 u32 sz; 1318 u64 *sas_address_le; 1319 u16 wait_state_count; 1320 1321 if (ioc->shost_recovery) { 1322 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", 1323 __func__, ioc->name); 1324 return -EFAULT; 1325 } 1326 1327 mutex_lock(&ioc->transport_cmds.mutex); 1328 1329 if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) { 1330 printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n", 1331 ioc->name, __func__); 1332 rc = -EAGAIN; 1333 goto out; 1334 } 1335 ioc->transport_cmds.status = MPT2_CMD_PENDING; 1336 1337 wait_state_count = 0; 1338 ioc_state = mpt2sas_base_get_iocstate(ioc, 1); 1339 while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { 1340 if (wait_state_count++ == 10) { 1341 printk(MPT2SAS_ERR_FMT 1342 "%s: failed due to ioc not operational\n", 1343 ioc->name, __func__); 1344 rc = -EFAULT; 1345 goto out; 1346 } 1347 ssleep(1); 1348 ioc_state = mpt2sas_base_get_iocstate(ioc, 1); 1349 printk(MPT2SAS_INFO_FMT "%s: waiting for " 1350 "operational state(count=%d)\n", ioc->name, 1351 __func__, wait_state_count); 1352 } 1353 if (wait_state_count) 1354 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n", 1355 ioc->name, __func__); 1356 1357 smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx); 1358 if (!smid) { 1359 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 1360 ioc->name, __func__); 1361 rc = -EAGAIN; 1362 goto out; 1363 } 1364 1365 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); 1366 ioc->transport_cmds.smid = smid; 1367 1368 sz = sizeof(struct phy_control_request) + 1369 sizeof(struct phy_control_reply); 1370 data_out = pci_alloc_consistent(ioc->pdev, sz, &data_out_dma); 1371 if (!data_out) { 1372 printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, 1373 __LINE__, __func__); 1374 rc = -ENOMEM; 1375 mpt2sas_base_free_smid(ioc, smid); 1376 goto out; 1377 } 1378 1379 rc = -EINVAL; 1380 memset(data_out, 0, sz); 1381 phy_control_request = data_out; 1382 phy_control_request->smp_frame_type = 0x40; 1383 phy_control_request->function = 0x91; 1384 phy_control_request->request_length = 9; 1385 phy_control_request->allocated_response_length = 0; 1386 phy_control_request->phy_identifier = phy->number; 1387 phy_control_request->phy_operation = phy_operation; 1388 phy_control_request->programmed_min_physical_link_rate = 1389 phy->minimum_linkrate << 4; 1390 phy_control_request->programmed_max_physical_link_rate = 1391 phy->maximum_linkrate << 4; 1392 1393 memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); 1394 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; 1395 mpi_request->PhysicalPort = 0xFF; 1396 mpi_request->VF_ID = 0; /* TODO */ 1397 mpi_request->VP_ID = 0; 1398 sas_address_le = (u64 *)&mpi_request->SASAddress; 1399 *sas_address_le = cpu_to_le64(phy->identify.sas_address); 1400 mpi_request->RequestDataLength = 1401 cpu_to_le16(sizeof(struct phy_error_log_request)); 1402 psge = &mpi_request->SGL; 1403 1404 /* WRITE sgel first */ 1405 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 1406 MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC); 1407 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; 1408 ioc->base_add_sg_single(psge, sgl_flags | 1409 sizeof(struct phy_control_request), data_out_dma); 1410 1411 /* incr sgel */ 1412 psge += ioc->sge_size; 1413 1414 /* READ sgel last */ 1415 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 1416 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | 1417 MPI2_SGE_FLAGS_END_OF_LIST); 1418 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; 1419 ioc->base_add_sg_single(psge, sgl_flags | 1420 sizeof(struct phy_control_reply), data_out_dma + 1421 sizeof(struct phy_control_request)); 1422 1423 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_control - " 1424 "send to sas_addr(0x%016llx), phy(%d), opcode(%d)\n", ioc->name, 1425 (unsigned long long)phy->identify.sas_address, phy->number, 1426 phy_operation)); 1427 mpt2sas_base_put_smid_default(ioc, smid); 1428 init_completion(&ioc->transport_cmds.done); 1429 timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done, 1430 10*HZ); 1431 1432 if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) { 1433 printk(MPT2SAS_ERR_FMT "%s: timeout\n", 1434 ioc->name, __func__); 1435 _debug_dump_mf(mpi_request, 1436 sizeof(Mpi2SmpPassthroughRequest_t)/4); 1437 if (!(ioc->transport_cmds.status & MPT2_CMD_RESET)) 1438 issue_reset = 1; 1439 goto issue_host_reset; 1440 } 1441 1442 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "phy_control - " 1443 "complete\n", ioc->name)); 1444 1445 if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) { 1446 1447 mpi_reply = ioc->transport_cmds.reply; 1448 1449 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT 1450 "phy_control - reply data transfer size(%d)\n", 1451 ioc->name, le16_to_cpu(mpi_reply->ResponseDataLength))); 1452 1453 if (le16_to_cpu(mpi_reply->ResponseDataLength) != 1454 sizeof(struct phy_control_reply)) 1455 goto out; 1456 1457 phy_control_reply = data_out + 1458 sizeof(struct phy_control_request); 1459 1460 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT 1461 "phy_control - function_result(%d)\n", 1462 ioc->name, phy_control_reply->function_result)); 1463 1464 rc = 0; 1465 } else 1466 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT 1467 "phy_control - no reply\n", ioc->name)); 1468 1469 issue_host_reset: 1470 if (issue_reset) 1471 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, 1472 FORCE_BIG_HAMMER); 1473 out: 1474 ioc->transport_cmds.status = MPT2_CMD_NOT_USED; 1475 if (data_out) 1476 pci_free_consistent(ioc->pdev, sz, data_out, data_out_dma); 1477 1478 mutex_unlock(&ioc->transport_cmds.mutex); 1479 return rc; 1480} 1481 1482/** 1483 * _transport_phy_reset - 1484 * @phy: The sas phy object 1485 * @hard_reset: 1486 * 1487 * Returns 0 for success, non-zero for failure. 1488 */ 1489static int 1490_transport_phy_reset(struct sas_phy *phy, int hard_reset) 1491{ 1492 struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy); 1493 Mpi2SasIoUnitControlReply_t mpi_reply; 1494 Mpi2SasIoUnitControlRequest_t mpi_request; 1495 unsigned long flags; 1496 1497 spin_lock_irqsave(&ioc->sas_node_lock, flags); 1498 if (_transport_sas_node_find_by_sas_address(ioc, 1499 phy->identify.sas_address) == NULL) { 1500 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 1501 return -EINVAL; 1502 } 1503 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 1504 1505 /* handle expander phys */ 1506 if (phy->identify.sas_address != ioc->sas_hba.sas_address) 1507 return _transport_expander_phy_control(ioc, phy, 1508 (hard_reset == 1) ? SMP_PHY_CONTROL_HARD_RESET : 1509 SMP_PHY_CONTROL_LINK_RESET); 1510 1511 /* handle hba phys */ 1512 memset(&mpi_request, 0, sizeof(Mpi2SasIoUnitControlReply_t)); 1513 mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; 1514 mpi_request.Operation = hard_reset ? 1515 MPI2_SAS_OP_PHY_HARD_RESET : MPI2_SAS_OP_PHY_LINK_RESET; 1516 mpi_request.PhyNum = phy->number; 1517 1518 if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply, &mpi_request))) { 1519 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1520 ioc->name, __FILE__, __LINE__, __func__); 1521 return -ENXIO; 1522 } 1523 1524 if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) 1525 printk(MPT2SAS_INFO_FMT "phy(%d), ioc_status" 1526 "(0x%04x), loginfo(0x%08x)\n", ioc->name, 1527 phy->number, le16_to_cpu(mpi_reply.IOCStatus), 1528 le32_to_cpu(mpi_reply.IOCLogInfo)); 1529 1530 return 0; 1531} 1532 1533/** 1534 * _transport_phy_enable - enable/disable phys 1535 * @phy: The sas phy object 1536 * @enable: enable phy when true 1537 * 1538 * Only support sas_host direct attached phys. 1539 * Returns 0 for success, non-zero for failure. 1540 */ 1541static int 1542_transport_phy_enable(struct sas_phy *phy, int enable) 1543{ 1544 struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy); 1545 Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL; 1546 Mpi2ConfigReply_t mpi_reply; 1547 u16 ioc_status; 1548 u16 sz; 1549 int rc = 0; 1550 unsigned long flags; 1551 1552 spin_lock_irqsave(&ioc->sas_node_lock, flags); 1553 if (_transport_sas_node_find_by_sas_address(ioc, 1554 phy->identify.sas_address) == NULL) { 1555 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 1556 return -EINVAL; 1557 } 1558 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 1559 1560 /* handle expander phys */ 1561 if (phy->identify.sas_address != ioc->sas_hba.sas_address) 1562 return _transport_expander_phy_control(ioc, phy, 1563 (enable == 1) ? SMP_PHY_CONTROL_LINK_RESET : 1564 SMP_PHY_CONTROL_DISABLE); 1565 1566 /* handle hba phys */ 1567 1568 /* sas_iounit page 1 */ 1569 sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys * 1570 sizeof(Mpi2SasIOUnit1PhyData_t)); 1571 sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL); 1572 if (!sas_iounit_pg1) { 1573 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1574 ioc->name, __FILE__, __LINE__, __func__); 1575 rc = -ENOMEM; 1576 goto out; 1577 } 1578 if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply, 1579 sas_iounit_pg1, sz))) { 1580 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1581 ioc->name, __FILE__, __LINE__, __func__); 1582 rc = -ENXIO; 1583 goto out; 1584 } 1585 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 1586 MPI2_IOCSTATUS_MASK; 1587 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 1588 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1589 ioc->name, __FILE__, __LINE__, __func__); 1590 rc = -EIO; 1591 goto out; 1592 } 1593 1594 if (enable) 1595 sas_iounit_pg1->PhyData[phy->number].PhyFlags 1596 &= ~MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE; 1597 else 1598 sas_iounit_pg1->PhyData[phy->number].PhyFlags 1599 |= MPI2_SASIOUNIT1_PHYFLAGS_PHY_DISABLE; 1600 1601 mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, sz); 1602 1603 /* link reset */ 1604 if (enable) 1605 _transport_phy_reset(phy, 0); 1606 1607 out: 1608 kfree(sas_iounit_pg1); 1609 return rc; 1610} 1611 1612/** 1613 * _transport_phy_speed - set phy min/max link rates 1614 * @phy: The sas phy object 1615 * @rates: rates defined in sas_phy_linkrates 1616 * 1617 * Only support sas_host direct attached phys. 1618 * Returns 0 for success, non-zero for failure. 1619 */ 1620static int 1621_transport_phy_speed(struct sas_phy *phy, struct sas_phy_linkrates *rates) 1622{ 1623 struct MPT2SAS_ADAPTER *ioc = phy_to_ioc(phy); 1624 Mpi2SasIOUnitPage1_t *sas_iounit_pg1 = NULL; 1625 Mpi2SasPhyPage0_t phy_pg0; 1626 Mpi2ConfigReply_t mpi_reply; 1627 u16 ioc_status; 1628 u16 sz; 1629 int i; 1630 int rc = 0; 1631 unsigned long flags; 1632 1633 spin_lock_irqsave(&ioc->sas_node_lock, flags); 1634 if (_transport_sas_node_find_by_sas_address(ioc, 1635 phy->identify.sas_address) == NULL) { 1636 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 1637 return -EINVAL; 1638 } 1639 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 1640 1641 if (!rates->minimum_linkrate) 1642 rates->minimum_linkrate = phy->minimum_linkrate; 1643 else if (rates->minimum_linkrate < phy->minimum_linkrate_hw) 1644 rates->minimum_linkrate = phy->minimum_linkrate_hw; 1645 1646 if (!rates->maximum_linkrate) 1647 rates->maximum_linkrate = phy->maximum_linkrate; 1648 else if (rates->maximum_linkrate > phy->maximum_linkrate_hw) 1649 rates->maximum_linkrate = phy->maximum_linkrate_hw; 1650 1651 /* handle expander phys */ 1652 if (phy->identify.sas_address != ioc->sas_hba.sas_address) { 1653 phy->minimum_linkrate = rates->minimum_linkrate; 1654 phy->maximum_linkrate = rates->maximum_linkrate; 1655 return _transport_expander_phy_control(ioc, phy, 1656 SMP_PHY_CONTROL_LINK_RESET); 1657 } 1658 1659 /* handle hba phys */ 1660 1661 /* sas_iounit page 1 */ 1662 sz = offsetof(Mpi2SasIOUnitPage1_t, PhyData) + (ioc->sas_hba.num_phys * 1663 sizeof(Mpi2SasIOUnit1PhyData_t)); 1664 sas_iounit_pg1 = kzalloc(sz, GFP_KERNEL); 1665 if (!sas_iounit_pg1) { 1666 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1667 ioc->name, __FILE__, __LINE__, __func__); 1668 rc = -ENOMEM; 1669 goto out; 1670 } 1671 if ((mpt2sas_config_get_sas_iounit_pg1(ioc, &mpi_reply, 1672 sas_iounit_pg1, sz))) { 1673 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1674 ioc->name, __FILE__, __LINE__, __func__); 1675 rc = -ENXIO; 1676 goto out; 1677 } 1678 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 1679 MPI2_IOCSTATUS_MASK; 1680 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 1681 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1682 ioc->name, __FILE__, __LINE__, __func__); 1683 rc = -EIO; 1684 goto out; 1685 } 1686 1687 for (i = 0; i < ioc->sas_hba.num_phys; i++) { 1688 if (phy->number != i) { 1689 sas_iounit_pg1->PhyData[i].MaxMinLinkRate = 1690 (ioc->sas_hba.phy[i].phy->minimum_linkrate + 1691 (ioc->sas_hba.phy[i].phy->maximum_linkrate << 4)); 1692 } else { 1693 sas_iounit_pg1->PhyData[i].MaxMinLinkRate = 1694 (rates->minimum_linkrate + 1695 (rates->maximum_linkrate << 4)); 1696 } 1697 } 1698 1699 if (mpt2sas_config_set_sas_iounit_pg1(ioc, &mpi_reply, sas_iounit_pg1, 1700 sz)) { 1701 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 1702 ioc->name, __FILE__, __LINE__, __func__); 1703 rc = -ENXIO; 1704 goto out; 1705 } 1706 1707 /* link reset */ 1708 _transport_phy_reset(phy, 0); 1709 1710 /* read phy page 0, then update the rates in the sas transport phy */ 1711 if (!mpt2sas_config_get_phy_pg0(ioc, &mpi_reply, &phy_pg0, 1712 phy->number)) { 1713 phy->minimum_linkrate = _transport_convert_phy_link_rate( 1714 phy_pg0.ProgrammedLinkRate & MPI2_SAS_PRATE_MIN_RATE_MASK); 1715 phy->maximum_linkrate = _transport_convert_phy_link_rate( 1716 phy_pg0.ProgrammedLinkRate >> 4); 1717 phy->negotiated_linkrate = _transport_convert_phy_link_rate( 1718 phy_pg0.NegotiatedLinkRate & 1719 MPI2_SAS_NEG_LINK_RATE_MASK_PHYSICAL); 1720 } 1721 1722 out: 1723 kfree(sas_iounit_pg1); 1724 return rc; 1725} 1726 1727 1728/** 1729 * _transport_smp_handler - transport portal for smp passthru 1730 * @shost: shost object 1731 * @rphy: sas transport rphy object 1732 * @req: 1733 * 1734 * This used primarily for smp_utils. 1735 * Example: 1736 * smp_rep_general /sys/class/bsg/expander-5:0 1737 */ 1738static int 1739_transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, 1740 struct request *req) 1741{ 1742 struct MPT2SAS_ADAPTER *ioc = shost_priv(shost); 1743 Mpi2SmpPassthroughRequest_t *mpi_request; 1744 Mpi2SmpPassthroughReply_t *mpi_reply; 1745 int rc; 1746 u16 smid; 1747 u32 ioc_state; 1748 unsigned long timeleft; 1749 void *psge; 1750 u32 sgl_flags; 1751 u8 issue_reset = 0; 1752 dma_addr_t dma_addr_in = 0; 1753 dma_addr_t dma_addr_out = 0; 1754 u16 wait_state_count; 1755 struct request *rsp = req->next_rq; 1756 1757 if (!rsp) { 1758 printk(MPT2SAS_ERR_FMT "%s: the smp response space is " 1759 "missing\n", ioc->name, __func__); 1760 return -EINVAL; 1761 } 1762 1763 /* do we need to support multiple segments? */ 1764 if (req->bio->bi_vcnt > 1 || rsp->bio->bi_vcnt > 1) { 1765 printk(MPT2SAS_ERR_FMT "%s: multiple segments req %u %u, " 1766 "rsp %u %u\n", ioc->name, __func__, req->bio->bi_vcnt, 1767 blk_rq_bytes(req), rsp->bio->bi_vcnt, blk_rq_bytes(rsp)); 1768 return -EINVAL; 1769 } 1770 1771 if (ioc->shost_recovery) { 1772 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", 1773 __func__, ioc->name); 1774 return -EFAULT; 1775 } 1776 1777 rc = mutex_lock_interruptible(&ioc->transport_cmds.mutex); 1778 if (rc) 1779 return rc; 1780 1781 if (ioc->transport_cmds.status != MPT2_CMD_NOT_USED) { 1782 printk(MPT2SAS_ERR_FMT "%s: transport_cmds in use\n", ioc->name, 1783 __func__); 1784 rc = -EAGAIN; 1785 goto out; 1786 } 1787 ioc->transport_cmds.status = MPT2_CMD_PENDING; 1788 1789 wait_state_count = 0; 1790 ioc_state = mpt2sas_base_get_iocstate(ioc, 1); 1791 while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) { 1792 if (wait_state_count++ == 10) { 1793 printk(MPT2SAS_ERR_FMT 1794 "%s: failed due to ioc not operational\n", 1795 ioc->name, __func__); 1796 rc = -EFAULT; 1797 goto out; 1798 } 1799 ssleep(1); 1800 ioc_state = mpt2sas_base_get_iocstate(ioc, 1); 1801 printk(MPT2SAS_INFO_FMT "%s: waiting for " 1802 "operational state(count=%d)\n", ioc->name, 1803 __func__, wait_state_count); 1804 } 1805 if (wait_state_count) 1806 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n", 1807 ioc->name, __func__); 1808 1809 smid = mpt2sas_base_get_smid(ioc, ioc->transport_cb_idx); 1810 if (!smid) { 1811 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 1812 ioc->name, __func__); 1813 rc = -EAGAIN; 1814 goto out; 1815 } 1816 1817 rc = 0; 1818 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); 1819 ioc->transport_cmds.smid = smid; 1820 1821 memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); 1822 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; 1823 mpi_request->PhysicalPort = 0xFF; 1824 mpi_request->VF_ID = 0; /* TODO */ 1825 mpi_request->VP_ID = 0; 1826 *((u64 *)&mpi_request->SASAddress) = (rphy) ? 1827 cpu_to_le64(rphy->identify.sas_address) : 1828 cpu_to_le64(ioc->sas_hba.sas_address); 1829 mpi_request->RequestDataLength = cpu_to_le16(blk_rq_bytes(req) - 4); 1830 psge = &mpi_request->SGL; 1831 1832 /* WRITE sgel first */ 1833 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 1834 MPI2_SGE_FLAGS_END_OF_BUFFER | MPI2_SGE_FLAGS_HOST_TO_IOC); 1835 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; 1836 dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio), 1837 blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL); 1838 if (!dma_addr_out) { 1839 mpt2sas_base_free_smid(ioc, smid); 1840 goto unmap; 1841 } 1842 1843 ioc->base_add_sg_single(psge, sgl_flags | (blk_rq_bytes(req) - 4), 1844 dma_addr_out); 1845 1846 /* incr sgel */ 1847 psge += ioc->sge_size; 1848 1849 /* READ sgel last */ 1850 sgl_flags = (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 1851 MPI2_SGE_FLAGS_LAST_ELEMENT | MPI2_SGE_FLAGS_END_OF_BUFFER | 1852 MPI2_SGE_FLAGS_END_OF_LIST); 1853 sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT; 1854 dma_addr_in = pci_map_single(ioc->pdev, bio_data(rsp->bio), 1855 blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL); 1856 if (!dma_addr_in) { 1857 mpt2sas_base_free_smid(ioc, smid); 1858 goto unmap; 1859 } 1860 1861 ioc->base_add_sg_single(psge, sgl_flags | (blk_rq_bytes(rsp) + 4), 1862 dma_addr_in); 1863 1864 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "%s - " 1865 "sending smp request\n", ioc->name, __func__)); 1866 1867 mpt2sas_base_put_smid_default(ioc, smid); 1868 init_completion(&ioc->transport_cmds.done); 1869 timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done, 1870 10*HZ); 1871 1872 if (!(ioc->transport_cmds.status & MPT2_CMD_COMPLETE)) { 1873 printk(MPT2SAS_ERR_FMT "%s : timeout\n", 1874 __func__, ioc->name); 1875 _debug_dump_mf(mpi_request, 1876 sizeof(Mpi2SmpPassthroughRequest_t)/4); 1877 if (!(ioc->transport_cmds.status & MPT2_CMD_RESET)) 1878 issue_reset = 1; 1879 goto issue_host_reset; 1880 } 1881 1882 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT "%s - " 1883 "complete\n", ioc->name, __func__)); 1884 1885 if (ioc->transport_cmds.status & MPT2_CMD_REPLY_VALID) { 1886 1887 mpi_reply = ioc->transport_cmds.reply; 1888 1889 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT 1890 "%s - reply data transfer size(%d)\n", 1891 ioc->name, __func__, 1892 le16_to_cpu(mpi_reply->ResponseDataLength))); 1893 1894 memcpy(req->sense, mpi_reply, sizeof(*mpi_reply)); 1895 req->sense_len = sizeof(*mpi_reply); 1896 req->resid_len = 0; 1897 rsp->resid_len -= 1898 le16_to_cpu(mpi_reply->ResponseDataLength); 1899 } else { 1900 dtransportprintk(ioc, printk(MPT2SAS_INFO_FMT 1901 "%s - no reply\n", ioc->name, __func__)); 1902 rc = -ENXIO; 1903 } 1904 1905 issue_host_reset: 1906 if (issue_reset) { 1907 mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, 1908 FORCE_BIG_HAMMER); 1909 rc = -ETIMEDOUT; 1910 } 1911 1912 unmap: 1913 if (dma_addr_out) 1914 pci_unmap_single(ioc->pdev, dma_addr_out, blk_rq_bytes(req), 1915 PCI_DMA_BIDIRECTIONAL); 1916 if (dma_addr_in) 1917 pci_unmap_single(ioc->pdev, dma_addr_in, blk_rq_bytes(rsp), 1918 PCI_DMA_BIDIRECTIONAL); 1919 1920 out: 1921 ioc->transport_cmds.status = MPT2_CMD_NOT_USED; 1922 mutex_unlock(&ioc->transport_cmds.mutex); 1923 return rc; 1924} 1925 1926struct sas_function_template mpt2sas_transport_functions = { 1927 .get_linkerrors = _transport_get_linkerrors, 1928 .get_enclosure_identifier = _transport_get_enclosure_identifier, 1929 .get_bay_identifier = _transport_get_bay_identifier, 1930 .phy_reset = _transport_phy_reset, 1931 .phy_enable = _transport_phy_enable, 1932 .set_phy_speed = _transport_phy_speed, 1933 .smp_handler = _transport_smp_handler, 1934}; 1935 1936struct scsi_transport_template *mpt2sas_transport_template; 1937