1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2026 LeapIO Tech Inc. 4 * 5 * LeapRAID storage and RAID controller driver. 6 */ 7 #include <linux/module.h> 8 9 #include "leapraid_func.h" 10 11 static int poll_queues; 12 module_param(poll_queues, int, 0444); 13 MODULE_PARM_DESC(poll_queues, 14 "specifies the number of queues for io_uring poll mode."); 15 16 static int max_msix_vectors = LEAPRAID_INVALID_MSIX_VECTORS; 17 module_param(max_msix_vectors, int, 0444); 18 MODULE_PARM_DESC(max_msix_vectors, "max msix vectors"); 19 20 static void leapraid_remove_device(struct leapraid_adapter *adapter, 21 struct leapraid_sas_dev *sas_dev); 22 static void leapraid_set_led(struct leapraid_adapter *adapter, 23 struct leapraid_sas_dev *sas_dev, bool on); 24 static void leapraid_ublk_io_dev(struct leapraid_adapter *adapter, 25 u64 sas_address, 26 struct leapraid_card_port *port); 27 static void leapraid_clear_cached_boot_dev(struct leapraid_adapter *adapter, 28 void *dev, u32 chnl); 29 static int leapraid_make_adapter_available(struct leapraid_adapter *adapter); 30 static void leapraid_sync_irqs_for_cleanup(struct leapraid_adapter *adapter); 31 static int leapraid_fw_log_init(struct leapraid_adapter *adapter); 32 static bool leapraid_should_skip_poll_work(struct leapraid_adapter *adapter); 33 static int leapraid_make_adapter_ready(struct leapraid_adapter *adapter, 34 enum reset_type type); 35 36 static noinline bool leapraid_shost_in_recovery(struct Scsi_Host *shost) 37 { 38 enum scsi_host_state state; 39 40 state = READ_ONCE(shost->shost_state); 41 return state == SHOST_RECOVERY || 42 state == SHOST_CANCEL_RECOVERY || 43 state == SHOST_DEL_RECOVERY || 44 shost->tmf_in_progress; 45 } 46 47 static inline bool leapraid_is_end_dev(u32 dev_type) 48 { 49 return (dev_type & LEAPRAID_DEVTYP_END_DEV) && 50 ((dev_type & LEAPRAID_DEVTYP_SSP_TGT) || 51 (dev_type & LEAPRAID_DEVTYP_STP_TGT) || 52 (dev_type & LEAPRAID_DEVTYP_SATA_DEV)); 53 } 54 55 bool leapraid_pci_removed(struct leapraid_adapter *adapter) 56 { 57 struct pci_dev *pdev = adapter->pdev; 58 u32 vendor_id; 59 60 if (pci_bus_read_config_dword(pdev->bus, 61 pdev->devfn, 62 PCI_VENDOR_ID, 63 &vendor_id)) 64 return true; 65 66 return (vendor_id & LEAPRAID_PCI_VENDOR_ID_MASK) != 67 LEAPRAID_VENDOR_ID; 68 } 69 70 static bool leapraid_pci_active(struct leapraid_adapter *adapter) 71 { 72 return !(adapter->access_ctrl.pcie_recovering || 73 leapraid_pci_removed(adapter)); 74 } 75 76 void *leapraid_get_reply_vaddr(struct leapraid_adapter *adapter, u32 rep_paddr) 77 { 78 if (!rep_paddr) 79 return NULL; 80 81 return adapter->mem_desc.rep_msg + 82 (rep_paddr - (u32)adapter->mem_desc.rep_msg_dma); 83 } 84 85 void *leapraid_get_task_desc(struct leapraid_adapter *adapter, u16 taskid) 86 { 87 return adapter->mem_desc.task_desc + 88 taskid * LEAPRAID_REQUEST_SIZE; 89 } 90 91 void *leapraid_get_sense_buffer(struct leapraid_adapter *adapter, u16 taskid) 92 { 93 return adapter->mem_desc.sense_data + 94 (taskid - 1) * SCSI_SENSE_BUFFERSIZE; 95 } 96 97 __le32 leapraid_get_sense_buffer_dma(struct leapraid_adapter *adapter, 98 u16 taskid) 99 { 100 return cpu_to_le32(adapter->mem_desc.sense_data_dma + 101 ((taskid - 1) * SCSI_SENSE_BUFFERSIZE)); 102 } 103 104 void leapraid_mask_int(struct leapraid_adapter *adapter) 105 { 106 u32 reg; 107 108 adapter->mask_int = 1; 109 reg = leapraid_readl(&adapter->iomem_base->host_int_mask); 110 reg |= LEAPRAID_TO_SYS_DB_MASK + LEAPRAID_REPLY_INT_MASK + 111 LEAPRAID_RESET_IRQ_MASK; 112 writel(reg, &adapter->iomem_base->host_int_mask); 113 leapraid_readl(&adapter->iomem_base->host_int_mask); 114 } 115 116 void leapraid_unmask_int(struct leapraid_adapter *adapter) 117 { 118 u32 reg; 119 120 reg = leapraid_readl(&adapter->iomem_base->host_int_mask); 121 reg &= ~LEAPRAID_REPLY_INT_MASK; 122 writel(reg, &adapter->iomem_base->host_int_mask); 123 adapter->mask_int = 0; 124 } 125 126 static void leapraid_overheat_suspend(struct leapraid_adapter *adapter) 127 { 128 struct workqueue_struct *wq; 129 struct Scsi_Host *shost; 130 struct pci_dev *pdev; 131 132 if (!adapter) 133 return; 134 135 pdev = adapter->pdev; 136 shost = pci_get_drvdata(pdev); 137 if (!shost) { 138 dev_warn(&pdev->dev, 139 "Overheat suspend failed, invalid host or adapter\n"); 140 return; 141 } 142 143 wq = adapter->overheat_desc.fault_overheat_wq; 144 if (!wq) 145 return; 146 147 if (atomic_cmpxchg(&adapter->overheat_desc.thermal_alert, 0, 1)) 148 return; 149 150 queue_work(wq, &adapter->overheat_desc.fault_overheat_work); 151 } 152 153 static void leapraid_stop_adapter_on_fault(struct leapraid_adapter *adapter, 154 u32 db) 155 { 156 u32 adapter_state = db & LEAPRAID_DB_MASK; 157 bool fault_1 = false; 158 bool fault_2 = false; 159 160 fault_1 = adapter_state == LEAPRAID_DB_MASK; 161 fault_2 = adapter_state == LEAPRAID_DB_FAULT && 162 (db & LEAPRAID_DB_DATA_MASK) == LEAPRAID_DB_OVER_TEMPERATURE; 163 164 if (!fault_1 && !fault_2) 165 return; 166 167 if (fault_1) 168 dev_err(&adapter->pdev->dev, 169 "%s: Doorbell status 0xFFFF!\n", __func__); 170 else 171 dev_err(&adapter->pdev->dev, 172 "%s: Adapter overheating detected!\n", __func__); 173 174 leapraid_overheat_suspend(adapter); 175 } 176 177 u32 leapraid_get_adapter_state(struct leapraid_adapter *adapter) 178 { 179 u32 db; 180 u32 adapter_state; 181 182 db = leapraid_readl(&adapter->iomem_base->db); 183 adapter_state = db & LEAPRAID_DB_MASK; 184 leapraid_stop_adapter_on_fault(adapter, db); 185 return adapter_state; 186 } 187 188 static bool leapraid_wait_adapter_ready(struct leapraid_adapter *adapter) 189 { 190 u32 cur_state; 191 u32 cnt; 192 193 for (cnt = LEAPRAID_ADAPTER_READY_MAX_RETRY; cnt > 0; cnt--) { 194 cur_state = leapraid_get_adapter_state(adapter); 195 196 if (cur_state == LEAPRAID_DB_READY) 197 return true; 198 if (cur_state == LEAPRAID_DB_FAULT) 199 break; 200 usleep_range(LEAPRAID_ADAPTER_READY_SLEEP_MIN_US, 201 LEAPRAID_ADAPTER_READY_SLEEP_MAX_US); 202 } 203 204 return false; 205 } 206 207 static int leapraid_db_wait_int_host(struct leapraid_adapter *adapter) 208 { 209 u32 cnt; 210 211 for (cnt = LEAPRAID_DB_WAIT_MAX_RETRY; cnt > 0; cnt--) { 212 if (leapraid_readl(&adapter->iomem_base->host_int_status) & 213 LEAPRAID_ADAPTER2HOST_DB_STATUS) 214 return 0; 215 216 udelay(LEAPRAID_DB_WAIT_DELAY_US); 217 } 218 219 return -EFAULT; 220 } 221 222 static int leapraid_db_wait_ack_and_clear_int(struct leapraid_adapter *adapter) 223 { 224 u32 adapter_state; 225 u32 int_status; 226 u32 cnt; 227 228 for (cnt = LEAPRAID_ADAPTER_READY_MAX_RETRY; cnt > 0; cnt--) { 229 int_status = 230 leapraid_readl(&adapter->iomem_base->host_int_status); 231 232 if (int_status == 0xFFFFFFFF) 233 return -EFAULT; 234 235 if (!(int_status & LEAPRAID_HOST2ADAPTER_DB_STATUS)) 236 return 0; 237 238 if (int_status & LEAPRAID_ADAPTER2HOST_DB_STATUS) { 239 adapter_state = leapraid_get_adapter_state(adapter); 240 if (adapter_state == LEAPRAID_DB_FAULT) 241 return -EFAULT; 242 } 243 244 usleep_range(LEAPRAID_ADAPTER_READY_SLEEP_MIN_US, 245 LEAPRAID_ADAPTER_READY_SLEEP_MAX_US); 246 } 247 248 return -EFAULT; 249 } 250 251 static int leapraid_handshake_func(struct leapraid_adapter *adapter, 252 int req_bytes, u32 *req, 253 int rep_bytes, u16 *rep) 254 { 255 int failed, i; 256 257 if (leapraid_readl(&adapter->iomem_base->db) & LEAPRAID_DB_USED) { 258 dev_err(&adapter->pdev->dev, "doorbell used\n"); 259 return -EFAULT; 260 } 261 262 if (leapraid_readl(&adapter->iomem_base->host_int_status) & 263 LEAPRAID_ADAPTER2HOST_DB_STATUS) 264 writel(0, &adapter->iomem_base->host_int_status); 265 266 writel(((LEAPRAID_FUNC_HANDSHAKE << LEAPRAID_DB_FUNC_SHIFT) | 267 ((req_bytes / LEAPRAID_DWORDS_BYTE_SIZE) << 268 LEAPRAID_DB_ADD_DWORDS_SHIFT)), 269 &adapter->iomem_base->db); 270 271 if (leapraid_db_wait_int_host(adapter)) { 272 dev_err(&adapter->pdev->dev, "%d: Wait db interrupt timeout\n", 273 __LINE__); 274 return -EFAULT; 275 } 276 277 writel(0, &adapter->iomem_base->host_int_status); 278 279 if (leapraid_db_wait_ack_and_clear_int(adapter)) { 280 dev_err(&adapter->pdev->dev, "%d: Wait ack failure\n", 281 __LINE__); 282 return -EFAULT; 283 } 284 285 for (i = 0, failed = 0; 286 i < req_bytes / LEAPRAID_DWORDS_BYTE_SIZE && !failed; 287 i++) { 288 writel((u32)req[i], &adapter->iomem_base->db); 289 if (leapraid_db_wait_ack_and_clear_int(adapter)) 290 failed = 1; 291 } 292 if (failed) { 293 dev_err(&adapter->pdev->dev, "%d: Wait ack failure\n", 294 __LINE__); 295 return -EFAULT; 296 } 297 298 for (i = 0; i < rep_bytes / LEAPRAID_WORD_BYTE_SIZE; i++) { 299 if (leapraid_db_wait_int_host(adapter)) { 300 dev_err(&adapter->pdev->dev, 301 "%d: Wait db interrupt timeout\n", __LINE__); 302 return -EFAULT; 303 } 304 rep[i] = (u16)(leapraid_readl(&adapter->iomem_base->db) 305 & LEAPRAID_DB_DATA_MASK); 306 writel(0, &adapter->iomem_base->host_int_status); 307 } 308 309 if (leapraid_db_wait_int_host(adapter)) { 310 dev_err(&adapter->pdev->dev, "%d: Wait db interrupt timeout\n", 311 __LINE__); 312 return -EFAULT; 313 } 314 315 writel(0, &adapter->iomem_base->host_int_status); 316 317 return 0; 318 } 319 320 int leapraid_check_adapter_is_op(struct leapraid_adapter *adapter, int wait, 321 const char *caller) 322 { 323 int wait_count; 324 325 for (wait_count = wait; wait_count > 0; wait_count--) { 326 if (READ_ONCE(adapter->access_ctrl.host_removing)) { 327 dev_warn(&adapter->pdev->dev, 328 "%s: Host is removing\n", caller); 329 return -EFAULT; 330 } 331 332 if (leapraid_pci_removed(adapter)) { 333 dev_warn(&adapter->pdev->dev, 334 "%s: PCI device removed\n", __func__); 335 return -EFAULT; 336 } 337 338 if (leapraid_get_adapter_state(adapter) == 339 LEAPRAID_DB_OPERATIONAL) 340 return 0; 341 342 dev_dbg(&adapter->pdev->dev, 343 "%s: Wait for adapter to become op status(cnt=%d)\n", 344 caller, wait - wait_count); 345 346 ssleep(1); 347 } 348 349 dev_err(&adapter->pdev->dev, 350 "%s: Adapter failed to become op state, last state=%d\n", 351 caller, leapraid_get_adapter_state(adapter)); 352 353 return -EFAULT; 354 } 355 356 struct leapraid_io_req_tracker *leapraid_get_io_tracker_from_taskid( 357 struct leapraid_adapter *adapter, u16 taskid) 358 { 359 struct scsi_cmnd *scmd; 360 361 if (WARN_ON(!taskid)) 362 return NULL; 363 364 if (WARN_ON(taskid > adapter->shost->can_queue)) 365 return NULL; 366 367 scmd = leapraid_get_scmd_from_taskid(adapter, taskid); 368 if (scmd) 369 return scsi_cmd_priv(scmd); 370 371 return NULL; 372 } 373 374 static u8 leapraid_get_cb_idx(struct leapraid_adapter *adapter, u16 taskid) 375 { 376 struct leapraid_driver_cmd *sp_cmd; 377 u8 cb_idx = 0xFF; 378 379 if (WARN_ON(!taskid)) 380 return cb_idx; 381 382 list_for_each_entry(sp_cmd, &adapter->driver_cmds.special_cmd_list, 383 list) 384 if (taskid == sp_cmd->taskid || 385 taskid == sp_cmd->hp_taskid || 386 taskid == sp_cmd->inter_taskid) 387 return sp_cmd->cb_idx; 388 389 WARN_ON(cb_idx == 0xFF); 390 return cb_idx; 391 } 392 393 struct scsi_cmnd *leapraid_get_scmd_from_taskid( 394 struct leapraid_adapter *adapter, 395 u16 taskid) 396 { 397 struct leapraid_scsiio_req *leap_mpi_req; 398 struct leapraid_io_req_tracker *st; 399 struct scsi_cmnd *scmd; 400 u32 uniq_tag; 401 402 if (taskid <= 0 || taskid > adapter->shost->can_queue) 403 return NULL; 404 405 uniq_tag = adapter->mem_desc.taskid_to_uniq_tag[taskid - 1] << 406 BLK_MQ_UNIQUE_TAG_BITS | (taskid - 1); 407 leap_mpi_req = leapraid_get_task_desc(adapter, taskid); 408 if (!leap_mpi_req->dev_hdl) 409 return NULL; 410 411 scmd = scsi_host_find_tag(adapter->shost, uniq_tag); 412 if (scmd) { 413 st = scsi_cmd_priv(scmd); 414 if (st && st->taskid == taskid) 415 return scmd; 416 } 417 418 return NULL; 419 } 420 421 u16 leapraid_alloc_scsiio_taskid(struct leapraid_adapter *adapter, 422 struct scsi_cmnd *scmd) 423 { 424 struct leapraid_io_req_tracker *request; 425 u16 taskid; 426 u32 tag = scsi_cmd_to_rq(scmd)->tag; 427 u32 unique_tag; 428 429 unique_tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmd)); 430 tag = blk_mq_unique_tag_to_tag(unique_tag); 431 adapter->mem_desc.taskid_to_uniq_tag[tag] = 432 blk_mq_unique_tag_to_hwq(unique_tag); 433 434 request = scsi_cmd_priv(scmd); 435 taskid = tag + 1; 436 request->taskid = taskid; 437 request->scmd = scmd; 438 return taskid; 439 } 440 441 static void leapraid_check_pending_io(struct leapraid_adapter *adapter) 442 { 443 if (adapter->access_ctrl.shost_recovering && 444 adapter->reset_desc.pending_io_cnt) { 445 if (adapter->reset_desc.pending_io_cnt == 1) 446 wake_up(&adapter->reset_desc.reset_wait_queue); 447 adapter->reset_desc.pending_io_cnt--; 448 } 449 } 450 451 static void leapraid_clear_io_tracker( 452 struct leapraid_adapter *adapter, 453 struct leapraid_io_req_tracker *io_tracker) 454 { 455 if (!io_tracker) 456 return; 457 458 if (WARN_ON(io_tracker->taskid == 0)) 459 return; 460 461 io_tracker->scmd = NULL; 462 } 463 464 static bool leapraid_is_fixed_taskid(struct leapraid_adapter *adapter, 465 u16 taskid) 466 { 467 struct leapraid_driver_cmds *driver_cmds = &adapter->driver_cmds; 468 469 return (taskid == driver_cmds->ctl_cmd.taskid || 470 taskid == driver_cmds->tm_cmd.hp_taskid || 471 taskid == driver_cmds->ctl_cmd.hp_taskid || 472 taskid == driver_cmds->scan_dev_cmd.inter_taskid || 473 taskid == driver_cmds->transport_cmd.inter_taskid || 474 taskid == driver_cmds->cfg_op_cmd.inter_taskid || 475 taskid == driver_cmds->enc_cmd.inter_taskid || 476 taskid == driver_cmds->notify_event_cmd.inter_taskid); 477 } 478 479 void leapraid_free_taskid(struct leapraid_adapter *adapter, u16 taskid) 480 { 481 struct leapraid_io_req_tracker *io_tracker; 482 void *task_desc; 483 484 if (leapraid_is_fixed_taskid(adapter, taskid)) 485 return; 486 487 if (taskid <= adapter->shost->can_queue) { 488 io_tracker = leapraid_get_io_tracker_from_taskid(adapter, 489 taskid); 490 if (!io_tracker) { 491 leapraid_check_pending_io(adapter); 492 return; 493 } 494 495 task_desc = leapraid_get_task_desc(adapter, taskid); 496 memset(task_desc, 0, LEAPRAID_REQUEST_SIZE); 497 leapraid_clear_io_tracker(adapter, io_tracker); 498 leapraid_check_pending_io(adapter); 499 adapter->mem_desc.taskid_to_uniq_tag[taskid - 1] = 0xFFFF; 500 } 501 } 502 503 static u8 leapraid_get_msix_idx(struct leapraid_adapter *adapter, 504 struct scsi_cmnd *scmd) 505 { 506 if (scmd && adapter->shost->nr_hw_queues > 1) { 507 u32 tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmd)); 508 509 return blk_mq_unique_tag_to_hwq(tag); 510 } 511 return adapter->notification_desc.msix_cpu_map[raw_smp_processor_id()]; 512 } 513 514 static u8 leapraid_get_and_set_msix_idx_from_taskid( 515 struct leapraid_adapter *adapter, u16 taskid) 516 { 517 struct leapraid_io_req_tracker *io_tracker = NULL; 518 519 if (taskid <= adapter->shost->can_queue) 520 io_tracker = leapraid_get_io_tracker_from_taskid(adapter, 521 taskid); 522 523 if (!io_tracker) 524 return leapraid_get_msix_idx(adapter, NULL); 525 526 io_tracker->msix_io = leapraid_get_msix_idx(adapter, io_tracker->scmd); 527 528 return io_tracker->msix_io; 529 } 530 531 void leapraid_fire_scsi_io(struct leapraid_adapter *adapter, u16 taskid, 532 u16 handle) 533 { 534 struct leapraid_atomic_req_desc desc; 535 536 desc.flg = LEAPRAID_REQ_DESC_FLG_SCSI_IO; 537 desc.msix_idx = leapraid_get_and_set_msix_idx_from_taskid(adapter, 538 taskid); 539 desc.taskid = cpu_to_le16(taskid); 540 writel((__force u32)cpu_to_le32(*((u32 *)&desc)), 541 &adapter->iomem_base->atomic_req_desc_post); 542 } 543 544 void leapraid_fire_hpr_task(struct leapraid_adapter *adapter, u16 taskid, 545 u16 msix_task) 546 { 547 struct leapraid_atomic_req_desc desc; 548 549 desc.flg = LEAPRAID_REQ_DESC_FLG_HPR; 550 desc.msix_idx = msix_task; 551 desc.taskid = cpu_to_le16(taskid); 552 writel((__force u32)cpu_to_le32(*((u32 *)&desc)), 553 &adapter->iomem_base->atomic_req_desc_post); 554 } 555 556 void leapraid_fire_task(struct leapraid_adapter *adapter, u16 taskid) 557 { 558 struct leapraid_atomic_req_desc desc; 559 560 desc.flg = LEAPRAID_REQ_DESC_FLG_DFLT_TYPE; 561 desc.msix_idx = leapraid_get_and_set_msix_idx_from_taskid(adapter, 562 taskid); 563 desc.taskid = cpu_to_le16(taskid); 564 writel((__force u32)cpu_to_le32(*((u32 *)&desc)), 565 &adapter->iomem_base->atomic_req_desc_post); 566 } 567 568 void leapraid_clean_active_scsi_cmds(struct leapraid_adapter *adapter) 569 { 570 struct leapraid_io_req_tracker *io_tracker; 571 struct scsi_cmnd *scmd; 572 void *task_desc; 573 u16 taskid; 574 575 leapraid_sync_irqs_for_cleanup(adapter); 576 577 for (taskid = 1; taskid <= adapter->shost->can_queue; taskid++) { 578 scmd = leapraid_get_scmd_from_taskid(adapter, taskid); 579 if (!scmd) 580 continue; 581 582 io_tracker = scsi_cmd_priv(scmd); 583 if (io_tracker && io_tracker->taskid == 0) 584 continue; 585 586 scsi_dma_unmap(scmd); 587 task_desc = leapraid_get_task_desc(adapter, taskid); 588 memset(task_desc, 0, LEAPRAID_REQUEST_SIZE); 589 leapraid_clear_io_tracker(adapter, io_tracker); 590 if (!leapraid_pci_active(adapter) || 591 adapter->reset_desc.adapter_reset_results != 0 || 592 atomic_read(&adapter->overheat_desc.thermal_alert) || 593 adapter->access_ctrl.host_removing) 594 scmd->result = DID_NO_CONNECT << 16; 595 else 596 scmd->result = DID_RESET << LEAPRAID_SCSI_HOST_SHIFT; 597 scsi_done(scmd); 598 } 599 } 600 601 static void leapraid_clean_active_driver_cmd(struct leapraid_driver_cmd *cmd) 602 { 603 if (cmd->status & LEAPRAID_CMD_PENDING) { 604 cmd->status |= LEAPRAID_CMD_RESET; 605 complete(&cmd->done); 606 } 607 } 608 609 static void leapraid_clean_active_driver_cmds(struct leapraid_adapter *adapter) 610 { 611 struct leapraid_driver_cmds *driver_cmds; 612 613 driver_cmds = &adapter->driver_cmds; 614 leapraid_clean_active_driver_cmd(&driver_cmds->tm_cmd); 615 leapraid_clean_active_driver_cmd(&driver_cmds->transport_cmd); 616 leapraid_clean_active_driver_cmd(&driver_cmds->enc_cmd); 617 leapraid_clean_active_driver_cmd(&driver_cmds->notify_event_cmd); 618 leapraid_clean_active_driver_cmd(&driver_cmds->cfg_op_cmd); 619 leapraid_clean_active_driver_cmd(&driver_cmds->ctl_cmd); 620 621 if (driver_cmds->scan_dev_cmd.status & LEAPRAID_CMD_PENDING) { 622 adapter->scan_dev_desc.scan_dev_failed = 1; 623 driver_cmds->scan_dev_cmd.status |= LEAPRAID_CMD_RESET; 624 if (adapter->scan_dev_desc.driver_loading) { 625 adapter->scan_dev_desc.scan_start_failed = 626 LEAPRAID_ADAPTER_STATUS_INTERNAL_ERROR; 627 adapter->scan_dev_desc.scan_start = 0; 628 } else { 629 complete(&driver_cmds->scan_dev_cmd.done); 630 } 631 } 632 } 633 634 static void leapraid_clean_active_cmds(struct leapraid_adapter *adapter) 635 { 636 leapraid_clean_active_driver_cmds(adapter); 637 leapraid_clean_active_fw_evt(adapter); 638 leapraid_clean_active_scsi_cmds(adapter); 639 } 640 641 static void leapraid_tgt_not_responding(struct leapraid_adapter *adapter, 642 u16 hdl) 643 { 644 struct leapraid_starget_priv *starget_priv = NULL; 645 struct leapraid_sas_dev *sas_dev; 646 unsigned long flags = 0; 647 u32 adapter_state; 648 649 if (adapter->access_ctrl.pcie_recovering) 650 return; 651 652 adapter_state = leapraid_get_adapter_state(adapter); 653 if (adapter_state != LEAPRAID_DB_OPERATIONAL) 654 return; 655 656 if (!hdl || hdl > adapter->adapter_attr.features.max_dev_handle || 657 test_bit(hdl, adapter->dev_topo.pd_hdls)) 658 return; 659 660 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 661 sas_dev = leapraid_hold_lock_get_sas_dev_by_hdl(adapter, hdl); 662 if (sas_dev && sas_dev->starget && sas_dev->starget->hostdata) { 663 starget_priv = sas_dev->starget->hostdata; 664 starget_priv->deleted = 1; 665 } 666 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 667 668 if (starget_priv) 669 starget_priv->hdl = LEAPRAID_INVALID_DEV_HANDLE; 670 671 if (sas_dev) 672 leapraid_sdev_put(sas_dev); 673 } 674 675 static void leapraid_tgt_rst_send(struct leapraid_adapter *adapter, u16 hdl) 676 { 677 struct leapraid_starget_priv *starget_priv = NULL; 678 struct leapraid_sas_dev *sas_dev; 679 struct leapraid_card_port *port; 680 u64 sas_address; 681 unsigned long flags; 682 u32 adapter_state; 683 684 if (adapter->access_ctrl.pcie_recovering) 685 return; 686 687 adapter_state = leapraid_get_adapter_state(adapter); 688 if (adapter_state != LEAPRAID_DB_OPERATIONAL) 689 return; 690 691 if (!hdl || hdl > adapter->adapter_attr.features.max_dev_handle || 692 test_bit(hdl, adapter->dev_topo.pd_hdls)) 693 return; 694 695 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 696 sas_dev = leapraid_hold_lock_get_sas_dev_by_hdl(adapter, hdl); 697 if (sas_dev && sas_dev->starget && sas_dev->starget->hostdata) { 698 starget_priv = sas_dev->starget->hostdata; 699 starget_priv->deleted = 1; 700 sas_address = sas_dev->sas_addr; 701 port = sas_dev->card_port; 702 } 703 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 704 705 if (starget_priv) { 706 leapraid_ublk_io_dev(adapter, sas_address, port); 707 starget_priv->hdl = LEAPRAID_INVALID_DEV_HANDLE; 708 } 709 if (sas_dev) 710 leapraid_sdev_put(sas_dev); 711 } 712 713 static inline void leapraid_single_mpi_sg_append( 714 struct leapraid_adapter *adapter, 715 void *sge, 716 u32 flag_and_len, 717 dma_addr_t dma_addr) 718 { 719 if (adapter->adapter_attr.use_32_dma_mask) { 720 struct leapraid_sge_simple32 *sge32 = sge; 721 722 sge32->flg_and_len = 723 cpu_to_le32(flag_and_len | 724 (LEAPRAID_SGE_FLG_32 | 725 LEAPRAID_SGE_FLG_SYSTEM_ADDR) << 726 LEAPRAID_SGE_FLG_SHIFT); 727 sge32->addr = cpu_to_le32(dma_addr); 728 } else { 729 struct leapraid_sge_simple64 *sge64 = sge; 730 731 sge64->flg_and_len = 732 cpu_to_le32(flag_and_len | 733 (LEAPRAID_SGE_FLG_64 | 734 LEAPRAID_SGE_FLG_SYSTEM_ADDR) << 735 LEAPRAID_SGE_FLG_SHIFT); 736 sge64->addr = cpu_to_le64(dma_addr); 737 } 738 } 739 740 static inline void leapraid_single_ieee_sg_append(void *sge, u8 flag, 741 u8 next_chain_offset, 742 u32 len, 743 dma_addr_t dma_addr) 744 { 745 struct leapraid_chain64_ieee_sg *ieee_sg = sge; 746 747 ieee_sg->flg = flag; 748 ieee_sg->next_chain_offset = next_chain_offset; 749 ieee_sg->len = cpu_to_le32(len); 750 ieee_sg->addr = cpu_to_le64(dma_addr); 751 } 752 753 static void leapraid_build_nodata_mpi_sg(struct leapraid_adapter *adapter, 754 void *sge) 755 { 756 leapraid_single_mpi_sg_append(adapter, 757 sge, 758 (LEAPRAID_SGE_FLG_LAST_ONE | 759 LEAPRAID_SGE_FLG_EOB | 760 LEAPRAID_SGE_FLG_EOL | 761 LEAPRAID_SGE_FLG_SIMPLE_ONE) << 762 LEAPRAID_SGE_FLG_SHIFT, 763 LEAPRAID_SGE_NO_DATA_ADDR); 764 } 765 766 void leapraid_build_mpi_sg(struct leapraid_adapter *adapter, void *sge, 767 dma_addr_t h2c_dma_addr, size_t h2c_size, 768 dma_addr_t c2h_dma_addr, size_t c2h_size) 769 { 770 if (h2c_size && !c2h_size) { 771 leapraid_single_mpi_sg_append(adapter, 772 sge, 773 ((LEAPRAID_SGE_FLG_SIMPLE_ONE | 774 LEAPRAID_SGE_FLG_LAST_ONE | 775 LEAPRAID_SGE_FLG_EOB | 776 LEAPRAID_SGE_FLG_EOL | 777 LEAPRAID_SGE_FLG_H2C) << 778 LEAPRAID_SGE_FLG_SHIFT) | 779 h2c_size, 780 h2c_dma_addr); 781 } else if (!h2c_size && c2h_size) { 782 leapraid_single_mpi_sg_append(adapter, 783 sge, 784 ((LEAPRAID_SGE_FLG_SIMPLE_ONE | 785 LEAPRAID_SGE_FLG_LAST_ONE | 786 LEAPRAID_SGE_FLG_EOB | 787 LEAPRAID_SGE_FLG_EOL) << 788 LEAPRAID_SGE_FLG_SHIFT) | 789 c2h_size, 790 c2h_dma_addr); 791 } else if (h2c_size && c2h_size) { 792 leapraid_single_mpi_sg_append(adapter, 793 sge, 794 ((LEAPRAID_SGE_FLG_SIMPLE_ONE | 795 LEAPRAID_SGE_FLG_EOB | 796 LEAPRAID_SGE_FLG_H2C) << 797 LEAPRAID_SGE_FLG_SHIFT) | 798 h2c_size, 799 h2c_dma_addr); 800 if (adapter->adapter_attr.use_32_dma_mask) 801 sge += sizeof(struct leapraid_sge_simple32); 802 else 803 sge += sizeof(struct leapraid_sge_simple64); 804 leapraid_single_mpi_sg_append(adapter, 805 sge, 806 ((LEAPRAID_SGE_FLG_SIMPLE_ONE | 807 LEAPRAID_SGE_FLG_LAST_ONE | 808 LEAPRAID_SGE_FLG_EOB | 809 LEAPRAID_SGE_FLG_EOL) << 810 LEAPRAID_SGE_FLG_SHIFT) | 811 c2h_size, 812 c2h_dma_addr); 813 } else { 814 leapraid_build_nodata_mpi_sg(adapter, sge); 815 } 816 } 817 818 void leapraid_build_ieee_nodata_sg(struct leapraid_adapter *adapter, void *sge) 819 { 820 leapraid_single_ieee_sg_append(sge, 821 (LEAPRAID_IEEE_SGE_FLG_SIMPLE_ONE | 822 LEAPRAID_IEEE_SGE_FLG_SYSTEM_ADDR | 823 LEAPRAID_IEEE_SGE_FLG_EOL), 824 0, 825 0, 826 LEAPRAID_SGE_NO_DATA_ADDR); 827 } 828 829 int leapraid_build_scmd_ieee_sg(struct leapraid_adapter *adapter, 830 struct scsi_cmnd *scmd, u16 taskid) 831 { 832 struct leapraid_scsiio_req *scsiio_req; 833 struct leapraid_io_req_tracker *io_tracker; 834 struct scatterlist *scmd_sg_cur; 835 int sg_entries_left; 836 void *sg_entry_cur; 837 void *host_chain; 838 dma_addr_t host_chain_dma; 839 u8 host_chain_cursor; 840 u32 sg_entries_in_cur_seg; 841 u32 chain_offset_in_cur_seg; 842 u32 chain_len_in_cur_seg; 843 844 io_tracker = scsi_cmd_priv(scmd); 845 scsiio_req = leapraid_get_task_desc(adapter, taskid); 846 scmd_sg_cur = scsi_sglist(scmd); 847 sg_entries_left = scsi_dma_map(scmd); 848 if (sg_entries_left < 0) 849 return -ENOMEM; 850 sg_entry_cur = &scsiio_req->sgl; 851 if (sg_entries_left <= LEAPRAID_SGL_INLINE_THRESHOLD) 852 goto fill_last_seg; 853 854 scsiio_req->chain_offset = LEAPRAID_CHAIN_OFFSET_DWORDS; 855 leapraid_single_ieee_sg_append(sg_entry_cur, 856 LEAPRAID_IEEE_SGE_FLG_SIMPLE_ONE | 857 LEAPRAID_IEEE_SGE_FLG_SYSTEM_ADDR, 858 0, sg_dma_len(scmd_sg_cur), 859 sg_dma_address(scmd_sg_cur)); 860 scmd_sg_cur = sg_next(scmd_sg_cur); 861 sg_entry_cur += LEAPRAID_IEEE_SGE64_ENTRY_SIZE; 862 sg_entries_left--; 863 864 host_chain_cursor = 0; 865 host_chain = io_tracker->chain + 866 host_chain_cursor * LEAPRAID_CHAIN_SEG_SIZE; 867 host_chain_dma = io_tracker->chain_dma + 868 host_chain_cursor * LEAPRAID_CHAIN_SEG_SIZE; 869 host_chain_cursor += 1; 870 for (;;) { 871 sg_entries_in_cur_seg = 872 (sg_entries_left <= LEAPRAID_MAX_SGES_IN_CHAIN) ? 873 sg_entries_left : LEAPRAID_MAX_SGES_IN_CHAIN; 874 chain_offset_in_cur_seg = 875 (sg_entries_left == (int)sg_entries_in_cur_seg) ? 876 0 : sg_entries_in_cur_seg; 877 chain_len_in_cur_seg = sg_entries_in_cur_seg * 878 LEAPRAID_IEEE_SGE64_ENTRY_SIZE; 879 if (chain_offset_in_cur_seg) 880 chain_len_in_cur_seg += LEAPRAID_IEEE_SGE64_ENTRY_SIZE; 881 882 leapraid_single_ieee_sg_append( 883 sg_entry_cur, 884 LEAPRAID_IEEE_SGE_FLG_CHAIN_ONE | 885 LEAPRAID_IEEE_SGE_FLG_SYSTEM_ADDR, 886 chain_offset_in_cur_seg, chain_len_in_cur_seg, 887 host_chain_dma); 888 sg_entry_cur = host_chain; 889 if (!chain_offset_in_cur_seg) 890 goto fill_last_seg; 891 892 while (sg_entries_in_cur_seg) { 893 leapraid_single_ieee_sg_append( 894 sg_entry_cur, 895 LEAPRAID_IEEE_SGE_FLG_SIMPLE_ONE | 896 LEAPRAID_IEEE_SGE_FLG_SYSTEM_ADDR, 897 0, sg_dma_len(scmd_sg_cur), 898 sg_dma_address(scmd_sg_cur)); 899 scmd_sg_cur = sg_next(scmd_sg_cur); 900 sg_entry_cur += LEAPRAID_IEEE_SGE64_ENTRY_SIZE; 901 sg_entries_left--; 902 sg_entries_in_cur_seg--; 903 } 904 host_chain = io_tracker->chain + 905 host_chain_cursor * LEAPRAID_CHAIN_SEG_SIZE; 906 host_chain_dma = io_tracker->chain_dma + 907 host_chain_cursor * LEAPRAID_CHAIN_SEG_SIZE; 908 host_chain_cursor += 1; 909 } 910 911 fill_last_seg: 912 while (sg_entries_left > 0) { 913 u32 flags = LEAPRAID_IEEE_SGE_FLG_SIMPLE_ONE | 914 LEAPRAID_IEEE_SGE_FLG_SYSTEM_ADDR; 915 if (sg_entries_left == 1) 916 flags |= LEAPRAID_IEEE_SGE_FLG_EOL; 917 leapraid_single_ieee_sg_append(sg_entry_cur, flags, 918 0, sg_dma_len(scmd_sg_cur), 919 sg_dma_address(scmd_sg_cur)); 920 scmd_sg_cur = sg_next(scmd_sg_cur); 921 sg_entry_cur += LEAPRAID_IEEE_SGE64_ENTRY_SIZE; 922 sg_entries_left--; 923 } 924 return 0; 925 } 926 927 void leapraid_build_ieee_sg(struct leapraid_adapter *adapter, void *sge, 928 dma_addr_t h2c_dma_addr, size_t h2c_size, 929 dma_addr_t c2h_dma_addr, size_t c2h_size) 930 { 931 u32 base_flag; 932 u32 flag; 933 934 base_flag = LEAPRAID_IEEE_SGE_FLG_SIMPLE_ONE | 935 LEAPRAID_IEEE_SGE_FLG_SYSTEM_ADDR; 936 937 if (h2c_size && !c2h_size) { 938 flag = base_flag | LEAPRAID_IEEE_SGE_FLG_EOL; 939 940 leapraid_single_ieee_sg_append(sge, 941 flag, 942 0, 943 h2c_size, 944 h2c_dma_addr); 945 } else if (!h2c_size && c2h_size) { 946 flag = base_flag | LEAPRAID_IEEE_SGE_FLG_EOL; 947 948 leapraid_single_ieee_sg_append(sge, 949 flag, 950 0, 951 c2h_size, 952 c2h_dma_addr); 953 } else if (h2c_size && c2h_size) { 954 leapraid_single_ieee_sg_append(sge, 955 base_flag, 956 0, 957 h2c_size, 958 h2c_dma_addr); 959 sge += LEAPRAID_IEEE_SGE64_ENTRY_SIZE; 960 961 flag = base_flag | LEAPRAID_IEEE_SGE_FLG_EOL; 962 leapraid_single_ieee_sg_append(sge, 963 flag, 964 0, 965 c2h_size, 966 c2h_dma_addr); 967 } else { 968 leapraid_build_ieee_nodata_sg(adapter, sge); 969 } 970 } 971 972 struct leapraid_sas_dev *leapraid_hold_lock_get_sas_dev_from_tgt( 973 struct leapraid_adapter *adapter, 974 struct leapraid_starget_priv *tgt_priv) 975 { 976 assert_spin_locked(&adapter->dev_topo.sas_dev_lock); 977 if (tgt_priv->sas_dev) 978 leapraid_sdev_get(tgt_priv->sas_dev); 979 980 return tgt_priv->sas_dev; 981 } 982 983 struct leapraid_sas_dev *leapraid_get_sas_dev_from_tgt( 984 struct leapraid_adapter *adapter, 985 struct leapraid_starget_priv *tgt_priv) 986 { 987 struct leapraid_sas_dev *sas_dev; 988 unsigned long flags; 989 990 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 991 sas_dev = leapraid_hold_lock_get_sas_dev_from_tgt(adapter, tgt_priv); 992 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 993 return sas_dev; 994 } 995 996 static struct leapraid_card_port *leapraid_get_port_by_id( 997 struct leapraid_adapter *adapter, 998 u8 port_id, bool skip_dirty) 999 { 1000 struct leapraid_card_port *port; 1001 struct leapraid_card_port *dirty_port = NULL; 1002 1003 if (!adapter->adapter_attr.enable_mp) 1004 port_id = LEAPRAID_DISABLE_MP_PORT_ID; 1005 1006 list_for_each_entry(port, &adapter->dev_topo.card_port_list, list) { 1007 if (port->port_id != port_id) 1008 continue; 1009 1010 if (!(port->flg & LEAPRAID_CARD_PORT_FLG_DIRTY)) 1011 return port; 1012 1013 if (skip_dirty && !dirty_port) 1014 dirty_port = port; 1015 } 1016 1017 if (dirty_port) 1018 return dirty_port; 1019 1020 if (unlikely(!adapter->adapter_attr.enable_mp)) { 1021 port = kzalloc_obj(*port, GFP_ATOMIC); 1022 if (!port) { 1023 dev_warn(&adapter->pdev->dev, 1024 "%s: Failed to alloc port\n", __func__); 1025 return NULL; 1026 } 1027 1028 port->port_id = LEAPRAID_DISABLE_MP_PORT_ID; 1029 list_add_tail(&port->list, &adapter->dev_topo.card_port_list); 1030 return port; 1031 } 1032 1033 return NULL; 1034 } 1035 1036 struct leapraid_vphy *leapraid_get_vphy_by_phy(struct leapraid_card_port *port, 1037 u32 phy_seq_num) 1038 { 1039 struct leapraid_vphy *vphy; 1040 1041 if (!port || !port->vphys_mask) 1042 return NULL; 1043 1044 list_for_each_entry(vphy, &port->vphys_list, list) { 1045 if (vphy->phy_mask & BIT(phy_seq_num)) 1046 return vphy; 1047 } 1048 1049 return NULL; 1050 } 1051 1052 struct leapraid_sas_dev *leapraid_hold_lock_get_sas_dev_by_addr_and_rphy( 1053 struct leapraid_adapter *adapter, 1054 u64 sas_address, 1055 struct sas_rphy *rphy) 1056 { 1057 struct leapraid_sas_dev *sas_dev; 1058 1059 assert_spin_locked(&adapter->dev_topo.sas_dev_lock); 1060 list_for_each_entry(sas_dev, &adapter->dev_topo.sas_dev_list, list) 1061 if (sas_dev->sas_addr == sas_address && 1062 sas_dev->rphy == rphy) { 1063 leapraid_sdev_get(sas_dev); 1064 return sas_dev; 1065 } 1066 1067 list_for_each_entry(sas_dev, &adapter->dev_topo.sas_dev_init_list, 1068 list) 1069 if (sas_dev->sas_addr == sas_address && 1070 sas_dev->rphy == rphy) { 1071 leapraid_sdev_get(sas_dev); 1072 return sas_dev; 1073 } 1074 1075 return NULL; 1076 } 1077 1078 struct leapraid_sas_dev *leapraid_hold_lock_get_sas_dev_by_addr( 1079 struct leapraid_adapter *adapter, 1080 u64 sas_address, struct leapraid_card_port *port) 1081 { 1082 struct leapraid_sas_dev *sas_dev; 1083 1084 if (!port) { 1085 dev_warn(&adapter->pdev->dev, "%s: Invalid port\n", __func__); 1086 return NULL; 1087 } 1088 1089 assert_spin_locked(&adapter->dev_topo.sas_dev_lock); 1090 list_for_each_entry(sas_dev, &adapter->dev_topo.sas_dev_list, list) 1091 if (sas_dev->sas_addr == sas_address && 1092 sas_dev->card_port == port) { 1093 leapraid_sdev_get(sas_dev); 1094 return sas_dev; 1095 } 1096 1097 list_for_each_entry(sas_dev, &adapter->dev_topo.sas_dev_init_list, 1098 list) 1099 if (sas_dev->sas_addr == sas_address && 1100 sas_dev->card_port == port) { 1101 leapraid_sdev_get(sas_dev); 1102 return sas_dev; 1103 } 1104 1105 return NULL; 1106 } 1107 1108 struct leapraid_sas_dev *leapraid_get_sas_dev_by_addr( 1109 struct leapraid_adapter *adapter, 1110 u64 sas_address, struct leapraid_card_port *port) 1111 { 1112 struct leapraid_sas_dev *sas_dev; 1113 unsigned long flags; 1114 1115 if (!port) { 1116 dev_warn(&adapter->pdev->dev, "%s: Invalid port\n", __func__); 1117 return NULL; 1118 } 1119 1120 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 1121 sas_dev = leapraid_hold_lock_get_sas_dev_by_addr(adapter, sas_address, 1122 port); 1123 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 1124 return sas_dev; 1125 } 1126 1127 struct leapraid_sas_dev *leapraid_hold_lock_get_sas_dev_by_hdl( 1128 struct leapraid_adapter *adapter, u16 hdl) 1129 { 1130 struct leapraid_sas_dev *sas_dev; 1131 1132 assert_spin_locked(&adapter->dev_topo.sas_dev_lock); 1133 list_for_each_entry(sas_dev, &adapter->dev_topo.sas_dev_list, list) 1134 if (sas_dev->hdl == hdl) { 1135 leapraid_sdev_get(sas_dev); 1136 return sas_dev; 1137 } 1138 1139 list_for_each_entry(sas_dev, &adapter->dev_topo.sas_dev_init_list, 1140 list) 1141 if (sas_dev->hdl == hdl) { 1142 leapraid_sdev_get(sas_dev); 1143 return sas_dev; 1144 } 1145 1146 return NULL; 1147 } 1148 1149 struct leapraid_sas_dev *leapraid_get_sas_dev_by_hdl( 1150 struct leapraid_adapter *adapter, u16 hdl) 1151 { 1152 struct leapraid_sas_dev *sas_dev; 1153 unsigned long flags; 1154 1155 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 1156 sas_dev = leapraid_hold_lock_get_sas_dev_by_hdl(adapter, hdl); 1157 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 1158 return sas_dev; 1159 } 1160 1161 void leapraid_sas_dev_remove(struct leapraid_adapter *adapter, 1162 struct leapraid_sas_dev *sas_dev) 1163 { 1164 unsigned long flags; 1165 bool del_from_list; 1166 1167 if (!sas_dev) { 1168 dev_warn(&adapter->pdev->dev, 1169 "%s: Invalid SAS device\n", __func__); 1170 return; 1171 } 1172 1173 del_from_list = false; 1174 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 1175 if (!list_empty(&sas_dev->list)) { 1176 list_del_init(&sas_dev->list); 1177 del_from_list = true; 1178 } 1179 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 1180 1181 if (del_from_list) { 1182 leapraid_clear_cached_boot_dev(adapter, sas_dev, 0); 1183 leapraid_sdev_put(sas_dev); 1184 } 1185 } 1186 1187 static void leapraid_sas_dev_remove_by_hdl(struct leapraid_adapter *adapter, 1188 u16 hdl) 1189 { 1190 struct leapraid_sas_dev *sas_dev; 1191 unsigned long flags; 1192 bool del_from_list; 1193 1194 if (adapter->access_ctrl.shost_recovering) 1195 return; 1196 1197 del_from_list = false; 1198 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 1199 sas_dev = leapraid_hold_lock_get_sas_dev_by_hdl(adapter, hdl); 1200 if (sas_dev && (!list_empty(&sas_dev->list))) { 1201 list_del_init(&sas_dev->list); 1202 del_from_list = true; 1203 leapraid_sdev_put(sas_dev); 1204 } 1205 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 1206 1207 if (del_from_list) { 1208 leapraid_remove_device(adapter, sas_dev); 1209 leapraid_sdev_put(sas_dev); 1210 } 1211 } 1212 1213 void leapraid_sas_dev_remove_by_sas_address(struct leapraid_adapter *adapter, 1214 u64 sas_address, 1215 struct leapraid_card_port *port) 1216 { 1217 struct leapraid_sas_dev *sas_dev; 1218 unsigned long flags; 1219 bool del_from_list; 1220 1221 if (adapter->access_ctrl.shost_recovering) 1222 return; 1223 1224 del_from_list = false; 1225 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 1226 sas_dev = leapraid_hold_lock_get_sas_dev_by_addr(adapter, sas_address, 1227 port); 1228 if (sas_dev && (!list_empty(&sas_dev->list))) { 1229 list_del_init(&sas_dev->list); 1230 del_from_list = true; 1231 leapraid_sdev_put(sas_dev); 1232 } 1233 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 1234 1235 if (del_from_list) { 1236 leapraid_remove_device(adapter, sas_dev); 1237 leapraid_sdev_put(sas_dev); 1238 } 1239 } 1240 1241 struct leapraid_raid_volume *leapraid_raid_volume_find_by_id( 1242 struct leapraid_adapter *adapter, uint id, uint channel) 1243 { 1244 struct leapraid_raid_volume *raid_volume; 1245 unsigned long flags; 1246 1247 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags); 1248 list_for_each_entry(raid_volume, &adapter->dev_topo.raid_volume_list, 1249 list) { 1250 if (raid_volume->id == id && raid_volume->channel == channel) { 1251 leapraid_raid_volume_get(raid_volume); 1252 spin_unlock_irqrestore( 1253 &adapter->dev_topo.raid_volume_lock, flags); 1254 return raid_volume; 1255 } 1256 } 1257 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags); 1258 1259 return NULL; 1260 } 1261 1262 struct leapraid_raid_volume *leapraid_raid_volume_find_by_hdl( 1263 struct leapraid_adapter *adapter, u16 hdl) 1264 { 1265 struct leapraid_raid_volume *raid_volume; 1266 unsigned long flags; 1267 1268 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags); 1269 list_for_each_entry(raid_volume, &adapter->dev_topo.raid_volume_list, 1270 list) { 1271 if (raid_volume->hdl == hdl) { 1272 leapraid_raid_volume_get(raid_volume); 1273 spin_unlock_irqrestore( 1274 &adapter->dev_topo.raid_volume_lock, flags); 1275 return raid_volume; 1276 } 1277 } 1278 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags); 1279 1280 return NULL; 1281 } 1282 1283 static struct leapraid_raid_volume *leapraid_raid_volume_find_by_wwid( 1284 struct leapraid_adapter *adapter, u64 wwid) 1285 { 1286 struct leapraid_raid_volume *raid_volume; 1287 unsigned long flags; 1288 1289 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags); 1290 list_for_each_entry(raid_volume, &adapter->dev_topo.raid_volume_list, 1291 list) { 1292 if (raid_volume->wwid == wwid) { 1293 leapraid_raid_volume_get(raid_volume); 1294 spin_unlock_irqrestore( 1295 &adapter->dev_topo.raid_volume_lock, flags); 1296 return raid_volume; 1297 } 1298 } 1299 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags); 1300 1301 return NULL; 1302 } 1303 1304 static void leapraid_raid_volume_add(struct leapraid_adapter *adapter, 1305 struct leapraid_raid_volume *raid_volume) 1306 { 1307 unsigned long flags; 1308 1309 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags); 1310 leapraid_raid_volume_get(raid_volume); 1311 list_add_tail(&raid_volume->list, &adapter->dev_topo.raid_volume_list); 1312 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags); 1313 } 1314 1315 void leapraid_raid_volume_remove(struct leapraid_adapter *adapter, 1316 struct leapraid_raid_volume *raid_volume) 1317 { 1318 unsigned long flags; 1319 bool del_from_list = false; 1320 1321 if (!raid_volume) { 1322 dev_warn(&adapter->pdev->dev, 1323 "%s: Invalid RAID volume\n", __func__); 1324 return; 1325 } 1326 1327 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags); 1328 if (!list_empty(&raid_volume->list)) { 1329 list_del_init(&raid_volume->list); 1330 del_from_list = true; 1331 } 1332 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags); 1333 1334 leapraid_clear_cached_boot_dev(adapter, raid_volume, RAID_CHANNEL); 1335 if (del_from_list) 1336 leapraid_raid_volume_put(raid_volume); 1337 } 1338 1339 static struct leapraid_enc_node *leapraid_enc_find_by_hdl( 1340 struct leapraid_adapter *adapter, u16 hdl) 1341 { 1342 struct leapraid_enc_node *enc_dev; 1343 1344 list_for_each_entry(enc_dev, &adapter->dev_topo.enc_list, list) 1345 if (le16_to_cpu(enc_dev->pg0.enc_hdl) == hdl) 1346 return enc_dev; 1347 1348 return NULL; 1349 } 1350 1351 struct leapraid_topo_node *leapraid_exp_find_by_sas_address( 1352 struct leapraid_adapter *adapter, 1353 u64 sas_address, struct leapraid_card_port *port) 1354 { 1355 struct leapraid_topo_node *sas_exp; 1356 1357 if (!port) { 1358 dev_warn(&adapter->pdev->dev, "%s: Invalid port\n", __func__); 1359 return NULL; 1360 } 1361 1362 list_for_each_entry(sas_exp, &adapter->dev_topo.exp_list, list) 1363 if (sas_exp->sas_address == sas_address && 1364 sas_exp->card_port == port) 1365 return sas_exp; 1366 1367 dev_warn(&adapter->pdev->dev, 1368 "%s: No expander found for SAS addr=0x%016llx port=%p\n", 1369 __func__, (unsigned long long)sas_address, port); 1370 return NULL; 1371 } 1372 1373 bool leapraid_scmd_find_by_tgt(struct leapraid_adapter *adapter, uint id, 1374 uint channel) 1375 { 1376 struct scsi_cmnd *scmd; 1377 int taskid; 1378 1379 for (taskid = 1; taskid <= adapter->shost->can_queue; taskid++) { 1380 scmd = leapraid_get_scmd_from_taskid(adapter, taskid); 1381 if (!scmd) 1382 continue; 1383 1384 if (scmd->device->id == id && scmd->device->channel == channel) 1385 return true; 1386 } 1387 1388 return false; 1389 } 1390 1391 bool leapraid_scmd_find_by_lun(struct leapraid_adapter *adapter, uint id, 1392 unsigned int lun, uint channel) 1393 { 1394 struct scsi_cmnd *scmd; 1395 int taskid; 1396 1397 for (taskid = 1; taskid <= adapter->shost->can_queue; taskid++) { 1398 scmd = leapraid_get_scmd_from_taskid(adapter, taskid); 1399 if (!scmd) 1400 continue; 1401 1402 if (scmd->device->id == id && 1403 scmd->device->channel == channel && 1404 scmd->device->lun == lun) 1405 return true; 1406 } 1407 1408 return false; 1409 } 1410 1411 static struct leapraid_topo_node *leapraid_exp_find_by_hdl( 1412 struct leapraid_adapter *adapter, u16 hdl) 1413 { 1414 struct leapraid_topo_node *sas_exp; 1415 1416 list_for_each_entry(sas_exp, &adapter->dev_topo.exp_list, list) 1417 if (sas_exp->hdl == hdl) 1418 return sas_exp; 1419 1420 return NULL; 1421 } 1422 1423 static enum leapraid_card_port_checking_flg leapraid_get_card_port_feature( 1424 struct leapraid_card_port *old_card_port, 1425 struct leapraid_card_port *card_port, 1426 struct leapraid_card_port_feature *feature) 1427 { 1428 feature->dirty_flg = 1429 old_card_port->flg & LEAPRAID_CARD_PORT_FLG_DIRTY; 1430 feature->same_addr = 1431 old_card_port->sas_address == card_port->sas_address; 1432 feature->exact_phy = 1433 old_card_port->phy_mask == card_port->phy_mask; 1434 feature->phy_overlap = 1435 old_card_port->phy_mask & card_port->phy_mask; 1436 feature->same_port = 1437 old_card_port->port_id == card_port->port_id; 1438 feature->cur_chking_old_port = old_card_port; 1439 1440 if (!feature->dirty_flg || !feature->same_addr) 1441 return CARD_PORT_SKIP_CHECKING; 1442 1443 return CARD_PORT_FURTHER_CHECKING_NEEDED; 1444 } 1445 1446 static bool leapraid_process_card_port_feature( 1447 struct leapraid_card_port_feature *feature) 1448 { 1449 struct leapraid_card_port *old_card_port; 1450 1451 old_card_port = feature->cur_chking_old_port; 1452 if (feature->exact_phy) { 1453 feature->checking_state = SAME_PORT_WITH_NOTHING_CHANGED; 1454 feature->expected_old_port = old_card_port; 1455 return true; 1456 } 1457 1458 if (feature->phy_overlap) { 1459 if (feature->same_port) { 1460 feature->checking_state = 1461 SAME_PORT_WITH_PARTIALLY_CHANGED_PHYS; 1462 feature->expected_old_port = old_card_port; 1463 } else if (feature->checking_state != 1464 SAME_PORT_WITH_PARTIALLY_CHANGED_PHYS) { 1465 feature->checking_state = 1466 SAME_ADDR_WITH_PARTIALLY_CHANGED_PHYS; 1467 feature->expected_old_port = old_card_port; 1468 } 1469 } else if (feature->checking_state != 1470 SAME_PORT_WITH_PARTIALLY_CHANGED_PHYS && 1471 feature->checking_state != 1472 SAME_ADDR_WITH_PARTIALLY_CHANGED_PHYS) { 1473 feature->checking_state = SAME_ADDR_ONLY; 1474 feature->expected_old_port = old_card_port; 1475 feature->same_addr_port_count++; 1476 } 1477 1478 return false; 1479 } 1480 1481 static int leapraid_check_card_port( 1482 struct leapraid_adapter *adapter, 1483 struct leapraid_card_port *card_port, 1484 struct leapraid_card_port **expected_card_port, 1485 int *count) 1486 { 1487 struct leapraid_card_port *old_card_port; 1488 struct leapraid_card_port_feature feature; 1489 1490 *expected_card_port = NULL; 1491 memset(&feature, 0, sizeof(struct leapraid_card_port_feature)); 1492 feature.expected_old_port = NULL; 1493 feature.same_addr_port_count = 0; 1494 feature.checking_state = NEW_CARD_PORT; 1495 1496 list_for_each_entry(old_card_port, &adapter->dev_topo.card_port_list, 1497 list) { 1498 if (leapraid_get_card_port_feature(old_card_port, card_port, 1499 &feature)) 1500 continue; 1501 1502 if (leapraid_process_card_port_feature(&feature)) 1503 break; 1504 } 1505 1506 if (feature.checking_state == SAME_ADDR_ONLY) 1507 *count = feature.same_addr_port_count; 1508 1509 *expected_card_port = feature.expected_old_port; 1510 return feature.checking_state; 1511 } 1512 1513 static void leapraid_del_phy_part_of_anther_port( 1514 struct leapraid_adapter *adapter, 1515 struct leapraid_card_port *card_port_table, int index, 1516 u8 port_count, int offset) 1517 { 1518 struct leapraid_topo_node *card_topo_node; 1519 bool found = false; 1520 int i; 1521 1522 card_topo_node = &adapter->dev_topo.card; 1523 for (i = 0; i < port_count; i++) { 1524 if (i == index) 1525 continue; 1526 1527 if (card_port_table[i].phy_mask & BIT(offset)) { 1528 leapraid_transport_detach_phy_to_port( 1529 adapter, 1530 card_topo_node, 1531 &card_topo_node->card_phy[offset]); 1532 found = true; 1533 break; 1534 } 1535 } 1536 1537 if (!found) 1538 card_port_table[index].phy_mask |= BIT(offset); 1539 } 1540 1541 static void leapraid_add_or_del_phys_from_existing_port( 1542 struct leapraid_adapter *adapter, 1543 struct leapraid_card_port *card_port, 1544 struct leapraid_card_port *card_port_table, 1545 int index, u8 port_count) 1546 { 1547 struct leapraid_topo_node *card_topo_node; 1548 u32 phy_mask_diff; 1549 u32 offset; 1550 1551 card_topo_node = &adapter->dev_topo.card; 1552 phy_mask_diff = card_port->phy_mask ^ 1553 card_port_table[index].phy_mask; 1554 for (offset = 0; offset < adapter->dev_topo.card.phys_num; offset++) { 1555 if (!(phy_mask_diff & BIT(offset))) 1556 continue; 1557 1558 if (!(card_port_table[index].phy_mask & BIT(offset))) { 1559 leapraid_del_phy_part_of_anther_port(adapter, 1560 card_port_table, 1561 index, port_count, 1562 offset); 1563 continue; 1564 } 1565 1566 if (card_topo_node->card_phy[offset].phy_is_assigned) 1567 leapraid_transport_detach_phy_to_port( 1568 adapter, 1569 card_topo_node, 1570 &card_topo_node->card_phy[offset]); 1571 1572 leapraid_transport_attach_phy_to_port( 1573 adapter, 1574 card_topo_node, 1575 &card_topo_node->card_phy[offset], 1576 card_port->sas_address, 1577 card_port); 1578 } 1579 } 1580 1581 struct leapraid_sas_dev *leapraid_get_next_sas_dev_from_init_list( 1582 struct leapraid_adapter *adapter) 1583 { 1584 struct leapraid_sas_dev *sas_dev = NULL; 1585 unsigned long flags; 1586 1587 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 1588 if (!list_empty(&adapter->dev_topo.sas_dev_init_list)) { 1589 sas_dev = list_first_entry(&adapter->dev_topo.sas_dev_init_list, 1590 struct leapraid_sas_dev, 1591 list); 1592 leapraid_sdev_get(sas_dev); 1593 } 1594 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 1595 return sas_dev; 1596 } 1597 1598 static bool leapraid_check_boot_dev_internal(u64 sas_address, u64 dev_name, 1599 u64 enc_lid, u16 slot, 1600 struct leapraid_boot_dev *boot_dev, 1601 u8 form) 1602 { 1603 struct leapraid_boot_dev_format_sas_wwid *wwid; 1604 struct leapraid_boot_dev_format_enc_slot *es; 1605 struct leapraid_boot_dev_format_dev_name *dn; 1606 void *pg_dev; 1607 1608 if (!boot_dev) 1609 return false; 1610 1611 pg_dev = boot_dev->pg_dev; 1612 switch (form & LEAPRAID_BOOTDEV_FORM_MASK) { 1613 case LEAPRAID_BOOTDEV_FORM_SAS_WWID: 1614 wwid = pg_dev; 1615 1616 if (!sas_address) 1617 return false; 1618 1619 return sas_address == le64_to_cpu(wwid->sas_addr); 1620 case LEAPRAID_BOOTDEV_FORM_ENC_SLOT: 1621 es = pg_dev; 1622 1623 if (!enc_lid) 1624 return false; 1625 1626 return (enc_lid == le64_to_cpu(es->enc_lid) && 1627 slot == le16_to_cpu(es->slot_num)); 1628 case LEAPRAID_BOOTDEV_FORM_DEV_NAME: 1629 dn = pg_dev; 1630 1631 if (!dev_name) 1632 return false; 1633 1634 return dev_name == le64_to_cpu(dn->dev_name); 1635 case LEAPRAID_BOOTDEV_FORM_NONE: 1636 default: 1637 return false; 1638 } 1639 } 1640 1641 void leapraid_boot_dev_get(void *dev, u32 chnl) 1642 { 1643 if (!dev) 1644 return; 1645 1646 if (chnl == RAID_CHANNEL) 1647 leapraid_raid_volume_get((struct leapraid_raid_volume *)dev); 1648 else 1649 leapraid_sdev_get((struct leapraid_sas_dev *)dev); 1650 } 1651 1652 void leapraid_boot_dev_put(void *dev, u32 chnl) 1653 { 1654 if (!dev) 1655 return; 1656 1657 if (chnl == RAID_CHANNEL) 1658 leapraid_raid_volume_put((struct leapraid_raid_volume *)dev); 1659 else 1660 leapraid_sdev_put((struct leapraid_sas_dev *)dev); 1661 } 1662 1663 static void leapraid_try_set_boot_dev(struct leapraid_boot_dev *boot_dev, 1664 u64 sas_addr, u64 dev_name, 1665 u64 enc_lid, u16 slot, 1666 void *dev, u32 chnl) 1667 { 1668 bool matched = false; 1669 1670 if (boot_dev->dev) 1671 return; 1672 1673 matched = leapraid_check_boot_dev_internal(sas_addr, dev_name, enc_lid, 1674 slot, boot_dev, 1675 boot_dev->form); 1676 if (matched) { 1677 leapraid_boot_dev_get(dev, chnl); 1678 boot_dev->dev = dev; 1679 boot_dev->chnl = chnl; 1680 } 1681 } 1682 1683 static void leapraid_clear_boot_dev(struct leapraid_adapter *adapter, 1684 struct leapraid_boot_dev *boot_dev, 1685 void *dev, u32 chnl) 1686 { 1687 void *cached_dev; 1688 u32 cached_chnl; 1689 unsigned long flags; 1690 1691 spin_lock_irqsave(&adapter->boot_devs.lock, flags); 1692 if (boot_dev->dev != dev || boot_dev->chnl != chnl) 1693 goto out_unlock; 1694 1695 cached_dev = boot_dev->dev; 1696 cached_chnl = boot_dev->chnl; 1697 boot_dev->dev = NULL; 1698 boot_dev->chnl = 0; 1699 spin_unlock_irqrestore(&adapter->boot_devs.lock, flags); 1700 leapraid_boot_dev_put(cached_dev, cached_chnl); 1701 return; 1702 1703 out_unlock: 1704 spin_unlock_irqrestore(&adapter->boot_devs.lock, flags); 1705 } 1706 1707 static void leapraid_clear_cached_boot_dev(struct leapraid_adapter *adapter, 1708 void *dev, u32 chnl) 1709 { 1710 leapraid_clear_boot_dev(adapter, 1711 &adapter->boot_devs.requested_boot_dev, 1712 dev, chnl); 1713 leapraid_clear_boot_dev(adapter, 1714 &adapter->boot_devs.requested_alt_boot_dev, 1715 dev, chnl); 1716 leapraid_clear_boot_dev(adapter, 1717 &adapter->boot_devs.current_boot_dev, 1718 dev, chnl); 1719 } 1720 1721 static void leapraid_check_boot_dev(struct leapraid_adapter *adapter, 1722 void *dev, u32 chnl) 1723 { 1724 struct leapraid_raid_volume *raid_volume; 1725 struct leapraid_sas_dev *sas_dev; 1726 u64 sas_addr; 1727 u64 dev_name = 0; 1728 u64 enc_lid = 0; 1729 u16 slot = 0; 1730 1731 if (!adapter->scan_dev_desc.driver_loading) 1732 return; 1733 1734 switch (chnl) { 1735 case RAID_CHANNEL: 1736 raid_volume = dev; 1737 sas_addr = raid_volume->wwid; 1738 break; 1739 default: 1740 sas_dev = dev; 1741 sas_addr = sas_dev->sas_addr; 1742 dev_name = sas_dev->dev_name; 1743 enc_lid = sas_dev->enc_lid; 1744 slot = sas_dev->slot; 1745 break; 1746 } 1747 1748 leapraid_try_set_boot_dev(&adapter->boot_devs.requested_boot_dev, 1749 sas_addr, dev_name, enc_lid, 1750 slot, dev, chnl); 1751 leapraid_try_set_boot_dev(&adapter->boot_devs.requested_alt_boot_dev, 1752 sas_addr, dev_name, enc_lid, 1753 slot, dev, chnl); 1754 leapraid_try_set_boot_dev(&adapter->boot_devs.current_boot_dev, 1755 sas_addr, dev_name, enc_lid, 1756 slot, dev, chnl); 1757 } 1758 1759 static const char *leapraid_func_name(u8 func) 1760 { 1761 switch (func) { 1762 case LEAPRAID_FUNC_SCSIIO: 1763 return "SCSIIO"; 1764 case LEAPRAID_FUNC_SCSI_TMF: 1765 return "SCSI_TMF"; 1766 case LEAPRAID_FUNC_ADAPTER_INIT: 1767 return "ADAPTER_INIT"; 1768 case LEAPRAID_FUNC_GET_ADAPTER_FEATURES: 1769 return "GET_ADAPTER_FEATURES"; 1770 case LEAPRAID_FUNC_CONFIG_OP: 1771 return "CONFIG_OP"; 1772 case LEAPRAID_FUNC_SCAN_DEV: 1773 return "SCAN_DEV"; 1774 case LEAPRAID_FUNC_EVENT_NOTIFY: 1775 return "EVENT_NOTIFY"; 1776 case LEAPRAID_FUNC_FW_DOWNLOAD: 1777 return "FW_DOWNLOAD"; 1778 case LEAPRAID_FUNC_FW_UPLOAD: 1779 return "FW_UPLOAD"; 1780 case LEAPRAID_FUNC_SCSIIO_RAID_PASSTHROUGH: 1781 return "SCSIIO_RAID_PASSTHROUGH"; 1782 case LEAPRAID_FUNC_SCSI_ENC_PROCESSOR: 1783 return "SCSI_ENC_PROCESSOR"; 1784 case LEAPRAID_FUNC_SMP_PASSTHROUGH: 1785 return "SMP_PASSTHROUGH"; 1786 case LEAPRAID_FUNC_SAS_IO_UNIT_CTRL: 1787 return "SAS_IO_UNIT_CTRL"; 1788 case LEAPRAID_FUNC_SCSIIO_SATA_PASSTHROUGH: 1789 return "SCSIIO_SATA_PASSTHROUGH"; 1790 case LEAPRAID_FUNC_ADAPTER_UNIT_RESET: 1791 return "ADAPTER_UNIT_RESET"; 1792 case LEAPRAID_FUNC_HANDSHAKE: 1793 return "HANDSHAKE"; 1794 case LEAPRAID_FUNC_LOGBUF_INIT: 1795 return "LOGBUF_INIT"; 1796 default: 1797 return "UNKNOWN"; 1798 } 1799 } 1800 1801 static const char *leapraid_cfg_action_name(u8 action) 1802 { 1803 switch (action) { 1804 case LEAPRAID_CFG_ACT_PAGE_HEADER: 1805 return "PAGE_HEADER"; 1806 case LEAPRAID_CFG_ACT_PAGE_READ_CUR: 1807 return "PAGE_READ_CUR"; 1808 case LEAPRAID_CFG_ACT_PAGE_WRITE_CUR: 1809 return "PAGE_WRITE_CUR"; 1810 default: 1811 return "UNKNOWN"; 1812 } 1813 } 1814 1815 static const char *leapraid_cfg_page_type_name(u8 page_type) 1816 { 1817 switch (page_type) { 1818 case LEAPRAID_CFG_PT_IO_UNIT: 1819 return "IO_UNIT"; 1820 case LEAPRAID_CFG_PT_ADAPTER: 1821 return "ADAPTER"; 1822 case LEAPRAID_CFG_PT_BIOS: 1823 return "BIOS"; 1824 case LEAPRAID_CFG_PT_RAID_VOLUME: 1825 return "RAID_VOLUME"; 1826 case LEAPRAID_CFG_PT_MANUFACTURING: 1827 return "MANUFACTURING"; 1828 case LEAPRAID_CFG_PT_RAID_PHYSDISK: 1829 return "RAID_PHYSDISK"; 1830 case LEAPRAID_CFG_PT_EXTENDED: 1831 return "EXTENDED"; 1832 default: 1833 return "UNKNOWN"; 1834 } 1835 } 1836 1837 static const char *leapraid_cfg_ext_page_type_name(u8 ext_page_type) 1838 { 1839 switch (ext_page_type) { 1840 case LEAPRAID_CFG_EXTPT_SAS_IO_UNIT: 1841 return "SAS_IO_UNIT"; 1842 case LEAPRAID_CFG_EXTPT_SAS_EXP: 1843 return "SAS_EXPANDER"; 1844 case LEAPRAID_CFG_EXTPT_SAS_DEV: 1845 return "SAS_DEVICE"; 1846 case LEAPRAID_CFG_EXTPT_SAS_PHY: 1847 return "SAS_PHY"; 1848 case LEAPRAID_CFG_EXTPT_ENC: 1849 return "ENCLOSURE"; 1850 case LEAPRAID_CFG_EXTPT_RAID_CONFIG: 1851 return "RAID_CONFIG"; 1852 default: 1853 return "UNKNOWN"; 1854 } 1855 } 1856 1857 static const char *leapraid_sep_action_name(u8 action) 1858 { 1859 switch (action) { 1860 case LEAPRAID_SEP_REQ_ACT_WRITE_STATUS: 1861 return "WRITE_STATUS"; 1862 default: 1863 return "UNKNOWN"; 1864 } 1865 } 1866 1867 static const char *leapraid_sas_op_name(u8 op) 1868 { 1869 switch (op) { 1870 case LEAPRAID_SAS_OP_PHY_LINK_RESET: 1871 return "PHY_LINK_RESET"; 1872 case LEAPRAID_SAS_OP_PHY_HARD_RESET: 1873 return "PHY_HARD_RESET"; 1874 case LEAPRAID_SAS_OP_SET_PARAMETER: 1875 return "SET_PARAMETER"; 1876 default: 1877 return "UNKNOWN"; 1878 } 1879 } 1880 1881 static const char *leapraid_tm_type_name(u8 task_type) 1882 { 1883 switch (task_type) { 1884 case LEAPRAID_TM_TASKTYPE_ABORT_TASK: 1885 return "ABORT_TASK"; 1886 case LEAPRAID_TM_TASKTYPE_ABRT_TASK_SET: 1887 return "ABORT_TASK_SET"; 1888 case LEAPRAID_TM_TASKTYPE_TARGET_RESET: 1889 return "TARGET_RESET"; 1890 case LEAPRAID_TM_TASKTYPE_LOGICAL_UNIT_RESET: 1891 return "LOGICAL_UNIT_RESET"; 1892 case LEAPRAID_TM_TASKTYPE_CLEAR_TASK_SET: 1893 return "CLEAR_TASK_SET"; 1894 case LEAPRAID_TM_TASKTYPE_QUERY_TASK: 1895 return "QUERY_TASK"; 1896 case LEAPRAID_TM_TASKTYPE_CLEAR_ACA: 1897 return "CLEAR_ACA"; 1898 case LEAPRAID_TM_TASKTYPE_QUERY_TASK_SET: 1899 return "QUERY_TASK_SET"; 1900 case LEAPRAID_TM_TASKTYPE_QUERY_ASYNC_EVENT: 1901 return "QUERY_ASYNC_EVENT"; 1902 default: 1903 return "UNKNOWN"; 1904 } 1905 } 1906 1907 void leapraid_log_req_context(struct leapraid_adapter *adapter, u16 smid, 1908 const void *req_data) 1909 { 1910 const struct leapraid_req *req = req_data; 1911 1912 if (!adapter || !adapter->pdev || !req_data) 1913 return; 1914 1915 switch (req->func) { 1916 case LEAPRAID_FUNC_CONFIG_OP: { 1917 const struct leapraid_cfg_req *cfg_req = req_data; 1918 1919 dev_err(&adapter->pdev->dev, 1920 "cfg-req: smid=%u func=0x%02x(%s) action=0x%02x(%s)\n", 1921 smid, req->func, leapraid_func_name(req->func), 1922 cfg_req->action, 1923 leapraid_cfg_action_name(cfg_req->action)); 1924 dev_err(&adapter->pdev->dev, 1925 "cfg-req: page_type=0x%02x(%s) page_num=%u\n", 1926 cfg_req->header.page_type, 1927 leapraid_cfg_page_type_name(cfg_req->header.page_type), 1928 cfg_req->header.page_num); 1929 if (cfg_req->header.page_type == LEAPRAID_CFG_PT_EXTENDED) 1930 dev_err(&adapter->pdev->dev, 1931 "cfg-req: ext_page_type=0x%02x(%s)\n", 1932 cfg_req->ext_page_type, 1933 leapraid_cfg_ext_page_type_name( 1934 cfg_req->ext_page_type)); 1935 dev_err(&adapter->pdev->dev, "cfg-req: page_addr=0x%08x\n", 1936 le32_to_cpu(cfg_req->page_addr)); 1937 break; 1938 } 1939 case LEAPRAID_FUNC_SCSI_TMF: { 1940 const struct leapraid_scsi_tm_req *tm_req = req_data; 1941 1942 dev_err(&adapter->pdev->dev, 1943 "scsi_tm:: smid=%u func=0x%02x(%s) task=0x%02x(%s)\n", 1944 smid, req->func, leapraid_func_name(req->func), 1945 tm_req->task_type, 1946 leapraid_tm_type_name(tm_req->task_type)); 1947 dev_err(&adapter->pdev->dev, 1948 "scsi_tm:: dev_hdl=0x%04x task_mid=%u\n", 1949 le16_to_cpu(tm_req->dev_hdl), 1950 le16_to_cpu(tm_req->task_mid)); 1951 break; 1952 } 1953 case LEAPRAID_FUNC_SCSI_ENC_PROCESSOR: { 1954 const struct leapraid_sep_req *sep_req = req_data; 1955 1956 dev_err(&adapter->pdev->dev, 1957 "sep: smid=%u func=0x%02x(%s) action=0x%02x(%s)\n", 1958 smid, req->func, leapraid_func_name(req->func), 1959 sep_req->act, 1960 leapraid_sep_action_name(sep_req->act)); 1961 dev_err(&adapter->pdev->dev, 1962 "sep: dev_hdl=0x%04x slot=%u enc_hdl=0x%04x\n", 1963 le16_to_cpu(sep_req->dev_hdl), 1964 le16_to_cpu(sep_req->slot), 1965 le16_to_cpu(sep_req->enc_hdl)); 1966 break; 1967 } 1968 case LEAPRAID_FUNC_SAS_IO_UNIT_CTRL: { 1969 const struct leapraid_io_unit_ctrl_req *io_req = req_data; 1970 1971 dev_err(&adapter->pdev->dev, 1972 "ctl_cmd: smid=%u func=0x%02x(%s) action=0x%02x(%s)\n", 1973 smid, req->func, leapraid_func_name(req->func), 1974 io_req->op, leapraid_sas_op_name(io_req->op)); 1975 dev_err(&adapter->pdev->dev, 1976 "ctl_cmd: dev_hdl=0x%04x param=0x%02x\n", 1977 le16_to_cpu(io_req->dev_hdl), 1978 io_req->adapter_para); 1979 break; 1980 } 1981 case LEAPRAID_FUNC_SMP_PASSTHROUGH: { 1982 const struct leapraid_smp_passthrough_req *smp_req = req_data; 1983 1984 dev_err(&adapter->pdev->dev, 1985 "smp_cmd: smid=%u func=0x%02x(%s) action=0x%02x\n", 1986 smid, req->func, leapraid_func_name(req->func), 1987 smp_req->passthrough_flg); 1988 dev_err(&adapter->pdev->dev, 1989 "smp_cmd: port=%u req_len=%u\n", 1990 smp_req->physical_port, 1991 le16_to_cpu(smp_req->req_data_len)); 1992 dev_err(&adapter->pdev->dev, "smp_cmd: sas_addr=0x%016llx\n", 1993 (unsigned long long)le64_to_cpu(smp_req->sas_address)); 1994 break; 1995 } 1996 default: 1997 dev_err(&adapter->pdev->dev, 1998 "cmd: smid=%u func=0x%02x(%s)\n", 1999 smid, req->func, leapraid_func_name(req->func)); 2000 break; 2001 } 2002 } 2003 2004 static void leapraid_build_and_fire_cfg_req( 2005 struct leapraid_adapter *adapter, 2006 struct leapraid_cfg_req *leap_mpi_cfgp_req, 2007 struct leapraid_cfg_rep *leap_mpi_cfgp_rep) 2008 { 2009 struct leapraid_cfg_req *local_leap_cfg_req; 2010 u16 smid; 2011 2012 memset(leap_mpi_cfgp_rep, 0, sizeof(struct leapraid_cfg_rep)); 2013 memset(&adapter->driver_cmds.cfg_op_cmd.reply, 0, 2014 sizeof(struct leapraid_cfg_rep)); 2015 adapter->driver_cmds.cfg_op_cmd.status = LEAPRAID_CMD_PENDING; 2016 smid = adapter->driver_cmds.cfg_op_cmd.inter_taskid; 2017 local_leap_cfg_req = leapraid_get_task_desc(adapter, smid); 2018 memcpy(local_leap_cfg_req, leap_mpi_cfgp_req, 2019 sizeof(struct leapraid_cfg_req)); 2020 init_completion(&adapter->driver_cmds.cfg_op_cmd.done); 2021 leapraid_fire_task(adapter, smid); 2022 wait_for_completion_timeout(&adapter->driver_cmds.cfg_op_cmd.done, 2023 LEAPRAID_CFG_OP_TIMEOUT * HZ); 2024 } 2025 2026 static int leapraid_req_cfg_func(struct leapraid_adapter *adapter, 2027 struct leapraid_cfg_req *leap_mpi_cfgp_req, 2028 struct leapraid_cfg_rep *leap_mpi_cfgp_rep, 2029 void *target_cfg_pg, void *real_cfg_pg_addr, 2030 u16 target_real_cfg_pg_sz) 2031 { 2032 u32 adapter_status = UINT_MAX; 2033 bool issue_reset = false; 2034 u16 smid; 2035 u8 retry_cnt; 2036 int rc; 2037 2038 retry_cnt = 0; 2039 mutex_lock(&adapter->driver_cmds.cfg_op_cmd.mutex); 2040 smid = adapter->driver_cmds.cfg_op_cmd.inter_taskid; 2041 retry: 2042 if (retry_cnt) { 2043 if (retry_cnt > LEAPRAID_CFG_REQ_RETRY_TIMES) { 2044 rc = -EFAULT; 2045 goto out_cleanup; 2046 } 2047 dev_warn(&adapter->pdev->dev, 2048 "cfg-req: Retry request, cnt=%u\n", retry_cnt); 2049 } 2050 2051 rc = leapraid_check_adapter_is_op(adapter, LEAPRAID_DB_WAIT_OP_SHORT, 2052 __func__); 2053 if (rc) { 2054 dev_err(&adapter->pdev->dev, 2055 "cfg-req: Adapter not operational\n"); 2056 goto out_cleanup; 2057 } 2058 2059 leapraid_build_and_fire_cfg_req(adapter, leap_mpi_cfgp_req, 2060 leap_mpi_cfgp_rep); 2061 if (!(adapter->driver_cmds.cfg_op_cmd.status & LEAPRAID_CMD_DONE)) { 2062 retry_cnt++; 2063 if (adapter->driver_cmds.cfg_op_cmd.status & 2064 LEAPRAID_CMD_RESET) { 2065 dev_warn(&adapter->pdev->dev, 2066 "cfg-req: CMD fail due to hard reset\n"); 2067 goto retry; 2068 } 2069 2070 if (adapter->access_ctrl.shost_recovering || 2071 adapter->access_ctrl.pcie_recovering) { 2072 dev_err(&adapter->pdev->dev, 2073 "cfg-req: pending in %s, status=0x%x\n", 2074 adapter->access_ctrl.shost_recovering ? 2075 "shost recovery" : "pcie recovery", 2076 adapter->driver_cmds.cfg_op_cmd.status); 2077 leapraid_log_req_context(adapter, smid, 2078 leap_mpi_cfgp_req); 2079 issue_reset = false; 2080 rc = -EFAULT; 2081 } else { 2082 dev_err(&adapter->pdev->dev, 2083 "cfg-req: timeout, status=0x%x, reset\n", 2084 adapter->driver_cmds.cfg_op_cmd.status); 2085 leapraid_log_req_context(adapter, smid, 2086 leap_mpi_cfgp_req); 2087 issue_reset = true; 2088 } 2089 2090 goto out_cleanup; 2091 } 2092 2093 if (adapter->driver_cmds.cfg_op_cmd.status & 2094 LEAPRAID_CMD_REPLY_VALID) { 2095 memcpy(leap_mpi_cfgp_rep, 2096 &adapter->driver_cmds.cfg_op_cmd.reply, 2097 sizeof(struct leapraid_cfg_rep)); 2098 adapter_status = le16_to_cpu( 2099 leap_mpi_cfgp_rep->adapter_status) & 2100 LEAPRAID_ADAPTER_STATUS_MASK; 2101 if (adapter_status == LEAPRAID_ADAPTER_STATUS_SUCCESS && 2102 target_cfg_pg && real_cfg_pg_addr && 2103 target_real_cfg_pg_sz && 2104 leap_mpi_cfgp_req->action == 2105 LEAPRAID_CFG_ACT_PAGE_READ_CUR) 2106 memcpy(target_cfg_pg, real_cfg_pg_addr, 2107 target_real_cfg_pg_sz); 2108 if (adapter_status != LEAPRAID_ADAPTER_STATUS_SUCCESS) { 2109 if (adapter_status != 2110 LEAPRAID_ADAPTER_STATUS_CONFIG_INVALID_PAGE) 2111 dev_err(&adapter->pdev->dev, 2112 "cfg-rep: adapter_status=0x%x\n", 2113 adapter_status); 2114 rc = -EFAULT; 2115 } 2116 } else { 2117 dev_err(&adapter->pdev->dev, "cfg-rep: Reply invalid\n"); 2118 rc = -EFAULT; 2119 } 2120 2121 out_cleanup: 2122 adapter->driver_cmds.cfg_op_cmd.status = LEAPRAID_CMD_NOT_USED; 2123 mutex_unlock(&adapter->driver_cmds.cfg_op_cmd.mutex); 2124 if (issue_reset) { 2125 if (adapter->scan_dev_desc.first_scan_dev_fired) { 2126 dev_warn(&adapter->pdev->dev, 2127 "%s:%d cfg-req: Failure, issuing reset\n", 2128 __func__, __LINE__); 2129 leapraid_hard_reset_handler(adapter, FULL_RESET); 2130 } else { 2131 dev_warn(&adapter->pdev->dev, 2132 "cfg-req: CMD fail in init, skip reset\n"); 2133 } 2134 rc = -EFAULT; 2135 } 2136 return rc; 2137 } 2138 2139 static int leapraid_request_cfg_pg_header( 2140 struct leapraid_adapter *adapter, 2141 struct leapraid_cfg_req *leap_mpi_cfgp_req, 2142 struct leapraid_cfg_rep *leap_mpi_cfgp_rep) 2143 { 2144 return leapraid_req_cfg_func(adapter, leap_mpi_cfgp_req, 2145 leap_mpi_cfgp_rep, NULL, NULL, 0); 2146 } 2147 2148 static int leapraid_request_cfg_pg(struct leapraid_adapter *adapter, 2149 struct leapraid_cfg_req *leap_mpi_cfgp_req, 2150 struct leapraid_cfg_rep *leap_mpi_cfgp_rep, 2151 void *target_cfg_pg, void *real_cfg_pg_addr, 2152 u16 target_real_cfg_pg_sz) 2153 { 2154 return leapraid_req_cfg_func(adapter, leap_mpi_cfgp_req, 2155 leap_mpi_cfgp_rep, target_cfg_pg, 2156 real_cfg_pg_addr, target_real_cfg_pg_sz); 2157 } 2158 2159 int leapraid_op_config_page(struct leapraid_adapter *adapter, 2160 void *target_cfg_pg, union cfg_param_1 cfgp1, 2161 union cfg_param_2 cfgp2, 2162 enum config_page_action cfg_op) 2163 { 2164 struct leapraid_cfg_req leap_mpi_cfgp_req; 2165 struct leapraid_cfg_rep leap_mpi_cfgp_rep; 2166 u16 real_cfg_pg_sz; 2167 void *real_cfg_pg_addr; 2168 dma_addr_t real_cfg_pg_dma = 0; 2169 u32 __page_size; 2170 int rc; 2171 2172 memset(&leap_mpi_cfgp_req, 0, sizeof(struct leapraid_cfg_req)); 2173 leap_mpi_cfgp_req.func = LEAPRAID_FUNC_CONFIG_OP; 2174 leap_mpi_cfgp_req.action = LEAPRAID_CFG_ACT_PAGE_HEADER; 2175 2176 switch (cfg_op) { 2177 case GET_BIOS_PG3: 2178 leap_mpi_cfgp_req.header.page_type = LEAPRAID_CFG_PT_BIOS; 2179 leap_mpi_cfgp_req.header.page_num = 2180 LEAPRAID_CFG_PAGE_NUM_BIOS3; 2181 __page_size = sizeof(struct leapraid_bios_page3); 2182 break; 2183 case GET_BIOS_PG2: 2184 leap_mpi_cfgp_req.header.page_type = LEAPRAID_CFG_PT_BIOS; 2185 leap_mpi_cfgp_req.header.page_num = 2186 LEAPRAID_CFG_PAGE_NUM_BIOS2; 2187 __page_size = sizeof(struct leapraid_bios_page2); 2188 break; 2189 case GET_MANUFACTURING_PG0: 2190 leap_mpi_cfgp_req.header.page_type = 2191 LEAPRAID_CFG_PT_MANUFACTURING; 2192 leap_mpi_cfgp_req.header.page_num = 2193 LEAPRAID_CFG_PAGE_NUM_MANU0; 2194 __page_size = sizeof(struct leapraid_manufacturing_p0); 2195 break; 2196 case GET_SAS_DEVICE_PG0: 2197 leap_mpi_cfgp_req.header.page_type = LEAPRAID_CFG_PT_EXTENDED; 2198 leap_mpi_cfgp_req.ext_page_type = LEAPRAID_CFG_EXTPT_SAS_DEV; 2199 leap_mpi_cfgp_req.header.page_num = LEAPRAID_CFG_PAGE_NUM_DEV0; 2200 __page_size = sizeof(struct leapraid_sas_dev_p0); 2201 break; 2202 case GET_SAS_IOUNIT_PG0: 2203 leap_mpi_cfgp_req.header.page_type = LEAPRAID_CFG_PT_EXTENDED; 2204 leap_mpi_cfgp_req.ext_page_type = 2205 LEAPRAID_CFG_EXTPT_SAS_IO_UNIT; 2206 leap_mpi_cfgp_req.header.page_num = 2207 LEAPRAID_CFG_PAGE_NUM_IOUNIT0; 2208 __page_size = cfgp1.size; 2209 break; 2210 case GET_SAS_IOUNIT_PG1: 2211 leap_mpi_cfgp_req.header.page_type = LEAPRAID_CFG_PT_EXTENDED; 2212 leap_mpi_cfgp_req.ext_page_type = 2213 LEAPRAID_CFG_EXTPT_SAS_IO_UNIT; 2214 leap_mpi_cfgp_req.header.page_num = 2215 LEAPRAID_CFG_PAGE_NUM_IOUNIT1; 2216 __page_size = cfgp1.size; 2217 break; 2218 case GET_SAS_EXPANDER_PG0: 2219 leap_mpi_cfgp_req.header.page_type = LEAPRAID_CFG_PT_EXTENDED; 2220 leap_mpi_cfgp_req.ext_page_type = LEAPRAID_CFG_EXTPT_SAS_EXP; 2221 leap_mpi_cfgp_req.header.page_num = LEAPRAID_CFG_PAGE_NUM_EXP0; 2222 __page_size = sizeof(struct leapraid_exp_p0); 2223 break; 2224 case GET_SAS_EXPANDER_PG1: 2225 leap_mpi_cfgp_req.header.page_type = LEAPRAID_CFG_PT_EXTENDED; 2226 leap_mpi_cfgp_req.ext_page_type = LEAPRAID_CFG_EXTPT_SAS_EXP; 2227 leap_mpi_cfgp_req.header.page_num = LEAPRAID_CFG_PAGE_NUM_EXP1; 2228 __page_size = sizeof(struct leapraid_exp_p1); 2229 break; 2230 case GET_SAS_ENCLOSURE_PG0: 2231 leap_mpi_cfgp_req.header.page_type = LEAPRAID_CFG_PT_EXTENDED; 2232 leap_mpi_cfgp_req.ext_page_type = LEAPRAID_CFG_EXTPT_ENC; 2233 leap_mpi_cfgp_req.header.page_num = LEAPRAID_CFG_PAGE_NUM_ENC0; 2234 __page_size = sizeof(struct leapraid_enc_p0); 2235 break; 2236 case GET_PHY_PG0: 2237 leap_mpi_cfgp_req.header.page_type = LEAPRAID_CFG_PT_EXTENDED; 2238 leap_mpi_cfgp_req.ext_page_type = LEAPRAID_CFG_EXTPT_SAS_PHY; 2239 leap_mpi_cfgp_req.header.page_num = LEAPRAID_CFG_PAGE_NUM_PHY0; 2240 __page_size = sizeof(struct leapraid_sas_phy_p0); 2241 break; 2242 case GET_RAID_VOLUME_PG0: 2243 leap_mpi_cfgp_req.header.page_type = 2244 LEAPRAID_CFG_PT_RAID_VOLUME; 2245 leap_mpi_cfgp_req.header.page_num = LEAPRAID_CFG_PAGE_NUM_VOL0; 2246 __page_size = cfgp1.size; 2247 break; 2248 case GET_RAID_VOLUME_PG1: 2249 leap_mpi_cfgp_req.header.page_type = 2250 LEAPRAID_CFG_PT_RAID_VOLUME; 2251 leap_mpi_cfgp_req.header.page_num = LEAPRAID_CFG_PAGE_NUM_VOL1; 2252 __page_size = sizeof(struct leapraid_raidvol_p1); 2253 break; 2254 case GET_PHY_DISK_PG0: 2255 leap_mpi_cfgp_req.header.page_type = 2256 LEAPRAID_CFG_PT_RAID_PHYSDISK; 2257 leap_mpi_cfgp_req.header.page_num = LEAPRAID_CFG_PAGE_NUM_PD0; 2258 __page_size = sizeof(struct leapraid_raidpd_p0); 2259 break; 2260 default: 2261 dev_err(&adapter->pdev->dev, 2262 "Unsupported config page action=%d!\n", cfg_op); 2263 return -EINVAL; 2264 } 2265 2266 leapraid_build_nodata_mpi_sg(adapter, 2267 &leap_mpi_cfgp_req.page_buf_sge); 2268 rc = leapraid_request_cfg_pg_header(adapter, 2269 &leap_mpi_cfgp_req, 2270 &leap_mpi_cfgp_rep); 2271 if (rc) { 2272 dev_err(&adapter->pdev->dev, 2273 "cfg-req: Header failed rc=%dn", rc); 2274 return rc; 2275 } 2276 2277 if (cfg_op == GET_SAS_DEVICE_PG0 || 2278 cfg_op == GET_SAS_EXPANDER_PG0 || 2279 cfg_op == GET_SAS_ENCLOSURE_PG0 || 2280 cfg_op == GET_RAID_VOLUME_PG1) 2281 leap_mpi_cfgp_req.page_addr = cpu_to_le32(cfgp1.form | 2282 cfgp2.handle); 2283 else if (cfg_op == GET_PHY_DISK_PG0) 2284 leap_mpi_cfgp_req.page_addr = cpu_to_le32(cfgp1.form | 2285 cfgp2.form_specific); 2286 else if (cfg_op == GET_RAID_VOLUME_PG0) 2287 leap_mpi_cfgp_req.page_addr = 2288 cpu_to_le32(cfgp2.handle | 2289 LEAPRAID_RAID_VOL_CFG_PGAD_HDL); 2290 else if (cfg_op == GET_SAS_EXPANDER_PG1) 2291 leap_mpi_cfgp_req.page_addr = 2292 cpu_to_le32(cfgp2.handle | 2293 (cfgp1.phy_number << 2294 LEAPRAID_SAS_EXP_CFG_PGAD_PHYNUM_SHIFT) | 2295 LEAPRAID_SAS_EXP_CFG_PGAD_HDL_PHY_NUM); 2296 else if (cfg_op == GET_PHY_PG0) 2297 leap_mpi_cfgp_req.page_addr = cpu_to_le32(cfgp1.phy_number | 2298 LEAPRAID_SAS_PHY_CFG_PGAD_PHY_NUMBER); 2299 2300 leap_mpi_cfgp_req.action = LEAPRAID_CFG_ACT_PAGE_READ_CUR; 2301 2302 leap_mpi_cfgp_req.header.page_num = leap_mpi_cfgp_rep.header.page_num; 2303 leap_mpi_cfgp_req.header.page_type = 2304 leap_mpi_cfgp_rep.header.page_type; 2305 leap_mpi_cfgp_req.header.page_len = leap_mpi_cfgp_rep.header.page_len; 2306 leap_mpi_cfgp_req.ext_page_len = leap_mpi_cfgp_rep.ext_page_len; 2307 leap_mpi_cfgp_req.ext_page_type = leap_mpi_cfgp_rep.ext_page_type; 2308 2309 real_cfg_pg_sz = (leap_mpi_cfgp_req.header.page_len) ? 2310 leap_mpi_cfgp_req.header.page_len * sizeof(u32) : 2311 le16_to_cpu(leap_mpi_cfgp_rep.ext_page_len) * sizeof(u32); 2312 real_cfg_pg_addr = dma_alloc_coherent(&adapter->pdev->dev, 2313 real_cfg_pg_sz, 2314 &real_cfg_pg_dma, 2315 GFP_KERNEL); 2316 if (!real_cfg_pg_addr) 2317 return -ENOMEM; 2318 2319 if (leap_mpi_cfgp_req.action == LEAPRAID_CFG_ACT_PAGE_WRITE_CUR) { 2320 leapraid_single_mpi_sg_append(adapter, 2321 &leap_mpi_cfgp_req.page_buf_sge, 2322 ((LEAPRAID_SGE_FLG_SIMPLE_ONE | 2323 LEAPRAID_SGE_FLG_LAST_ONE | 2324 LEAPRAID_SGE_FLG_EOB | 2325 LEAPRAID_SGE_FLG_EOL | 2326 LEAPRAID_SGE_FLG_H2C) << 2327 LEAPRAID_SGE_FLG_SHIFT) | 2328 real_cfg_pg_sz, 2329 real_cfg_pg_dma); 2330 memcpy(real_cfg_pg_addr, target_cfg_pg, 2331 min_t(u16, real_cfg_pg_sz, __page_size)); 2332 } else { 2333 memset(target_cfg_pg, 0, __page_size); 2334 leapraid_single_mpi_sg_append(adapter, 2335 &leap_mpi_cfgp_req.page_buf_sge, 2336 ((LEAPRAID_SGE_FLG_SIMPLE_ONE | 2337 LEAPRAID_SGE_FLG_LAST_ONE | 2338 LEAPRAID_SGE_FLG_EOB | 2339 LEAPRAID_SGE_FLG_EOL) << 2340 LEAPRAID_SGE_FLG_SHIFT) | 2341 real_cfg_pg_sz, 2342 real_cfg_pg_dma); 2343 memset(real_cfg_pg_addr, 0, 2344 min_t(u16, real_cfg_pg_sz, __page_size)); 2345 } 2346 2347 rc = leapraid_request_cfg_pg(adapter, 2348 &leap_mpi_cfgp_req, 2349 &leap_mpi_cfgp_rep, 2350 target_cfg_pg, 2351 real_cfg_pg_addr, 2352 min_t(u16, real_cfg_pg_sz, __page_size)); 2353 if (rc) { 2354 u32 status; 2355 2356 status = le16_to_cpu(leap_mpi_cfgp_rep.adapter_status) & 2357 LEAPRAID_ADAPTER_STATUS_MASK; 2358 if (status != LEAPRAID_ADAPTER_STATUS_CONFIG_INVALID_PAGE) 2359 dev_err(&adapter->pdev->dev, 2360 "cfg-req: rc=%d, pg_info: 0x%x, 0x%x, %d\n", 2361 rc, leap_mpi_cfgp_req.header.page_type, 2362 leap_mpi_cfgp_req.ext_page_type, 2363 leap_mpi_cfgp_req.header.page_num); 2364 } 2365 2366 if (real_cfg_pg_addr) 2367 dma_free_coherent(&adapter->pdev->dev, 2368 real_cfg_pg_sz, 2369 real_cfg_pg_addr, 2370 real_cfg_pg_dma); 2371 2372 return rc; 2373 } 2374 2375 static int leapraid_cfg_find_vol_in_page( 2376 struct leapraid_raid_cfg_p0 *raid_cfg_p0, 2377 u16 pd_hdl, u16 *vol_hdl) 2378 { 2379 u16 elements = raid_cfg_p0->elements_num; 2380 int i; 2381 2382 for (i = 0; i < elements; i++) { 2383 struct leapraid_raid_cfg_p0_element *elem; 2384 u16 type; 2385 2386 elem = &raid_cfg_p0->cfg_element[i]; 2387 2388 type = le16_to_cpu(elem->element_flg) & 2389 LEAPRAID_RAIDCFG_P0_EFLG_MASK_ELEMENT_TYPE; 2390 2391 switch (type) { 2392 case LEAPRAID_RAIDCFG_P0_EFLG_VOL_PHYS_DISK_ELEMENT: 2393 case LEAPRAID_RAIDCFG_P0_EFLG_OCE_ELEMENT: { 2394 u16 phys_hdl; 2395 2396 phys_hdl = le16_to_cpu(elem->phys_disk_dev_hdl); 2397 if (phys_hdl == pd_hdl) { 2398 *vol_hdl = le16_to_cpu(elem->vol_dev_hdl); 2399 return 0; 2400 } 2401 break; 2402 } 2403 case LEAPRAID_RAIDCFG_P0_EFLG_HOT_SPARE_ELEMENT: 2404 *vol_hdl = 0; 2405 return 0; 2406 2407 default: 2408 break; 2409 } 2410 } 2411 2412 return -ENOENT; 2413 } 2414 2415 static int leapraid_cfg_get_volume_hdl_dispatch( 2416 struct leapraid_adapter *adapter, 2417 struct leapraid_cfg_req *cfg_req, 2418 struct leapraid_cfg_rep *cfg_rep, 2419 struct leapraid_raid_cfg_p0 *raid_cfg_p0, 2420 void *real_cfg_pg_addr, 2421 u16 real_cfg_pg_sz, 2422 u16 raid_cfg_p0_sz, 2423 u16 pd_hdl, u16 *vol_hdl) 2424 { 2425 u16 adapter_status; 2426 int config_num; 2427 int rc; 2428 2429 config_num = 0xFF; 2430 while (true) { 2431 cfg_req->page_addr = 2432 cpu_to_le32(config_num + 2433 LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP); 2434 rc = leapraid_request_cfg_pg( 2435 adapter, cfg_req, cfg_rep, 2436 raid_cfg_p0, real_cfg_pg_addr, 2437 min_t(u16, real_cfg_pg_sz, raid_cfg_p0_sz)); 2438 adapter_status = le16_to_cpu(cfg_rep->adapter_status) & 2439 LEAPRAID_ADAPTER_STATUS_MASK; 2440 if (rc) { 2441 if (adapter_status == 2442 LEAPRAID_ADAPTER_STATUS_CONFIG_INVALID_PAGE) { 2443 *vol_hdl = 0; 2444 return 0; 2445 } 2446 return rc; 2447 } 2448 2449 if (adapter_status != LEAPRAID_ADAPTER_STATUS_SUCCESS) 2450 return LEAPRAID_OPERATION_FAILED; 2451 2452 rc = leapraid_cfg_find_vol_in_page(raid_cfg_p0, 2453 pd_hdl, 2454 vol_hdl); 2455 if (rc != -ENOENT) 2456 return rc; 2457 2458 config_num = raid_cfg_p0->cfg_num; 2459 } 2460 return 0; 2461 } 2462 2463 int leapraid_cfg_get_volume_hdl(struct leapraid_adapter *adapter, 2464 u16 pd_hdl, u16 *vol_hdl) 2465 { 2466 struct leapraid_raid_cfg_p0 *raid_cfg_p0; 2467 struct leapraid_cfg_req cfg_req; 2468 struct leapraid_cfg_rep cfg_rep; 2469 dma_addr_t real_cfg_pg_dma = 0; 2470 void *real_cfg_pg_addr; 2471 u16 real_cfg_pg_sz; 2472 int rc, raid_cfg_p0_sz; 2473 2474 *vol_hdl = 0; 2475 memset(&cfg_req, 0, sizeof(struct leapraid_cfg_req)); 2476 cfg_req.func = LEAPRAID_FUNC_CONFIG_OP; 2477 cfg_req.action = LEAPRAID_CFG_ACT_PAGE_HEADER; 2478 cfg_req.header.page_type = LEAPRAID_CFG_PT_EXTENDED; 2479 cfg_req.ext_page_type = LEAPRAID_CFG_EXTPT_RAID_CONFIG; 2480 cfg_req.header.page_num = LEAPRAID_CFG_PAGE_NUM_VOL0; 2481 2482 leapraid_build_nodata_mpi_sg(adapter, &cfg_req.page_buf_sge); 2483 rc = leapraid_request_cfg_pg_header(adapter, &cfg_req, &cfg_rep); 2484 if (rc) 2485 return rc; 2486 2487 cfg_req.action = LEAPRAID_CFG_ACT_PAGE_READ_CUR; 2488 raid_cfg_p0_sz = le16_to_cpu(cfg_rep.ext_page_len) * 2489 LEAPRAID_CFG_UNIT_SIZE; 2490 raid_cfg_p0 = kmalloc(raid_cfg_p0_sz, GFP_KERNEL); 2491 if (!raid_cfg_p0) 2492 return -ENOMEM; 2493 2494 real_cfg_pg_sz = (cfg_req.header.page_len) ? 2495 cfg_req.header.page_len * LEAPRAID_CFG_UNIT_SIZE : 2496 le16_to_cpu(cfg_rep.ext_page_len) * LEAPRAID_CFG_UNIT_SIZE; 2497 2498 real_cfg_pg_addr = dma_alloc_coherent(&adapter->pdev->dev, 2499 real_cfg_pg_sz, &real_cfg_pg_dma, 2500 GFP_KERNEL); 2501 if (!real_cfg_pg_addr) { 2502 rc = -ENOMEM; 2503 goto out_free; 2504 } 2505 2506 memset(raid_cfg_p0, 0, raid_cfg_p0_sz); 2507 leapraid_single_mpi_sg_append(adapter, 2508 &cfg_req.page_buf_sge, 2509 ((LEAPRAID_SGE_FLG_SIMPLE_ONE | 2510 LEAPRAID_SGE_FLG_LAST_ONE | 2511 LEAPRAID_SGE_FLG_EOB | 2512 LEAPRAID_SGE_FLG_EOL) << 2513 LEAPRAID_SGE_FLG_SHIFT) | 2514 real_cfg_pg_sz, 2515 real_cfg_pg_dma); 2516 memset(real_cfg_pg_addr, 0, 2517 min_t(u16, real_cfg_pg_sz, raid_cfg_p0_sz)); 2518 2519 rc = leapraid_cfg_get_volume_hdl_dispatch(adapter, 2520 &cfg_req, &cfg_rep, 2521 raid_cfg_p0, 2522 real_cfg_pg_addr, 2523 real_cfg_pg_sz, 2524 raid_cfg_p0_sz, 2525 pd_hdl, vol_hdl); 2526 2527 out_free: 2528 if (real_cfg_pg_addr) 2529 dma_free_coherent(&adapter->pdev->dev, 2530 real_cfg_pg_sz, real_cfg_pg_addr, 2531 real_cfg_pg_dma); 2532 kfree(raid_cfg_p0); 2533 return rc; 2534 } 2535 2536 static int leapraid_get_adapter_phys(struct leapraid_adapter *adapter, 2537 u8 *nr_phys) 2538 { 2539 struct leapraid_sas_io_unit_p0 sas_io_unit_page0; 2540 union cfg_param_1 cfgp1 = {0}; 2541 union cfg_param_2 cfgp2 = {0}; 2542 int rc; 2543 2544 *nr_phys = 0; 2545 cfgp1.size = sizeof(struct leapraid_sas_io_unit_p0); 2546 rc = leapraid_op_config_page(adapter, &sas_io_unit_page0, cfgp1, 2547 cfgp2, GET_SAS_IOUNIT_PG0); 2548 if (rc) 2549 return rc; 2550 2551 *nr_phys = sas_io_unit_page0.phy_num; 2552 2553 return 0; 2554 } 2555 2556 static int leapraid_cfg_get_number_pds(struct leapraid_adapter *adapter, 2557 u16 hdl, u8 *num_pds) 2558 { 2559 union cfg_param_1 cfgp1 = {0}; 2560 union cfg_param_2 cfgp2 = {0}; 2561 struct leapraid_raidvol_p0 raidvol_p0; 2562 int rc; 2563 2564 *num_pds = 0; 2565 cfgp1.size = sizeof(struct leapraid_raidvol_p0); 2566 cfgp2.handle = hdl; 2567 rc = leapraid_op_config_page(adapter, &raidvol_p0, cfgp1, 2568 cfgp2, GET_RAID_VOLUME_PG0); 2569 if (!rc) 2570 *num_pds = raidvol_p0.num_phys_disks; 2571 2572 return rc; 2573 } 2574 2575 int leapraid_cfg_get_volume_wwid(struct leapraid_adapter *adapter, 2576 u16 vol_hdl, u64 *wwid) 2577 { 2578 union cfg_param_1 cfgp1 = {0}; 2579 union cfg_param_2 cfgp2 = {0}; 2580 struct leapraid_raidvol_p1 raidvol_p1; 2581 int rc; 2582 2583 *wwid = 0; 2584 cfgp1.form = LEAPRAID_RAID_VOL_CFG_PGAD_HDL; 2585 cfgp2.handle = vol_hdl; 2586 rc = leapraid_op_config_page(adapter, &raidvol_p1, cfgp1, 2587 cfgp2, GET_RAID_VOLUME_PG1); 2588 if (!rc) 2589 *wwid = le64_to_cpu(raidvol_p1.wwid); 2590 2591 return rc; 2592 } 2593 2594 static int leapraid_get_sas_io_unit_page0( 2595 struct leapraid_adapter *adapter, 2596 struct leapraid_sas_io_unit_p0 *sas_io_unit_p0, 2597 u16 sas_iou_pg0_sz) 2598 { 2599 union cfg_param_1 cfgp1 = {0}; 2600 union cfg_param_2 cfgp2 = {0}; 2601 2602 cfgp1.size = sas_iou_pg0_sz; 2603 return leapraid_op_config_page(adapter, sas_io_unit_p0, cfgp1, 2604 cfgp2, GET_SAS_IOUNIT_PG0); 2605 } 2606 2607 static int leapraid_get_sas_address(struct leapraid_adapter *adapter, 2608 u16 hdl, u64 *sas_address) 2609 { 2610 union cfg_param_1 cfgp1 = {0}; 2611 union cfg_param_2 cfgp2 = {0}; 2612 struct leapraid_sas_dev_p0 sas_dev_p0; 2613 2614 *sas_address = 0; 2615 cfgp1.form = LEAPRAID_SAS_DEV_CFG_PGAD_HDL; 2616 cfgp2.handle = hdl; 2617 if (leapraid_op_config_page(adapter, &sas_dev_p0, cfgp1, 2618 cfgp2, GET_SAS_DEVICE_PG0)) 2619 return -ENXIO; 2620 2621 if (hdl <= adapter->dev_topo.card.phys_num && 2622 (!(le32_to_cpu(sas_dev_p0.dev_info) & LEAPRAID_DEVTYP_SEP))) 2623 *sas_address = adapter->dev_topo.card.sas_address; 2624 else 2625 *sas_address = le64_to_cpu(sas_dev_p0.sas_address); 2626 2627 return 0; 2628 } 2629 2630 int leapraid_get_volume_cap(struct leapraid_adapter *adapter, 2631 struct leapraid_raid_volume *raid_volume) 2632 { 2633 union cfg_param_1 cfgp1 = {0}; 2634 union cfg_param_2 cfgp2 = {0}; 2635 struct leapraid_raidvol_p0 *raidvol_p0; 2636 struct leapraid_sas_dev_p0 sas_dev_p0; 2637 struct leapraid_raidpd_p0 raidpd_p0; 2638 u8 num_pds; 2639 u16 sz; 2640 int rc = 0; 2641 2642 if (leapraid_cfg_get_number_pds(adapter, raid_volume->hdl, 2643 &num_pds) || !num_pds) 2644 return -EFAULT; 2645 2646 raid_volume->pd_num = num_pds; 2647 sz = offsetof(struct leapraid_raidvol_p0, phys_disk) + 2648 (num_pds * sizeof(struct leapraid_raidvol0_phys_disk)); 2649 raidvol_p0 = kzalloc(sz, GFP_KERNEL); 2650 if (!raidvol_p0) 2651 return -ENOMEM; 2652 2653 cfgp1.size = sz; 2654 cfgp2.handle = raid_volume->hdl; 2655 if (leapraid_op_config_page(adapter, raidvol_p0, cfgp1, cfgp2, 2656 GET_RAID_VOLUME_PG0)) { 2657 rc = -EFAULT; 2658 goto out_cleanup; 2659 } 2660 2661 raid_volume->vol_type = raidvol_p0->volume_type; 2662 cfgp1.form = LEAPRAID_PHYSDISK_CFG_PGAD_PHYSDISKNUM; 2663 cfgp2.form_specific = raidvol_p0->phys_disk[0].phys_disk_num; 2664 if (!(leapraid_op_config_page(adapter, &raidpd_p0, cfgp1, cfgp2, 2665 GET_PHY_DISK_PG0))) { 2666 cfgp1.form = LEAPRAID_SAS_DEV_CFG_PGAD_HDL; 2667 cfgp2.handle = le16_to_cpu(raidpd_p0.dev_hdl); 2668 if (!(leapraid_op_config_page(adapter, &sas_dev_p0, cfgp1, 2669 cfgp2, GET_SAS_DEVICE_PG0))) 2670 raid_volume->dev_info = 2671 le32_to_cpu(sas_dev_p0.dev_info); 2672 } 2673 2674 out_cleanup: 2675 kfree(raidvol_p0); 2676 return rc; 2677 } 2678 2679 static bool leapraid_should_skip_poll_work(struct leapraid_adapter *adapter) 2680 { 2681 unsigned long flags; 2682 bool skip; 2683 2684 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags); 2685 skip = adapter->access_ctrl.shost_recovering || 2686 adapter->access_ctrl.pcie_recovering || 2687 adapter->access_ctrl.host_removing; 2688 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags); 2689 2690 return skip; 2691 } 2692 2693 static void leapraid_fw_log_work(struct work_struct *work) 2694 { 2695 struct leapraid_adapter *adapter = container_of(work, 2696 struct leapraid_adapter, fw_log_desc.fw_log_work.work); 2697 struct leapraid_fw_log_info *infom; 2698 struct leapraid_reg_base __iomem *iomem_base; 2699 unsigned long flags; 2700 2701 if (leapraid_should_skip_poll_work(adapter)) 2702 goto scheduled_timer; 2703 2704 infom = (struct leapraid_fw_log_info *) 2705 (adapter->fw_log_desc.fw_log_buffer + 2706 LEAPRAID_SYS_LOG_BUF_SIZE); 2707 2708 iomem_base = adapter->iomem_base; 2709 if (adapter->fw_log_desc.fw_log_init_flag == 0) { 2710 infom->user_position = 2711 leapraid_readl(&iomem_base->host_log_buf_pos); 2712 infom->adapter_position = 2713 leapraid_readl(&iomem_base->adapter_log_buf_pos); 2714 adapter->fw_log_desc.fw_log_init_flag++; 2715 } 2716 2717 writel(infom->user_position, &iomem_base->host_log_buf_pos); 2718 infom->adapter_position = 2719 leapraid_readl(&iomem_base->adapter_log_buf_pos); 2720 2721 scheduled_timer: 2722 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags); 2723 if (adapter->fw_log_desc.fw_log_wq) 2724 queue_delayed_work( 2725 adapter->fw_log_desc.fw_log_wq, 2726 &adapter->fw_log_desc.fw_log_work, 2727 msecs_to_jiffies(LEAPRAID_PCIE_LOG_POLLING_INTERVAL)); 2728 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags); 2729 } 2730 2731 void leapraid_fw_log_stop(struct leapraid_adapter *adapter) 2732 { 2733 struct workqueue_struct *wq; 2734 unsigned long flags; 2735 2736 if (!adapter->fw_log_desc.open_pcie_trace) 2737 return; 2738 2739 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags); 2740 wq = adapter->fw_log_desc.fw_log_wq; 2741 adapter->fw_log_desc.fw_log_wq = NULL; 2742 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags); 2743 if (wq) { 2744 if (!cancel_delayed_work_sync(&adapter->fw_log_desc 2745 .fw_log_work)) 2746 flush_workqueue(wq); 2747 destroy_workqueue(wq); 2748 } 2749 } 2750 2751 void leapraid_fw_log_start(struct leapraid_adapter *adapter) 2752 { 2753 unsigned long flags; 2754 2755 if (!adapter->fw_log_desc.open_pcie_trace) 2756 return; 2757 2758 if (adapter->fw_log_desc.fw_log_wq) 2759 return; 2760 2761 INIT_DELAYED_WORK(&adapter->fw_log_desc.fw_log_work, 2762 leapraid_fw_log_work); 2763 snprintf(adapter->fw_log_desc.fw_log_wq_name, 2764 sizeof(adapter->fw_log_desc.fw_log_wq_name), 2765 "poll_%s%u_fw_log", 2766 LEAPRAID_DRIVER_NAME, adapter->adapter_attr.id); 2767 adapter->fw_log_desc.fw_log_wq = 2768 create_singlethread_workqueue( 2769 adapter->fw_log_desc.fw_log_wq_name); 2770 if (!adapter->fw_log_desc.fw_log_wq) 2771 return; 2772 2773 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags); 2774 if (adapter->fw_log_desc.fw_log_wq) 2775 queue_delayed_work( 2776 adapter->fw_log_desc.fw_log_wq, 2777 &adapter->fw_log_desc.fw_log_work, 2778 msecs_to_jiffies(LEAPRAID_PCIE_LOG_POLLING_INTERVAL)); 2779 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags); 2780 } 2781 2782 static void leapraid_check_scheduled_fault_work(struct work_struct *work) 2783 { 2784 struct leapraid_adapter *adapter; 2785 unsigned long flags; 2786 u32 adapter_state; 2787 int rc; 2788 2789 adapter = container_of(work, struct leapraid_adapter, 2790 reset_desc.fault_reset_work.work); 2791 2792 if (leapraid_should_skip_poll_work(adapter)) 2793 goto scheduled_timer; 2794 2795 adapter_state = leapraid_get_adapter_state(adapter); 2796 if (adapter_state != LEAPRAID_DB_OPERATIONAL) { 2797 dev_info(&adapter->pdev->dev, "%s:%d: call hard_reset 0x%x\n", 2798 __func__, __LINE__, adapter_state); 2799 rc = leapraid_hard_reset_handler(adapter, FULL_RESET); 2800 adapter_state = leapraid_get_adapter_state(adapter); 2801 if (rc && adapter_state != LEAPRAID_DB_OPERATIONAL) { 2802 dev_err(&adapter->pdev->dev, 2803 "%s: Hard reset failed, state=0x%x rc=%d\n", 2804 __func__, adapter_state, rc); 2805 return; 2806 } 2807 } 2808 2809 scheduled_timer: 2810 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags); 2811 if (adapter->reset_desc.fault_reset_wq) 2812 queue_delayed_work( 2813 adapter->reset_desc.fault_reset_wq, 2814 &adapter->reset_desc.fault_reset_work, 2815 msecs_to_jiffies(LEAPRAID_FAULT_POLLING_INTERVAL)); 2816 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags); 2817 } 2818 2819 void leapraid_check_scheduled_fault_start(struct leapraid_adapter *adapter) 2820 { 2821 unsigned long flags; 2822 2823 if (adapter->reset_desc.fault_reset_wq) 2824 return; 2825 2826 INIT_DELAYED_WORK(&adapter->reset_desc.fault_reset_work, 2827 leapraid_check_scheduled_fault_work); 2828 snprintf(adapter->reset_desc.fault_reset_wq_name, 2829 sizeof(adapter->reset_desc.fault_reset_wq_name), 2830 "poll_%s%u_status", 2831 LEAPRAID_DRIVER_NAME, adapter->adapter_attr.id); 2832 adapter->reset_desc.fault_reset_wq = 2833 create_singlethread_workqueue( 2834 adapter->reset_desc.fault_reset_wq_name); 2835 if (!adapter->reset_desc.fault_reset_wq) { 2836 dev_err(&adapter->pdev->dev, 2837 "Create single thread workqueue failed!\n"); 2838 return; 2839 } 2840 2841 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags); 2842 if (adapter->reset_desc.fault_reset_wq) 2843 queue_delayed_work( 2844 adapter->reset_desc.fault_reset_wq, 2845 &adapter->reset_desc.fault_reset_work, 2846 msecs_to_jiffies(LEAPRAID_FAULT_POLLING_INTERVAL)); 2847 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags); 2848 } 2849 2850 void leapraid_check_scheduled_fault_stop(struct leapraid_adapter *adapter) 2851 { 2852 struct workqueue_struct *wq; 2853 unsigned long flags; 2854 2855 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags); 2856 wq = adapter->reset_desc.fault_reset_wq; 2857 adapter->reset_desc.fault_reset_wq = NULL; 2858 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags); 2859 2860 if (!wq) 2861 return; 2862 2863 if (!cancel_delayed_work_sync(&adapter->reset_desc.fault_reset_work)) 2864 flush_workqueue(wq); 2865 destroy_workqueue(wq); 2866 } 2867 2868 static void leapraid_overheat_work(struct work_struct *work) 2869 { 2870 struct leapraid_overheat_desc *desc; 2871 struct leapraid_adapter *adapter; 2872 struct workqueue_struct *wq; 2873 struct Scsi_Host *shost; 2874 struct pci_dev *pdev; 2875 unsigned long flags; 2876 2877 desc = container_of(work, struct leapraid_overheat_desc, 2878 fault_overheat_work); 2879 adapter = container_of(desc, struct leapraid_adapter, overheat_desc); 2880 pdev = adapter->pdev; 2881 shost = pci_get_drvdata(pdev); 2882 2883 if (!shost) { 2884 dev_err(&pdev->dev, 2885 "Overheat processing failed: invalid host/adapter\n"); 2886 atomic_set(&adapter->overheat_desc.thermal_alert, 0); 2887 wake_up(&adapter->scan_dev_desc.wait_driver_loading); 2888 return; 2889 } 2890 2891 if (adapter->access_ctrl.host_removing) { 2892 atomic_set(&adapter->overheat_desc.thermal_alert, 0); 2893 wake_up(&adapter->scan_dev_desc.wait_driver_loading); 2894 return; 2895 } 2896 2897 adapter->access_ctrl.host_removing = 1; 2898 adapter->access_ctrl.shost_recover_async = 0; 2899 adapter->scan_dev_desc.scan_start = 0; 2900 adapter->scan_dev_desc.wait_scan_dev_done = 0; 2901 adapter->scan_dev_desc.driver_loading = 0; 2902 wake_up(&adapter->access_ctrl.shost_recover_wq); 2903 wake_up(&adapter->scan_dev_desc.wait_driver_loading); 2904 2905 leapraid_mask_int(adapter); 2906 2907 leapraid_check_scheduled_fault_stop(adapter); 2908 leapraid_fw_log_stop(adapter); 2909 leapraid_mq_polling_pause(adapter); 2910 2911 leapraid_clean_active_cmds(adapter); 2912 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags); 2913 wq = adapter->fw_evt_s.fw_evt_thread; 2914 adapter->fw_evt_s.fw_evt_thread = NULL; 2915 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags); 2916 if (wq) 2917 destroy_workqueue(wq); 2918 2919 sas_remove_host(shost); 2920 leapraid_cleanup_lists(adapter); 2921 atomic_set(&adapter->overheat_desc.thermal_alert, 0); 2922 wake_up(&adapter->scan_dev_desc.wait_driver_loading); 2923 dev_err(&pdev->dev, "%s: Suspend adapter due to overheat\n", __func__); 2924 } 2925 2926 static void leapraid_overheat_init(struct leapraid_adapter *adapter) 2927 { 2928 if (adapter->overheat_desc.fault_overheat_wq) 2929 return; 2930 2931 atomic_set(&adapter->overheat_desc.thermal_alert, 0); 2932 snprintf(adapter->overheat_desc.fault_overheat_wq_name, 2933 sizeof(adapter->overheat_desc.fault_overheat_wq_name), 2934 "driver_%s%u_overheat", 2935 LEAPRAID_DRIVER_NAME, 2936 adapter->adapter_attr.id); 2937 adapter->overheat_desc.fault_overheat_wq = 2938 create_singlethread_workqueue( 2939 adapter->overheat_desc.fault_overheat_wq_name); 2940 if (!adapter->overheat_desc.fault_overheat_wq) { 2941 dev_err(&adapter->pdev->dev, 2942 "Failed to create overheat workqueue\n"); 2943 return; 2944 } 2945 2946 INIT_WORK(&adapter->overheat_desc.fault_overheat_work, 2947 leapraid_overheat_work); 2948 } 2949 2950 void leapraid_overheat_cleanup(struct leapraid_adapter *adapter) 2951 { 2952 struct workqueue_struct *wq; 2953 2954 wq = xchg(&adapter->overheat_desc.fault_overheat_wq, NULL); 2955 if (!wq) 2956 return; 2957 2958 cancel_work_sync(&adapter->overheat_desc.fault_overheat_work); 2959 destroy_workqueue(wq); 2960 } 2961 2962 static void leapraid_fw_work(struct leapraid_adapter *adapter, 2963 struct leapraid_fw_evt_work *fw_evt); 2964 2965 static void leapraid_fw_evt_free(struct kref *r) 2966 { 2967 struct leapraid_fw_evt_work *fw_evt; 2968 2969 fw_evt = container_of(r, struct leapraid_fw_evt_work, refcnt); 2970 2971 kfree(fw_evt->evt_data); 2972 kfree(fw_evt); 2973 } 2974 2975 static void leapraid_fw_evt_get(struct leapraid_fw_evt_work *fw_evt) 2976 { 2977 kref_get(&fw_evt->refcnt); 2978 } 2979 2980 static void leapraid_fw_evt_put(struct leapraid_fw_evt_work *fw_work) 2981 { 2982 kref_put(&fw_work->refcnt, leapraid_fw_evt_free); 2983 } 2984 2985 static struct leapraid_fw_evt_work *leapraid_alloc_fw_evt_work(void) 2986 { 2987 struct leapraid_fw_evt_work *fw_evt = 2988 kzalloc(sizeof(*fw_evt), GFP_ATOMIC); 2989 2990 if (fw_evt) 2991 kref_init(&fw_evt->refcnt); 2992 2993 return fw_evt; 2994 } 2995 2996 static void leapraid_run_fw_evt_work(struct work_struct *work) 2997 { 2998 struct leapraid_fw_evt_work *fw_evt = 2999 container_of(work, struct leapraid_fw_evt_work, work); 3000 3001 leapraid_fw_work(fw_evt->adapter, fw_evt); 3002 } 3003 3004 static void leapraid_fw_evt_add(struct leapraid_adapter *adapter, 3005 struct leapraid_fw_evt_work *fw_evt) 3006 { 3007 unsigned long flags; 3008 3009 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags); 3010 if (adapter->access_ctrl.host_removing || 3011 adapter->access_ctrl.pcie_recovering || 3012 !adapter->fw_evt_s.fw_evt_thread) { 3013 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags); 3014 return; 3015 } 3016 3017 leapraid_fw_evt_get(fw_evt); 3018 INIT_LIST_HEAD(&fw_evt->list); 3019 list_add_tail(&fw_evt->list, &adapter->fw_evt_s.fw_evt_list); 3020 INIT_WORK(&fw_evt->work, leapraid_run_fw_evt_work); 3021 leapraid_fw_evt_get(fw_evt); 3022 queue_work(adapter->fw_evt_s.fw_evt_thread, &fw_evt->work); 3023 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags); 3024 } 3025 3026 static void leapraid_del_fw_evt_from_list(struct leapraid_adapter *adapter, 3027 struct leapraid_fw_evt_work *fw_evt) 3028 { 3029 unsigned long flags; 3030 3031 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags); 3032 if (!list_empty(&fw_evt->list)) { 3033 list_del_init(&fw_evt->list); 3034 leapraid_fw_evt_put(fw_evt); 3035 } 3036 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags); 3037 } 3038 3039 static struct leapraid_fw_evt_work *leapraid_next_fw_evt( 3040 struct leapraid_adapter *adapter) 3041 { 3042 struct leapraid_fw_evt_work *fw_evt = NULL; 3043 unsigned long flags; 3044 3045 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags); 3046 if (!list_empty(&adapter->fw_evt_s.fw_evt_list)) { 3047 fw_evt = list_first_entry(&adapter->fw_evt_s.fw_evt_list, 3048 struct leapraid_fw_evt_work, list); 3049 list_del_init(&fw_evt->list); 3050 } 3051 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags); 3052 return fw_evt; 3053 } 3054 3055 void leapraid_clean_active_fw_evt(struct leapraid_adapter *adapter) 3056 { 3057 struct leapraid_fw_evt_work *fw_evt; 3058 unsigned long flags; 3059 bool in_fw_evt_context; 3060 bool rc; 3061 3062 if ((list_empty(&adapter->fw_evt_s.fw_evt_list) && 3063 !adapter->fw_evt_s.cur_evt) || !adapter->fw_evt_s.fw_evt_thread) 3064 return; 3065 3066 adapter->fw_evt_s.fw_evt_cleanup = 1; 3067 if (adapter->access_ctrl.shost_recovering && 3068 adapter->fw_evt_s.cur_evt) 3069 adapter->fw_evt_s.cur_evt->ignore = 1; 3070 3071 while ((fw_evt = leapraid_next_fw_evt(adapter))) { 3072 rc = cancel_work_sync(&fw_evt->work); 3073 if (rc) 3074 leapraid_fw_evt_put(fw_evt); 3075 leapraid_fw_evt_put(fw_evt); 3076 } 3077 3078 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags); 3079 fw_evt = adapter->fw_evt_s.cur_evt; 3080 if (fw_evt) { 3081 in_fw_evt_context = adapter->fw_evt_s.cur_evt_task == current; 3082 leapraid_fw_evt_get(fw_evt); 3083 } 3084 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags); 3085 if (fw_evt) { 3086 if (!in_fw_evt_context) 3087 cancel_work_sync(&fw_evt->work); 3088 leapraid_fw_evt_put(fw_evt); 3089 } 3090 3091 adapter->fw_evt_s.fw_evt_cleanup = 0; 3092 } 3093 3094 static void leapraid_internal_dev_ublk(struct scsi_device *sdev, 3095 struct leapraid_sdev_priv *sdev_priv) 3096 { 3097 int rc; 3098 3099 sdev_printk(KERN_WARNING, sdev, 3100 "hdl 0x%04x: Now internal unblkg dev\n", 3101 sdev_priv->starget_priv->hdl); 3102 sdev_priv->block = 0; 3103 rc = scsi_internal_device_unblock_nowait(sdev, SDEV_RUNNING); 3104 if (rc == -EINVAL) { 3105 sdev_printk(KERN_WARNING, sdev, 3106 "hdl 0x%04x: unblkg failed, rc=%d\n", 3107 sdev_priv->starget_priv->hdl, rc); 3108 sdev_priv->block = 1; 3109 rc = scsi_internal_device_block_nowait(sdev); 3110 if (rc) 3111 sdev_printk(KERN_WARNING, sdev, 3112 "hdl 0x%04x: Earlier ublkg err, rc=%d\n", 3113 sdev_priv->starget_priv->hdl, rc); 3114 3115 sdev_priv->block = 0; 3116 rc = scsi_internal_device_unblock_nowait(sdev, SDEV_RUNNING); 3117 if (rc) 3118 sdev_printk(KERN_WARNING, sdev, 3119 "hdl 0x%04x: ublkg failed again, rc=%d\n", 3120 sdev_priv->starget_priv->hdl, rc); 3121 } 3122 } 3123 3124 static void leapraid_ublk_io_dev(struct leapraid_adapter *adapter, 3125 u64 sas_addr, 3126 struct leapraid_card_port *card_port) 3127 { 3128 struct leapraid_sdev_priv *sdev_priv; 3129 struct scsi_device *sdev; 3130 3131 shost_for_each_device(sdev, adapter->shost) { 3132 sdev_priv = sdev->hostdata; 3133 if (!sdev_priv || !sdev_priv->starget_priv) 3134 continue; 3135 3136 if (sdev_priv->starget_priv->sas_address != sas_addr) 3137 continue; 3138 3139 if (sdev_priv->starget_priv->card_port != card_port) 3140 continue; 3141 3142 if (sdev_priv->block) 3143 leapraid_internal_dev_ublk(sdev, sdev_priv); 3144 3145 scsi_device_set_state(sdev, SDEV_OFFLINE); 3146 } 3147 } 3148 3149 static void leapraid_ublk_io_all_dev(struct leapraid_adapter *adapter) 3150 { 3151 struct leapraid_sdev_priv *sdev_priv; 3152 struct leapraid_starget_priv *stgt_priv; 3153 struct scsi_device *sdev; 3154 3155 shost_for_each_device(sdev, adapter->shost) { 3156 sdev_priv = sdev->hostdata; 3157 3158 if (!sdev_priv) 3159 continue; 3160 3161 stgt_priv = sdev_priv->starget_priv; 3162 if (!stgt_priv || stgt_priv->deleted) 3163 continue; 3164 3165 if (!sdev_priv->block) 3166 continue; 3167 3168 sdev_printk(KERN_WARNING, sdev, "hdl 0x%04x: blkg...\n", 3169 sdev_priv->starget_priv->hdl); 3170 leapraid_internal_dev_ublk(sdev, sdev_priv); 3171 continue; 3172 } 3173 } 3174 3175 static void leapraid_internal_dev_blk( 3176 struct scsi_device *sdev, 3177 struct leapraid_sdev_priv *sdev_priv) 3178 { 3179 int rc; 3180 3181 sdev_printk(KERN_INFO, sdev, "Internal blkg hdl 0x%04x\n", 3182 sdev_priv->starget_priv->hdl); 3183 sdev_priv->block = 1; 3184 rc = scsi_internal_device_block_nowait(sdev); 3185 if (rc == -EINVAL) 3186 sdev_printk(KERN_WARNING, sdev, 3187 "hdl 0x%04x: blkg failed, rc=%d\n", 3188 rc, sdev_priv->starget_priv->hdl); 3189 } 3190 3191 static void leapraid_imm_blkio_to_end_dev(struct leapraid_adapter *adapter, 3192 struct leapraid_sas_port *sas_port) 3193 { 3194 struct leapraid_sdev_priv *sdev_priv; 3195 struct leapraid_sas_dev *sas_dev; 3196 struct scsi_device *sdev; 3197 unsigned long flags; 3198 3199 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 3200 sas_dev = leapraid_hold_lock_get_sas_dev_by_addr( 3201 adapter, 3202 sas_port->remote_identify.sas_address, 3203 sas_port->card_port); 3204 3205 if (sas_dev) { 3206 shost_for_each_device(sdev, adapter->shost) { 3207 sdev_priv = sdev->hostdata; 3208 if (!sdev_priv) 3209 continue; 3210 3211 if (sdev_priv->starget_priv->hdl != sas_dev->hdl) 3212 continue; 3213 3214 if (sdev_priv->block) 3215 continue; 3216 3217 if (sas_dev && sas_dev->pend_sas_rphy_add) 3218 continue; 3219 3220 if (sdev_priv->sep) { 3221 sdev_printk(KERN_INFO, sdev, 3222 "skip dev blk: sep hdl 0x%04x\n", 3223 sdev_priv->starget_priv->hdl); 3224 continue; 3225 } 3226 3227 leapraid_internal_dev_blk(sdev, sdev_priv); 3228 } 3229 3230 leapraid_sdev_put(sas_dev); 3231 } 3232 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 3233 } 3234 3235 static void leapraid_imm_blkio_set_end_dev_blk_hdls( 3236 struct leapraid_adapter *adapter, 3237 struct leapraid_topo_node *topo_node_exp) 3238 { 3239 struct leapraid_sas_port *sas_port; 3240 3241 list_for_each_entry(sas_port, 3242 &topo_node_exp->sas_port_list, port_list) { 3243 if (sas_port->remote_identify.device_type == SAS_END_DEVICE) 3244 leapraid_imm_blkio_to_end_dev(adapter, sas_port); 3245 } 3246 } 3247 3248 static void leapraid_imm_blkio_to_kids_attchd_to_ex( 3249 struct leapraid_adapter *adapter, 3250 struct leapraid_topo_node *topo_node_exp); 3251 3252 static void leapraid_imm_blkio_to_sib_exp( 3253 struct leapraid_adapter *adapter, 3254 struct leapraid_topo_node *topo_node_exp) 3255 { 3256 struct leapraid_topo_node *topo_node_exp_sib; 3257 struct leapraid_sas_port *sas_port; 3258 3259 list_for_each_entry(sas_port, 3260 &topo_node_exp->sas_port_list, port_list) { 3261 if (sas_port->remote_identify.device_type == 3262 SAS_EDGE_EXPANDER_DEVICE || 3263 sas_port->remote_identify.device_type == 3264 SAS_FANOUT_EXPANDER_DEVICE) { 3265 topo_node_exp_sib = 3266 leapraid_exp_find_by_sas_address( 3267 adapter, 3268 sas_port->remote_identify.sas_address, 3269 sas_port->card_port); 3270 leapraid_imm_blkio_to_kids_attchd_to_ex( 3271 adapter, 3272 topo_node_exp_sib); 3273 } 3274 } 3275 } 3276 3277 static void leapraid_imm_blkio_to_kids_attchd_to_ex( 3278 struct leapraid_adapter *adapter, 3279 struct leapraid_topo_node *topo_node_exp) 3280 { 3281 if (!topo_node_exp) 3282 return; 3283 3284 leapraid_imm_blkio_set_end_dev_blk_hdls(adapter, topo_node_exp); 3285 3286 leapraid_imm_blkio_to_sib_exp(adapter, topo_node_exp); 3287 } 3288 3289 static void leapraid_report_sdev_directly(struct leapraid_adapter *adapter, 3290 struct leapraid_sas_dev *sas_dev) 3291 { 3292 struct leapraid_sas_port *sas_port; 3293 3294 sas_port = leapraid_transport_port_add(adapter, 3295 sas_dev->hdl, 3296 sas_dev->parent_sas_addr, 3297 sas_dev->card_port); 3298 if (!sas_port) { 3299 leapraid_sas_dev_remove(adapter, sas_dev); 3300 return; 3301 } 3302 3303 if (!sas_dev->starget) { 3304 if (!adapter->scan_dev_desc.driver_loading) { 3305 leapraid_transport_port_remove( 3306 adapter, 3307 sas_dev->sas_addr, 3308 sas_dev->parent_sas_addr, 3309 sas_dev->card_port); 3310 leapraid_sas_dev_remove(adapter, sas_dev); 3311 } 3312 return; 3313 } 3314 } 3315 3316 static struct leapraid_sas_dev *leapraid_init_sas_dev( 3317 struct leapraid_adapter *adapter, 3318 struct leapraid_sas_dev_p0 *sas_dev_pg0, 3319 struct leapraid_card_port *card_port, u16 hdl, 3320 u64 parent_sas_addr, u64 sas_addr, u32 dev_info) 3321 { 3322 struct leapraid_sas_dev *sas_dev; 3323 struct leapraid_enc_node *enc_dev; 3324 unsigned long flags; 3325 3326 sas_dev = kzalloc_obj(*sas_dev); 3327 if (!sas_dev) 3328 return NULL; 3329 3330 kref_init(&sas_dev->refcnt); 3331 sas_dev->hdl = hdl; 3332 sas_dev->dev_info = dev_info; 3333 sas_dev->sas_addr = sas_addr; 3334 sas_dev->card_port = card_port; 3335 sas_dev->parent_sas_addr = parent_sas_addr; 3336 sas_dev->phy = sas_dev_pg0->phy_num; 3337 sas_dev->enc_hdl = le16_to_cpu(sas_dev_pg0->enc_hdl); 3338 sas_dev->dev_name = le64_to_cpu(sas_dev_pg0->dev_name); 3339 sas_dev->port_connection = sas_dev_pg0->max_port_connections; 3340 sas_dev->slot = sas_dev->enc_hdl ? le16_to_cpu(sas_dev_pg0->slot) : 0; 3341 if (le16_to_cpu(sas_dev_pg0->flg) & 3342 LEAPRAID_SAS_DEV_P0_FLG_ENC_LEVEL_VALID) { 3343 sas_dev->enc_level = sas_dev_pg0->enc_level; 3344 memcpy(sas_dev->connector_name, 3345 sas_dev_pg0->connector_name, 3346 LEAPRAID_SAS_DEV_P0_CON_NAME_LEN); 3347 sas_dev->connector_name[LEAPRAID_SAS_DEV_P0_CON_NAME_LEN] = 3348 '\0'; 3349 } else { 3350 sas_dev->enc_level = 0; 3351 sas_dev->connector_name[0] = '\0'; 3352 } 3353 if (sas_dev->enc_hdl) { 3354 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags); 3355 enc_dev = leapraid_enc_find_by_hdl(adapter, sas_dev->enc_hdl); 3356 if (enc_dev) 3357 sas_dev->enc_lid = le64_to_cpu(enc_dev->pg0.enc_lid); 3358 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags); 3359 } 3360 dev_info(&adapter->pdev->dev, 3361 "add dev: hdl=0x%x, SAS addr=0x%016llx, port connect=0x%x\n", 3362 hdl, sas_dev->sas_addr, sas_dev->port_connection); 3363 3364 return sas_dev; 3365 } 3366 3367 static void leapraid_add_dev(struct leapraid_adapter *adapter, u16 hdl) 3368 { 3369 union cfg_param_1 cfgp1 = {0}; 3370 union cfg_param_2 cfgp2 = {0}; 3371 struct leapraid_sas_dev_p0 sas_dev_pg0; 3372 struct leapraid_card_port *card_port; 3373 struct leapraid_sas_dev *sas_dev; 3374 unsigned long flags; 3375 u64 parent_sas_addr; 3376 u32 dev_info; 3377 u64 sas_addr; 3378 u8 port_id; 3379 3380 cfgp1.form = LEAPRAID_SAS_DEV_CFG_PGAD_HDL; 3381 cfgp2.handle = hdl; 3382 if (leapraid_op_config_page(adapter, &sas_dev_pg0, 3383 cfgp1, cfgp2, GET_SAS_DEVICE_PG0)) 3384 return; 3385 3386 dev_info = le32_to_cpu(sas_dev_pg0.dev_info); 3387 if (!(leapraid_is_end_dev(dev_info))) 3388 return; 3389 3390 sas_addr = le64_to_cpu(sas_dev_pg0.sas_address); 3391 if (!(le16_to_cpu(sas_dev_pg0.flg) & 3392 LEAPRAID_SAS_DEV_P0_FLG_DEV_PRESENT)) 3393 return; 3394 3395 port_id = sas_dev_pg0.physical_port; 3396 card_port = leapraid_get_port_by_id(adapter, port_id, false); 3397 if (!card_port) 3398 return; 3399 3400 sas_dev = leapraid_get_sas_dev_by_addr(adapter, sas_addr, card_port); 3401 if (sas_dev) { 3402 leapraid_sdev_put(sas_dev); 3403 return; 3404 } 3405 3406 if (leapraid_get_sas_address(adapter, 3407 le16_to_cpu(sas_dev_pg0.parent_dev_hdl), 3408 &parent_sas_addr)) 3409 return; 3410 3411 sas_dev = leapraid_init_sas_dev(adapter, &sas_dev_pg0, card_port, 3412 hdl, parent_sas_addr, sas_addr, 3413 dev_info); 3414 if (!sas_dev) 3415 return; 3416 3417 if (adapter->scan_dev_desc.wait_scan_dev_done) { 3418 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 3419 leapraid_sdev_get(sas_dev); 3420 list_add_tail(&sas_dev->list, 3421 &adapter->dev_topo.sas_dev_init_list); 3422 leapraid_check_boot_dev(adapter, sas_dev, 0); 3423 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 3424 } else { 3425 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 3426 leapraid_sdev_get(sas_dev); 3427 list_add_tail(&sas_dev->list, &adapter->dev_topo.sas_dev_list); 3428 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 3429 leapraid_report_sdev_directly(adapter, sas_dev); 3430 } 3431 leapraid_sdev_put(sas_dev); 3432 } 3433 3434 static void leapraid_remove_device(struct leapraid_adapter *adapter, 3435 struct leapraid_sas_dev *sas_dev) 3436 { 3437 struct leapraid_starget_priv *starget_priv; 3438 3439 leapraid_clear_cached_boot_dev(adapter, sas_dev, 0); 3440 if (sas_dev->led_on) { 3441 leapraid_set_led(adapter, sas_dev, false); 3442 sas_dev->led_on = 0; 3443 } 3444 3445 if (sas_dev->starget && sas_dev->starget->hostdata) { 3446 starget_priv = sas_dev->starget->hostdata; 3447 starget_priv->deleted = 1; 3448 leapraid_ublk_io_dev(adapter, 3449 sas_dev->sas_addr, sas_dev->card_port); 3450 starget_priv->hdl = LEAPRAID_INVALID_DEV_HANDLE; 3451 } 3452 3453 leapraid_transport_port_remove(adapter, 3454 sas_dev->sas_addr, 3455 sas_dev->parent_sas_addr, 3456 sas_dev->card_port); 3457 3458 dev_info(&adapter->pdev->dev, 3459 "remove dev: hdl=0x%04x, SAS addr=0x%016llx\n", 3460 sas_dev->hdl, (unsigned long long)sas_dev->sas_addr); 3461 } 3462 3463 static struct leapraid_vphy *leapraid_alloc_vphy( 3464 struct leapraid_adapter *adapter, 3465 u8 port_id, u8 phy_num) 3466 { 3467 struct leapraid_card_port *port; 3468 struct leapraid_vphy *vphy; 3469 3470 port = leapraid_get_port_by_id(adapter, port_id, false); 3471 if (!port) 3472 return NULL; 3473 3474 vphy = leapraid_get_vphy_by_phy(port, phy_num); 3475 if (vphy) 3476 return vphy; 3477 vphy = kzalloc_obj(*vphy); 3478 if (!vphy) 3479 return NULL; 3480 3481 if (!port->vphys_mask) 3482 INIT_LIST_HEAD(&port->vphys_list); 3483 3484 port->vphys_mask |= BIT(phy_num); 3485 vphy->phy_mask |= BIT(phy_num); 3486 list_add_tail(&vphy->list, &port->vphys_list); 3487 return vphy; 3488 } 3489 3490 static int leapraid_add_port_to_card_port_list( 3491 struct leapraid_adapter *adapter, 3492 u8 port_id, bool refresh) 3493 { 3494 struct leapraid_card_port *card_port; 3495 3496 card_port = leapraid_get_port_by_id(adapter, port_id, false); 3497 if (card_port) 3498 return 0; 3499 card_port = kzalloc_obj(*card_port); 3500 if (!card_port) 3501 return -ENOMEM; 3502 3503 card_port->port_id = port_id; 3504 dev_dbg(&adapter->pdev->dev, 3505 "port: %d is added to card_port list\n", 3506 card_port->port_id); 3507 3508 if (refresh && adapter->access_ctrl.shost_recovering) 3509 card_port->flg = LEAPRAID_CARD_PORT_FLG_NEW; 3510 list_add_tail(&card_port->list, &adapter->dev_topo.card_port_list); 3511 return 0; 3512 } 3513 3514 static int leapraid_add_card_phy(struct leapraid_adapter *adapter, 3515 struct leapraid_sas_io_unit_p0 *iou, 3516 int i) 3517 { 3518 struct leapraid_sas_phy_p0 phy_pg0; 3519 union cfg_param_1 cfgp1 = {0}; 3520 union cfg_param_2 cfgp2 = {0}; 3521 struct leapraid_topo_node *card = &adapter->dev_topo.card; 3522 u8 port_id; 3523 3524 cfgp1.phy_number = i; 3525 3526 if (leapraid_op_config_page(adapter, &phy_pg0, 3527 cfgp1, cfgp2, GET_PHY_PG0)) 3528 return -EINVAL; 3529 3530 port_id = iou->phy_info[i].port; 3531 3532 if (leapraid_add_port_to_card_port_list(adapter, port_id, false)) 3533 return -EINVAL; 3534 3535 if ((le32_to_cpu(phy_pg0.phy_info) & 3536 LEAPRAID_SAS_PHYINFO_VPHY) && 3537 ((phy_pg0.neg_link_rate >> 3538 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT) >= 3539 LEAPRAID_SAS_NEG_LINK_RATE_1_5)) { 3540 if (!leapraid_alloc_vphy(adapter, port_id, i)) 3541 return -ENOMEM; 3542 3543 card->card_phy[i].vphy = 1; 3544 } 3545 3546 card->card_phy[i].hdl = card->hdl; 3547 card->card_phy[i].phy_id = i; 3548 card->card_phy[i].card_port = 3549 leapraid_get_port_by_id(adapter, port_id, false); 3550 3551 leapraid_transport_add_card_phy(adapter, 3552 &card->card_phy[i], 3553 &phy_pg0, 3554 card->parent_dev); 3555 3556 return 0; 3557 } 3558 3559 static int leapraid_refresh_card_phy(struct leapraid_adapter *adapter, 3560 struct leapraid_sas_io_unit_p0 *iou, 3561 int i) 3562 { 3563 struct leapraid_topo_node *card = &adapter->dev_topo.card; 3564 struct leapraid_sas_phy_p0 phy_pg0; 3565 union cfg_param_1 cfgp1 = {0}; 3566 union cfg_param_2 cfgp2 = {0}; 3567 u16 attached_hdl; 3568 u32 dev_info; 3569 u8 link_rate; 3570 u8 port_id; 3571 3572 link_rate = iou->phy_info[i].neg_link_rate >> 3573 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT; 3574 port_id = iou->phy_info[i].port; 3575 if (leapraid_add_port_to_card_port_list(adapter, port_id, true)) 3576 return -EINVAL; 3577 3578 dev_info = le32_to_cpu(iou->phy_info[i].controller_phy_dev_info); 3579 if (dev_info & LEAPRAID_DEVTYP_SEP && 3580 link_rate >= LEAPRAID_SAS_NEG_LINK_RATE_1_5) { 3581 cfgp1.phy_number = i; 3582 3583 if (leapraid_op_config_page(adapter, &phy_pg0, 3584 cfgp1, cfgp2, GET_PHY_PG0)) 3585 return 0; 3586 3587 if (le32_to_cpu(phy_pg0.phy_info) & 3588 LEAPRAID_SAS_PHYINFO_VPHY) { 3589 if (!leapraid_alloc_vphy(adapter, port_id, i)) 3590 return -ENOMEM; 3591 card->card_phy[i].vphy = 1; 3592 } 3593 } 3594 3595 card->card_phy[i].hdl = card->hdl; 3596 3597 attached_hdl = le16_to_cpu(iou->phy_info[i].attached_dev_hdl); 3598 if (attached_hdl && link_rate < LEAPRAID_SAS_NEG_LINK_RATE_1_5) 3599 link_rate = LEAPRAID_SAS_NEG_LINK_RATE_1_5; 3600 3601 card->card_phy[i].card_port = 3602 leapraid_get_port_by_id(adapter, port_id, false); 3603 3604 if (!card->card_phy[i].phy) { 3605 cfgp1.phy_number = i; 3606 if (leapraid_op_config_page(adapter, &phy_pg0, 3607 cfgp1, cfgp2, GET_PHY_PG0)) 3608 return 0; 3609 3610 card->card_phy[i].phy_id = i; 3611 3612 leapraid_transport_add_card_phy(adapter, 3613 &card->card_phy[i], 3614 &phy_pg0, 3615 card->parent_dev); 3616 return 0; 3617 } 3618 3619 leapraid_transport_update_links(adapter, 3620 card->sas_address, 3621 attached_hdl, 3622 i, 3623 link_rate, 3624 card->card_phy[i].card_port); 3625 3626 return 0; 3627 } 3628 3629 static void leapraid_sas_host_add(struct leapraid_adapter *adapter, 3630 bool refresh) 3631 { 3632 union cfg_param_1 cfgp1 = {0}; 3633 union cfg_param_2 cfgp2 = {0}; 3634 struct leapraid_sas_dev_p0 sas_dev_pg0; 3635 struct leapraid_enc_p0 enc_pg0; 3636 struct leapraid_sas_io_unit_p0 *sas_iou_pg0; 3637 u16 sas_iou_pg0_sz; 3638 u8 phys_num; 3639 int i; 3640 int rc; 3641 3642 if (!refresh) { 3643 if (leapraid_get_adapter_phys(adapter, &phys_num) || !phys_num) 3644 return; 3645 3646 adapter->dev_topo.card.card_phy = 3647 kcalloc(phys_num, 3648 sizeof(struct leapraid_card_phy), GFP_KERNEL); 3649 if (!adapter->dev_topo.card.card_phy) 3650 return; 3651 3652 adapter->dev_topo.card.phys_num = phys_num; 3653 } 3654 3655 sas_iou_pg0_sz = 3656 offsetof(struct leapraid_sas_io_unit_p0, phy_info) + 3657 (adapter->dev_topo.card.phys_num * 3658 sizeof(struct leapraid_sas_io_unit0_phy_info)); 3659 sas_iou_pg0 = kzalloc(sas_iou_pg0_sz, GFP_KERNEL); 3660 if (!sas_iou_pg0) 3661 return; 3662 3663 if (leapraid_get_sas_io_unit_page0(adapter, 3664 sas_iou_pg0, 3665 sas_iou_pg0_sz)) 3666 goto out_free; 3667 3668 adapter->dev_topo.card.parent_dev = &adapter->shost->shost_gendev; 3669 adapter->dev_topo.card.hdl = 3670 le16_to_cpu(sas_iou_pg0->phy_info[0].controller_dev_hdl); 3671 for (i = 0; i < adapter->dev_topo.card.phys_num; i++) { 3672 if (!refresh) /* add */ 3673 rc = leapraid_add_card_phy(adapter, sas_iou_pg0, i); 3674 else /* refresh */ 3675 rc = leapraid_refresh_card_phy(adapter, 3676 sas_iou_pg0, 3677 i); 3678 if (rc) 3679 goto out_free; 3680 } 3681 3682 if (!refresh) { 3683 cfgp1.form = LEAPRAID_SAS_DEV_CFG_PGAD_HDL; 3684 cfgp2.handle = adapter->dev_topo.card.hdl; 3685 if (leapraid_op_config_page(adapter, &sas_dev_pg0, cfgp1, 3686 cfgp2, GET_SAS_DEVICE_PG0)) 3687 goto out_free; 3688 3689 adapter->dev_topo.card.enc_hdl = 3690 le16_to_cpu(sas_dev_pg0.enc_hdl); 3691 adapter->dev_topo.card.sas_address = 3692 le64_to_cpu(sas_dev_pg0.sas_address); 3693 dev_info(&adapter->pdev->dev, 3694 "add host: hdl=0x%04x, SAS addr=0x%016llx, phy=%d\n", 3695 adapter->dev_topo.card.hdl, 3696 (unsigned long long)adapter->dev_topo.card.sas_address, 3697 adapter->dev_topo.card.phys_num); 3698 3699 if (adapter->dev_topo.card.enc_hdl) { 3700 cfgp1.form = LEAPRAID_SAS_ENC_CFG_PGAD_HDL; 3701 cfgp2.handle = adapter->dev_topo.card.enc_hdl; 3702 if (!(leapraid_op_config_page(adapter, &enc_pg0, 3703 cfgp1, cfgp2, 3704 GET_SAS_ENCLOSURE_PG0))) 3705 adapter->dev_topo.card.enc_lid = 3706 le64_to_cpu(enc_pg0.enc_lid); 3707 } 3708 } 3709 out_free: 3710 kfree(sas_iou_pg0); 3711 } 3712 3713 static int leapraid_internal_exp_add(struct leapraid_adapter *adapter, 3714 struct leapraid_exp_p0 *exp_pg0, 3715 union cfg_param_1 *cfgp1, 3716 union cfg_param_2 *cfgp2, 3717 u16 hdl) 3718 { 3719 struct leapraid_topo_node *topo_node_exp; 3720 struct leapraid_sas_port *sas_port = NULL; 3721 struct leapraid_enc_node *enc_dev; 3722 struct leapraid_exp_p1 exp_pg1; 3723 int ret; 3724 int rc; 3725 unsigned long flags; 3726 u8 port_id; 3727 u16 parent_handle; 3728 u64 sas_addr_parent; 3729 int i; 3730 3731 port_id = exp_pg0->physical_port; 3732 parent_handle = le16_to_cpu(exp_pg0->parent_dev_hdl); 3733 3734 rc = leapraid_get_sas_address(adapter, 3735 parent_handle, &sas_addr_parent); 3736 if (rc) 3737 return rc; 3738 topo_node_exp = kzalloc_obj(*topo_node_exp); 3739 if (!topo_node_exp) 3740 return -ENOMEM; 3741 3742 topo_node_exp->hdl = hdl; 3743 topo_node_exp->phys_num = exp_pg0->phy_num; 3744 topo_node_exp->sas_address_parent = sas_addr_parent; 3745 topo_node_exp->sas_address = le64_to_cpu(exp_pg0->sas_address); 3746 topo_node_exp->card_port = 3747 leapraid_get_port_by_id(adapter, port_id, false); 3748 if (!topo_node_exp->card_port) { 3749 rc = -EPERM; 3750 goto out_fail; 3751 } 3752 3753 dev_info(&adapter->pdev->dev, 3754 "add exp: saddr=0x%016llx, hdl=0x%04x, phdl=0x%04x, phy=%d\n", 3755 (unsigned long long)topo_node_exp->sas_address, 3756 hdl, parent_handle, 3757 topo_node_exp->phys_num); 3758 if (!topo_node_exp->phys_num) { 3759 dev_err(&adapter->pdev->dev, 3760 "%s: Invalid PHY num from exp_pg0\n", __func__); 3761 rc = -EPERM; 3762 goto out_fail; 3763 } 3764 3765 topo_node_exp->card_phy = 3766 kcalloc(topo_node_exp->phys_num, 3767 sizeof(struct leapraid_card_phy), GFP_KERNEL); 3768 if (!topo_node_exp->card_phy) { 3769 dev_err(&adapter->pdev->dev, 3770 "%s: Failed to alloc expander phy array, count=%u\n", 3771 __func__, topo_node_exp->phys_num); 3772 rc = -EPERM; 3773 goto out_fail; 3774 } 3775 3776 INIT_LIST_HEAD(&topo_node_exp->sas_port_list); 3777 sas_port = leapraid_transport_port_add(adapter, hdl, sas_addr_parent, 3778 topo_node_exp->card_port); 3779 if (!sas_port) { 3780 rc = -EPERM; 3781 goto out_fail; 3782 } 3783 3784 topo_node_exp->parent_dev = &sas_port->rphy->dev; 3785 topo_node_exp->rphy = sas_port->rphy; 3786 for (i = 0; i < topo_node_exp->phys_num; i++) { 3787 cfgp1->phy_number = i; 3788 cfgp2->handle = hdl; 3789 if (leapraid_op_config_page(adapter, &exp_pg1, *cfgp1, *cfgp2, 3790 GET_SAS_EXPANDER_PG1)) { 3791 dev_err(&adapter->pdev->dev, 3792 "%s: Failed to get exp_pg1, phy=%d\n", 3793 __func__, i); 3794 rc = -EPERM; 3795 goto out_fail; 3796 } 3797 3798 topo_node_exp->card_phy[i].hdl = hdl; 3799 topo_node_exp->card_phy[i].phy_id = i; 3800 topo_node_exp->card_phy[i].card_port = 3801 leapraid_get_port_by_id(adapter, port_id, false); 3802 ret = leapraid_transport_add_exp_phy( 3803 adapter, 3804 &topo_node_exp->card_phy[i], 3805 &exp_pg1, 3806 topo_node_exp->parent_dev); 3807 if (ret) { 3808 rc = -EPERM; 3809 goto out_fail; 3810 } 3811 } 3812 3813 if (topo_node_exp->enc_hdl) { 3814 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags); 3815 enc_dev = leapraid_enc_find_by_hdl(adapter, 3816 topo_node_exp->enc_hdl); 3817 if (enc_dev) 3818 topo_node_exp->enc_lid = 3819 le64_to_cpu(enc_dev->pg0.enc_lid); 3820 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags); 3821 } 3822 3823 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags); 3824 list_add_tail(&topo_node_exp->list, &adapter->dev_topo.exp_list); 3825 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags); 3826 return 0; 3827 3828 out_fail: 3829 if (sas_port) 3830 leapraid_transport_port_remove(adapter, 3831 topo_node_exp->sas_address, 3832 sas_addr_parent, 3833 topo_node_exp->card_port); 3834 kfree(topo_node_exp->card_phy); 3835 kfree(topo_node_exp); 3836 return rc; 3837 } 3838 3839 static int leapraid_exp_add(struct leapraid_adapter *adapter, u16 hdl) 3840 { 3841 union cfg_param_1 cfgp1 = {0}; 3842 union cfg_param_2 cfgp2 = {0}; 3843 struct leapraid_topo_node *topo_node_exp; 3844 struct leapraid_exp_p0 exp_pg0; 3845 u16 parent_handle; 3846 u64 sas_addr, sas_addr_parent; 3847 unsigned long flags; 3848 u8 port_id; 3849 int rc; 3850 3851 if (!hdl) { 3852 dev_warn(&adapter->pdev->dev, "%s: Invalid hdl\n", __func__); 3853 return -EPERM; 3854 } 3855 3856 if (adapter->access_ctrl.shost_recovering || 3857 adapter->access_ctrl.pcie_recovering) { 3858 dev_warn(&adapter->pdev->dev, 3859 "%s: Failed, shost_recovering=%d pcie_recovering=%d\n", 3860 __func__, adapter->access_ctrl.shost_recovering, 3861 adapter->access_ctrl.pcie_recovering); 3862 return -EPERM; 3863 } 3864 3865 cfgp1.form = LEAPRAID_SAS_EXP_CFD_PGAD_HDL; 3866 cfgp2.handle = hdl; 3867 if (leapraid_op_config_page(adapter, &exp_pg0, cfgp1, cfgp2, 3868 GET_SAS_EXPANDER_PG0)) 3869 return -EPERM; 3870 3871 parent_handle = le16_to_cpu(exp_pg0.parent_dev_hdl); 3872 if (leapraid_get_sas_address(adapter, parent_handle, &sas_addr_parent)) 3873 return -EPERM; 3874 3875 port_id = exp_pg0.physical_port; 3876 if (sas_addr_parent != adapter->dev_topo.card.sas_address) { 3877 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags); 3878 topo_node_exp = 3879 leapraid_exp_find_by_sas_address( 3880 adapter, 3881 sas_addr_parent, 3882 leapraid_get_port_by_id(adapter, 3883 port_id, 3884 false)); 3885 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, 3886 flags); 3887 if (!topo_node_exp) { 3888 rc = leapraid_exp_add(adapter, parent_handle); 3889 if (rc != 0) 3890 return rc; 3891 } 3892 } 3893 3894 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags); 3895 sas_addr = le64_to_cpu(exp_pg0.sas_address); 3896 topo_node_exp = 3897 leapraid_exp_find_by_sas_address( 3898 adapter, 3899 sas_addr, 3900 leapraid_get_port_by_id(adapter, port_id, false)); 3901 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags); 3902 3903 if (topo_node_exp) 3904 return 0; 3905 3906 return leapraid_internal_exp_add(adapter, &exp_pg0, &cfgp1, 3907 &cfgp2, hdl); 3908 } 3909 3910 static void leapraid_exp_node_rm(struct leapraid_adapter *adapter, 3911 struct leapraid_topo_node *topo_node_exp) 3912 { 3913 struct leapraid_sas_port *sas_port, *sas_port_next; 3914 unsigned long flags; 3915 int port_id; 3916 3917 list_for_each_entry_safe(sas_port, sas_port_next, 3918 &topo_node_exp->sas_port_list, 3919 port_list) { 3920 if (adapter->access_ctrl.shost_recovering) 3921 return; 3922 3923 switch (sas_port->remote_identify.device_type) { 3924 case SAS_END_DEVICE: 3925 leapraid_sas_dev_remove_by_sas_address( 3926 adapter, 3927 sas_port->remote_identify.sas_address, 3928 sas_port->card_port); 3929 break; 3930 case SAS_EDGE_EXPANDER_DEVICE: 3931 case SAS_FANOUT_EXPANDER_DEVICE: 3932 leapraid_exp_rm( 3933 adapter, 3934 sas_port->remote_identify.sas_address, 3935 sas_port->card_port); 3936 break; 3937 default: 3938 break; 3939 } 3940 } 3941 3942 port_id = topo_node_exp->card_port->port_id; 3943 leapraid_transport_port_remove(adapter, topo_node_exp->sas_address, 3944 topo_node_exp->sas_address_parent, 3945 topo_node_exp->card_port); 3946 dev_info(&adapter->pdev->dev, 3947 "removing exp: port=%d, SAS addr=0x%016llx, hdl=0x%04x\n", 3948 port_id, (unsigned long long)topo_node_exp->sas_address, 3949 topo_node_exp->hdl); 3950 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags); 3951 list_del(&topo_node_exp->list); 3952 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags); 3953 kfree(topo_node_exp->card_phy); 3954 kfree(topo_node_exp); 3955 } 3956 3957 void leapraid_exp_rm(struct leapraid_adapter *adapter, u64 sas_addr, 3958 struct leapraid_card_port *port) 3959 { 3960 struct leapraid_topo_node *topo_node_exp; 3961 unsigned long flags; 3962 3963 if (adapter->access_ctrl.shost_recovering) 3964 return; 3965 3966 if (!port) 3967 return; 3968 3969 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags); 3970 topo_node_exp = leapraid_exp_find_by_sas_address(adapter, 3971 sas_addr, 3972 port); 3973 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags); 3974 3975 if (topo_node_exp) 3976 leapraid_exp_node_rm(adapter, topo_node_exp); 3977 } 3978 3979 static void leapraid_internal_sas_topo_chg_evt( 3980 struct leapraid_adapter *adapter, 3981 struct leapraid_card_port *card_port, 3982 struct leapraid_topo_node *topo_node_exp, 3983 struct leapraid_fw_evt_work *fw_evt, 3984 u64 sas_addr, u8 max_phys) 3985 { 3986 struct leapraid_evt_data_sas_topo_change_list *evt_data; 3987 u8 phy_number; 3988 u8 link_rate; 3989 u16 reason_code; 3990 u16 hdl; 3991 int i; 3992 3993 evt_data = fw_evt->evt_data; 3994 for (i = 0; i < evt_data->entry_num; i++) { 3995 if (fw_evt->ignore) 3996 return; 3997 3998 if (adapter->access_ctrl.host_removing || 3999 adapter->access_ctrl.pcie_recovering) 4000 return; 4001 4002 phy_number = evt_data->start_phy_num + i; 4003 if (phy_number >= max_phys) 4004 continue; 4005 4006 reason_code = evt_data->phy[i].phy_status & 4007 LEAPRAID_EVT_SAS_TOPO_RC_MASK; 4008 4009 hdl = le16_to_cpu(evt_data->phy[i].attached_dev_hdl); 4010 if (!hdl || 4011 hdl > adapter->adapter_attr.features.max_dev_handle) { 4012 dev_warn(&adapter->pdev->dev, 4013 "%s: Invalid device handle\n", __func__); 4014 continue; 4015 } 4016 link_rate = evt_data->phy[i].link_rate >> 4017 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT; 4018 switch (reason_code) { 4019 case LEAPRAID_EVT_SAS_TOPO_RC_TARG_ADDED: 4020 if (adapter->access_ctrl.shost_recovering) 4021 break; 4022 leapraid_transport_update_links(adapter, sas_addr, 4023 hdl, phy_number, 4024 link_rate, card_port); 4025 if (link_rate < LEAPRAID_SAS_NEG_LINK_RATE_1_5) 4026 break; 4027 leapraid_add_dev(adapter, hdl); 4028 break; 4029 case LEAPRAID_EVT_SAS_TOPO_RC_TARG_NOT_RESPONDING: 4030 leapraid_sas_dev_remove_by_hdl(adapter, hdl); 4031 break; 4032 } 4033 } 4034 4035 if (evt_data->exp_status == LEAPRAID_EVT_SAS_TOPO_ES_NOT_RESPONDING && 4036 topo_node_exp) 4037 leapraid_exp_rm(adapter, sas_addr, card_port); 4038 } 4039 4040 static void leapraid_sas_topo_chg_evt(struct leapraid_adapter *adapter, 4041 struct leapraid_fw_evt_work *fw_evt) 4042 { 4043 struct leapraid_topo_node *topo_node_exp; 4044 struct leapraid_card_port *card_port; 4045 struct leapraid_evt_data_sas_topo_change_list *evt_data; 4046 u16 phdl; 4047 u8 max_phys; 4048 u64 sas_addr; 4049 unsigned long flags; 4050 4051 if (adapter->access_ctrl.shost_recovering || 4052 adapter->access_ctrl.host_removing || 4053 adapter->access_ctrl.pcie_recovering) 4054 return; 4055 4056 evt_data = fw_evt->evt_data; 4057 leapraid_sas_host_add(adapter, adapter->dev_topo.card.phys_num > 0); 4058 4059 if (fw_evt->ignore) 4060 return; 4061 4062 phdl = le16_to_cpu(evt_data->exp_dev_hdl); 4063 card_port = leapraid_get_port_by_id(adapter, 4064 evt_data->physical_port, 4065 false); 4066 if (evt_data->exp_status == LEAPRAID_EVT_SAS_TOPO_ES_ADDED && 4067 leapraid_exp_add(adapter, phdl) != 0) 4068 return; 4069 4070 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags); 4071 topo_node_exp = leapraid_exp_find_by_hdl(adapter, phdl); 4072 if (topo_node_exp) { 4073 sas_addr = topo_node_exp->sas_address; 4074 max_phys = topo_node_exp->phys_num; 4075 card_port = topo_node_exp->card_port; 4076 } else if (phdl < adapter->dev_topo.card.phys_num) { 4077 sas_addr = adapter->dev_topo.card.sas_address; 4078 max_phys = adapter->dev_topo.card.phys_num; 4079 } else { 4080 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, 4081 flags); 4082 return; 4083 } 4084 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags); 4085 4086 leapraid_internal_sas_topo_chg_evt(adapter, card_port, 4087 topo_node_exp, fw_evt, 4088 sas_addr, max_phys); 4089 } 4090 4091 static void leapraid_reprobe_lun(struct scsi_device *sdev, void *no_uld_attach) 4092 { 4093 sdev->no_uld_attach = no_uld_attach ? 1 : 0; 4094 sdev_printk(KERN_INFO, sdev, 4095 "%s RAID component to upper layer\n", 4096 sdev->no_uld_attach ? "hide" : "expose"); 4097 WARN_ON(scsi_device_reprobe(sdev)); 4098 } 4099 4100 static void leapraid_sas_pd_add( 4101 struct leapraid_adapter *adapter, 4102 struct leapraid_evt_data_ir_change *evt_data) 4103 { 4104 union cfg_param_1 cfgp1 = {0}; 4105 union cfg_param_2 cfgp2 = {0}; 4106 struct leapraid_sas_dev_p0 sas_dev_p0; 4107 struct leapraid_sas_dev *sas_dev; 4108 u64 sas_address; 4109 u16 parent_hdl; 4110 u16 hdl; 4111 4112 hdl = le16_to_cpu(evt_data->phys_disk_dev_hdl); 4113 if (!hdl || hdl > adapter->adapter_attr.features.max_dev_handle) { 4114 dev_warn(&adapter->pdev->dev, 4115 "%s: Invalid device handle\n", __func__); 4116 return; 4117 } 4118 4119 set_bit(hdl, adapter->dev_topo.pd_hdls); 4120 sas_dev = leapraid_get_sas_dev_by_hdl(adapter, hdl); 4121 if (sas_dev) { 4122 leapraid_sdev_put(sas_dev); 4123 dev_warn(&adapter->pdev->dev, 4124 "Dev handle 0x%x already exists\n", hdl); 4125 return; 4126 } 4127 4128 cfgp1.form = LEAPRAID_SAS_DEV_CFG_PGAD_HDL; 4129 cfgp2.handle = hdl; 4130 if (leapraid_op_config_page(adapter, &sas_dev_p0, cfgp1, cfgp2, 4131 GET_SAS_DEVICE_PG0)) { 4132 dev_warn(&adapter->pdev->dev, "Failed to read dev page0\n"); 4133 return; 4134 } 4135 4136 parent_hdl = le16_to_cpu(sas_dev_p0.parent_dev_hdl); 4137 if (!leapraid_get_sas_address(adapter, parent_hdl, &sas_address)) 4138 leapraid_transport_update_links(adapter, sas_address, hdl, 4139 sas_dev_p0.phy_num, 4140 LEAPRAID_SAS_NEG_LINK_RATE_1_5, 4141 leapraid_get_port_by_id(adapter, 4142 sas_dev_p0.physical_port, 4143 false)); 4144 leapraid_add_dev(adapter, hdl); 4145 } 4146 4147 static void leapraid_sas_pd_delete( 4148 struct leapraid_adapter *adapter, 4149 struct leapraid_evt_data_ir_change *evt_data) 4150 { 4151 u16 hdl; 4152 4153 hdl = le16_to_cpu(evt_data->phys_disk_dev_hdl); 4154 leapraid_sas_dev_remove_by_hdl(adapter, hdl); 4155 } 4156 4157 static void leapraid_sas_pd_hide( 4158 struct leapraid_adapter *adapter, 4159 struct leapraid_evt_data_ir_change *evt_data) 4160 { 4161 struct leapraid_starget_priv *starget_priv; 4162 struct scsi_target *starget = NULL; 4163 struct leapraid_sas_dev *sas_dev; 4164 unsigned long flags; 4165 u64 volume_wwid = 0; 4166 u16 volume_hdl; 4167 u16 hdl; 4168 4169 hdl = le16_to_cpu(evt_data->phys_disk_dev_hdl); 4170 if (!hdl || hdl > adapter->adapter_attr.features.max_dev_handle) { 4171 dev_warn(&adapter->pdev->dev, 4172 "%s: Invalid device handle\n", __func__); 4173 return; 4174 } 4175 leapraid_cfg_get_volume_hdl(adapter, hdl, &volume_hdl); 4176 if (volume_hdl) 4177 leapraid_cfg_get_volume_wwid(adapter, 4178 volume_hdl, 4179 &volume_wwid); 4180 4181 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 4182 sas_dev = leapraid_hold_lock_get_sas_dev_by_hdl(adapter, hdl); 4183 if (!sas_dev) { 4184 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 4185 return; 4186 } 4187 4188 set_bit(hdl, adapter->dev_topo.pd_hdls); 4189 if (sas_dev->starget && sas_dev->starget->hostdata) { 4190 starget = sas_dev->starget; 4191 starget_priv = starget->hostdata; 4192 starget_priv->flg |= LEAPRAID_TGT_FLG_RAID_MEMBER; 4193 sas_dev->volume_hdl = volume_hdl; 4194 sas_dev->volume_wwid = volume_wwid; 4195 } 4196 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 4197 if (starget) { 4198 starget_for_each_device(starget, 4199 (void *)LEAPRAID_NO_ULD_ATTACH_FLAG, 4200 leapraid_reprobe_lun); 4201 } 4202 4203 leapraid_sdev_put(sas_dev); 4204 } 4205 4206 static void leapraid_sas_pd_expose( 4207 struct leapraid_adapter *adapter, 4208 struct leapraid_evt_data_ir_change *evt_data) 4209 { 4210 struct leapraid_starget_priv *starget_priv; 4211 struct scsi_target *starget = NULL; 4212 struct leapraid_sas_dev *sas_dev; 4213 unsigned long flags; 4214 u16 hdl; 4215 4216 hdl = le16_to_cpu(evt_data->phys_disk_dev_hdl); 4217 if (!hdl || hdl > adapter->adapter_attr.features.max_dev_handle) { 4218 dev_warn(&adapter->pdev->dev, 4219 "%s: Invalid device handle\n", __func__); 4220 return; 4221 } 4222 4223 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 4224 sas_dev = leapraid_hold_lock_get_sas_dev_by_hdl(adapter, hdl); 4225 if (!sas_dev) { 4226 dev_warn(&adapter->pdev->dev, 4227 "%s:%d: sas_dev not found, hdl=0x%x\n", 4228 __func__, __LINE__, hdl); 4229 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 4230 return; 4231 } 4232 4233 sas_dev->volume_hdl = 0; 4234 sas_dev->volume_wwid = 0; 4235 clear_bit(hdl, adapter->dev_topo.pd_hdls); 4236 if (sas_dev->starget && sas_dev->starget->hostdata) { 4237 starget = sas_dev->starget; 4238 starget_priv = starget->hostdata; 4239 starget_priv->flg &= ~LEAPRAID_TGT_FLG_RAID_MEMBER; 4240 sas_dev->led_on = 0; 4241 } 4242 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 4243 4244 if (starget) { 4245 starget_for_each_device(starget, 4246 NULL, 4247 leapraid_reprobe_lun); 4248 } 4249 4250 leapraid_sdev_put(sas_dev); 4251 } 4252 4253 static void leapraid_sas_vol_visibility( 4254 struct leapraid_adapter *adapter, 4255 struct leapraid_evt_data_ir_change *evt_data) 4256 { 4257 struct leapraid_raid_volume *raid_volume; 4258 struct scsi_device *sdev; 4259 bool reprobe_flg = false; 4260 bool sdev_held = false; 4261 unsigned long flags; 4262 u16 hdl; 4263 u8 rc; 4264 4265 hdl = le16_to_cpu(evt_data->vol_dev_hdl); 4266 rc = evt_data->reason_code; 4267 raid_volume = leapraid_raid_volume_find_by_hdl(adapter, hdl); 4268 if (!raid_volume) { 4269 dev_warn(&adapter->pdev->dev, 4270 "%s:%d: Volume handle 0x%x not found\n", 4271 __func__, __LINE__, hdl); 4272 return; 4273 } 4274 4275 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags); 4276 sdev = raid_volume->sdev; 4277 if (!sdev) { 4278 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, 4279 flags); 4280 leapraid_raid_volume_put(raid_volume); 4281 dev_warn(&adapter->pdev->dev, 4282 "%s:%d: Volume handle 0x%x has no sdev\n", 4283 __func__, __LINE__, hdl); 4284 return; 4285 } 4286 4287 if (sdev->no_uld_attach && 4288 rc == LEAPRAID_EVT_IR_RC_VOLUME_UNHIDE) { 4289 sdev->no_uld_attach = 0; 4290 reprobe_flg = true; 4291 } else if (!sdev->no_uld_attach && 4292 rc == LEAPRAID_EVT_IR_RC_VOLUME_HIDE) { 4293 sdev->no_uld_attach = 1; 4294 reprobe_flg = true; 4295 } 4296 4297 if (reprobe_flg && !scsi_device_get(sdev)) 4298 sdev_held = true; 4299 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags); 4300 leapraid_raid_volume_put(raid_volume); 4301 4302 if (!reprobe_flg) { 4303 dev_warn(&adapter->pdev->dev, 4304 "%s:rc(0x%x): Request matches, skipping\n", 4305 __func__, rc); 4306 return; 4307 } 4308 4309 if (!sdev_held) { 4310 dev_warn(&adapter->pdev->dev, 4311 "%s: Failed to hold sdev for reprobe, hdl=0x%x\n", 4312 __func__, hdl); 4313 return; 4314 } 4315 4316 if (sdev->no_uld_attach) 4317 sdev_printk(KERN_INFO, sdev, "hide vol\n"); 4318 else 4319 sdev_printk(KERN_INFO, sdev, "unhide vol\n"); 4320 4321 WARN_ON(scsi_device_reprobe(sdev)); 4322 scsi_device_put(sdev); 4323 } 4324 4325 static void leapraid_sas_volume_add( 4326 struct leapraid_adapter *adapter, 4327 struct leapraid_evt_data_ir_change *evt_data) 4328 { 4329 struct leapraid_raid_volume *raid_volume; 4330 unsigned long flags; 4331 u64 wwid; 4332 u16 hdl; 4333 4334 hdl = le16_to_cpu(evt_data->vol_dev_hdl); 4335 4336 if (leapraid_cfg_get_volume_wwid(adapter, hdl, &wwid)) { 4337 dev_warn(&adapter->pdev->dev, "Failed to read volume page1\n"); 4338 return; 4339 } 4340 4341 if (!wwid) { 4342 dev_warn(&adapter->pdev->dev, "Invalid WWID(handle=0x%x)\n", 4343 hdl); 4344 return; 4345 } 4346 4347 raid_volume = leapraid_raid_volume_find_by_wwid(adapter, wwid); 4348 if (raid_volume) { 4349 dev_warn(&adapter->pdev->dev, 4350 "Volume handle 0x%x already exists\n", hdl); 4351 leapraid_raid_volume_put(raid_volume); 4352 return; 4353 } 4354 4355 raid_volume = kzalloc(sizeof(*raid_volume), GFP_KERNEL); 4356 if (!raid_volume) 4357 return; 4358 4359 INIT_LIST_HEAD(&raid_volume->list); 4360 kref_init(&raid_volume->refcnt); 4361 raid_volume->id = adapter->dev_topo.sas_id++; 4362 raid_volume->channel = RAID_CHANNEL; 4363 raid_volume->hdl = hdl; 4364 raid_volume->wwid = wwid; 4365 leapraid_raid_volume_add(adapter, raid_volume); 4366 if (!adapter->scan_dev_desc.wait_scan_dev_done) { 4367 if (scsi_add_device(adapter->shost, RAID_CHANNEL, 4368 raid_volume->id, 0)) 4369 leapraid_raid_volume_remove(adapter, raid_volume); 4370 dev_info(&adapter->pdev->dev, 4371 "add RAID volume: hdl=0x%x, wwid=0x%llx\n", hdl, wwid); 4372 } else { 4373 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags); 4374 leapraid_check_boot_dev(adapter, raid_volume, RAID_CHANNEL); 4375 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, 4376 flags); 4377 } 4378 leapraid_raid_volume_put(raid_volume); 4379 } 4380 4381 static void leapraid_sas_volume_delete_by_ptr( 4382 struct leapraid_adapter *adapter, 4383 struct leapraid_raid_volume *raid_volume) 4384 { 4385 struct leapraid_starget_priv *starget_priv; 4386 struct scsi_target *starget = NULL; 4387 unsigned long flags; 4388 bool in_list; 4389 4390 if (!raid_volume) 4391 return; 4392 4393 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags); 4394 in_list = !list_empty(&raid_volume->list); 4395 if (in_list && raid_volume->starget) { 4396 starget = raid_volume->starget; 4397 starget_priv = starget->hostdata; 4398 if (starget_priv) 4399 starget_priv->deleted = 1; 4400 } 4401 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags); 4402 4403 if (!in_list) 4404 return; 4405 4406 dev_info(&adapter->pdev->dev, 4407 "delete RAID volume: hdl=0x%x, wwid=0x%llx\n", 4408 raid_volume->hdl, raid_volume->wwid); 4409 leapraid_raid_volume_remove(adapter, raid_volume); 4410 4411 if (starget) 4412 scsi_remove_target(&starget->dev); 4413 } 4414 4415 static void leapraid_sas_volume_delete(struct leapraid_adapter *adapter, 4416 u16 hdl) 4417 { 4418 struct leapraid_raid_volume *raid_volume; 4419 4420 raid_volume = leapraid_raid_volume_find_by_hdl(adapter, hdl); 4421 if (!raid_volume) { 4422 dev_warn(&adapter->pdev->dev, 4423 "%s:%d: Volume handle 0x%x not found\n", 4424 __func__, __LINE__, hdl); 4425 return; 4426 } 4427 4428 leapraid_sas_volume_delete_by_ptr(adapter, raid_volume); 4429 leapraid_raid_volume_put(raid_volume); 4430 } 4431 4432 static void leapraid_sas_ir_chg_evt(struct leapraid_adapter *adapter, 4433 struct leapraid_fw_evt_work *fw_evt) 4434 { 4435 struct leapraid_evt_data_ir_change *evt_data; 4436 4437 evt_data = fw_evt->evt_data; 4438 4439 switch (evt_data->reason_code) { 4440 case LEAPRAID_EVT_IR_RC_VOLUME_ADD: 4441 leapraid_sas_volume_add(adapter, evt_data); 4442 break; 4443 case LEAPRAID_EVT_IR_RC_VOLUME_DELETE: 4444 leapraid_sas_volume_delete(adapter, 4445 le16_to_cpu(evt_data->vol_dev_hdl)); 4446 break; 4447 case LEAPRAID_EVT_IR_RC_PD_HIDDEN_TO_ADD: 4448 leapraid_sas_pd_add(adapter, evt_data); 4449 break; 4450 case LEAPRAID_EVT_IR_RC_PD_UNHIDDEN_TO_DELETE: 4451 leapraid_sas_pd_delete(adapter, evt_data); 4452 break; 4453 case LEAPRAID_EVT_IR_RC_PD_CREATED_TO_HIDE: 4454 leapraid_sas_pd_hide(adapter, evt_data); 4455 break; 4456 case LEAPRAID_EVT_IR_RC_PD_DELETED_TO_EXPOSE: 4457 leapraid_sas_pd_expose(adapter, evt_data); 4458 break; 4459 case LEAPRAID_EVT_IR_RC_VOLUME_HIDE: 4460 case LEAPRAID_EVT_IR_RC_VOLUME_UNHIDE: 4461 leapraid_sas_vol_visibility(adapter, evt_data); 4462 break; 4463 default: 4464 break; 4465 } 4466 } 4467 4468 static void leapraid_sas_enc_dev_stat_add_node( 4469 struct leapraid_adapter *adapter, u16 hdl) 4470 { 4471 union cfg_param_1 cfgp1 = {0}; 4472 union cfg_param_2 cfgp2 = {0}; 4473 struct leapraid_enc_node *enc_node; 4474 struct leapraid_enc_node *enc_exist; 4475 unsigned long flags; 4476 int rc; 4477 4478 enc_node = kzalloc_obj(*enc_node); 4479 if (!enc_node) 4480 return; 4481 4482 cfgp1.form = LEAPRAID_SAS_ENC_CFG_PGAD_HDL; 4483 cfgp2.handle = hdl; 4484 rc = leapraid_op_config_page(adapter, &enc_node->pg0, cfgp1, cfgp2, 4485 GET_SAS_ENCLOSURE_PG0); 4486 if (rc) { 4487 kfree(enc_node); 4488 return; 4489 } 4490 4491 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags); 4492 enc_exist = leapraid_enc_find_by_hdl(adapter, hdl); 4493 if (enc_exist) { 4494 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags); 4495 kfree(enc_node); 4496 return; 4497 } 4498 list_add_tail(&enc_node->list, &adapter->dev_topo.enc_list); 4499 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags); 4500 } 4501 4502 static void leapraid_sas_enc_dev_stat_del_node( 4503 struct leapraid_adapter *adapter, u16 hdl) 4504 { 4505 struct leapraid_enc_node *enc_node; 4506 unsigned long flags; 4507 4508 if (!hdl) 4509 return; 4510 4511 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags); 4512 enc_node = leapraid_enc_find_by_hdl(adapter, hdl); 4513 if (enc_node) 4514 list_del(&enc_node->list); 4515 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags); 4516 4517 kfree(enc_node); 4518 } 4519 4520 static void leapraid_sas_enc_dev_stat_chg_evt( 4521 struct leapraid_adapter *adapter, 4522 struct leapraid_fw_evt_work *fw_evt) 4523 { 4524 struct leapraid_evt_data_sas_enc_dev_status_change *evt_data; 4525 u16 enc_hdl; 4526 4527 if (adapter->access_ctrl.shost_recovering) 4528 return; 4529 4530 evt_data = fw_evt->evt_data; 4531 enc_hdl = le16_to_cpu(evt_data->enc_hdl); 4532 switch (evt_data->reason_code) { 4533 case LEAPRAID_EVT_SAS_ENCL_RC_ADDED: 4534 if (enc_hdl) 4535 leapraid_sas_enc_dev_stat_add_node(adapter, enc_hdl); 4536 break; 4537 case LEAPRAID_EVT_SAS_ENCL_RC_NOT_RESPONDING: 4538 leapraid_sas_enc_dev_stat_del_node(adapter, enc_hdl); 4539 break; 4540 default: 4541 break; 4542 } 4543 } 4544 4545 static void leapraid_remove_unresp_sas_end_dev( 4546 struct leapraid_adapter *adapter) 4547 { 4548 struct leapraid_sas_dev *sas_dev, *sas_dev_next; 4549 unsigned long flags; 4550 LIST_HEAD(head); 4551 4552 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 4553 list_for_each_entry_safe(sas_dev, sas_dev_next, 4554 &adapter->dev_topo.sas_dev_init_list, list) { 4555 if (sas_dev->rphy || sas_dev->pend_sas_rphy_add) 4556 continue; 4557 4558 list_del_init(&sas_dev->list); 4559 leapraid_clear_cached_boot_dev(adapter, sas_dev, 0); 4560 leapraid_sdev_put(sas_dev); 4561 } 4562 list_for_each_entry_safe(sas_dev, sas_dev_next, 4563 &adapter->dev_topo.sas_dev_list, list) { 4564 if (!sas_dev->resp) 4565 list_move_tail(&sas_dev->list, &head); 4566 else 4567 sas_dev->resp = 0; 4568 } 4569 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 4570 4571 list_for_each_entry_safe(sas_dev, sas_dev_next, &head, list) { 4572 leapraid_remove_device(adapter, sas_dev); 4573 list_del_init(&sas_dev->list); 4574 leapraid_sdev_put(sas_dev); 4575 } 4576 4577 dev_warn(&adapter->pdev->dev, 4578 "Unresponsive SAS end devices removed\n"); 4579 } 4580 4581 static void leapraid_remove_unresp_raid_volumes( 4582 struct leapraid_adapter *adapter) 4583 { 4584 unsigned long flags; 4585 struct leapraid_raid_volume *raid_volume, *raid_volume_next; 4586 LIST_HEAD(head); 4587 4588 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags); 4589 list_for_each_entry_safe(raid_volume, raid_volume_next, 4590 &adapter->dev_topo.raid_volume_list, list) { 4591 if (!raid_volume->resp) 4592 list_move_tail(&raid_volume->list, &head); 4593 else 4594 raid_volume->resp = 0; 4595 } 4596 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags); 4597 4598 list_for_each_entry_safe(raid_volume, raid_volume_next, &head, list) { 4599 leapraid_sas_volume_delete_by_ptr(adapter, raid_volume); 4600 } 4601 4602 dev_warn(&adapter->pdev->dev, 4603 "Unresponsive RAID volumes removed\n"); 4604 } 4605 4606 static void leapraid_remove_unresp_sas_exp(struct leapraid_adapter *adapter) 4607 { 4608 struct leapraid_topo_node *topo_node_exp, *topo_node_exp_next; 4609 unsigned long flags; 4610 LIST_HEAD(head); 4611 4612 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags); 4613 list_for_each_entry_safe(topo_node_exp, topo_node_exp_next, 4614 &adapter->dev_topo.exp_list, list) { 4615 if (!topo_node_exp->resp) 4616 list_move_tail(&topo_node_exp->list, &head); 4617 else 4618 topo_node_exp->resp = 0; 4619 } 4620 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags); 4621 4622 list_for_each_entry_safe(topo_node_exp, topo_node_exp_next, 4623 &head, list) 4624 leapraid_exp_node_rm(adapter, topo_node_exp); 4625 4626 dev_warn(&adapter->pdev->dev, 4627 "Unresponsive SAS expanders removed\n"); 4628 } 4629 4630 static void leapraid_remove_unresp_dev(struct leapraid_adapter *adapter) 4631 { 4632 leapraid_remove_unresp_sas_end_dev(adapter); 4633 if (adapter->adapter_attr.raid_support) 4634 leapraid_remove_unresp_raid_volumes(adapter); 4635 leapraid_remove_unresp_sas_exp(adapter); 4636 leapraid_ublk_io_all_dev(adapter); 4637 } 4638 4639 static void leapraid_del_dirty_vphy(struct leapraid_adapter *adapter) 4640 { 4641 struct leapraid_card_port *card_port, *card_port_next; 4642 struct leapraid_vphy *vphy, *vphy_next; 4643 4644 list_for_each_entry_safe(card_port, card_port_next, 4645 &adapter->dev_topo.card_port_list, list) { 4646 if (!card_port->vphys_mask) 4647 continue; 4648 4649 list_for_each_entry_safe(vphy, vphy_next, 4650 &card_port->vphys_list, list) { 4651 if (!(vphy->flg & LEAPRAID_VPHY_FLG_DIRTY)) 4652 continue; 4653 4654 card_port->vphys_mask &= ~vphy->phy_mask; 4655 list_del(&vphy->list); 4656 kfree(vphy); 4657 } 4658 4659 if (!card_port->vphys_mask && !card_port->sas_address) 4660 card_port->flg |= LEAPRAID_CARD_PORT_FLG_DIRTY; 4661 } 4662 } 4663 4664 static void leapraid_del_dirty_card_port(struct leapraid_adapter *adapter) 4665 { 4666 struct leapraid_card_port *card_port, *card_port_next; 4667 4668 list_for_each_entry_safe(card_port, card_port_next, 4669 &adapter->dev_topo.card_port_list, list) { 4670 if (!(card_port->flg & LEAPRAID_CARD_PORT_FLG_DIRTY) || 4671 card_port->flg & LEAPRAID_CARD_PORT_FLG_NEW) 4672 continue; 4673 4674 list_del(&card_port->list); 4675 kfree(card_port); 4676 } 4677 } 4678 4679 static void leapraid_update_dev_qdepth(struct leapraid_adapter *adapter) 4680 { 4681 struct leapraid_sdev_priv *sdev_priv; 4682 struct leapraid_sas_dev *sas_dev; 4683 struct leapraid_adapter_attr *attr; 4684 struct scsi_device *sdev; 4685 u16 qdepth; 4686 4687 attr = &adapter->adapter_attr; 4688 shost_for_each_device(sdev, adapter->shost) { 4689 sdev_priv = sdev->hostdata; 4690 if (!sdev_priv || !sdev_priv->starget_priv) 4691 continue; 4692 sas_dev = sdev_priv->starget_priv->sas_dev; 4693 if (sas_dev && sas_dev->dev_info & LEAPRAID_DEVTYP_SSP_TGT) 4694 qdepth = (sas_dev->port_connection > 1) ? 4695 attr->wideport_max_queue_depth : 4696 attr->narrowport_max_queue_depth; 4697 else if (sas_dev && sas_dev->dev_info & 4698 LEAPRAID_DEVTYP_SATA_DEV) 4699 qdepth = attr->sata_max_queue_depth; 4700 else 4701 continue; 4702 4703 leapraid_change_queue_depth(sdev, qdepth); 4704 } 4705 } 4706 4707 static void leapraid_update_exp_links(struct leapraid_adapter *adapter, 4708 struct leapraid_topo_node *topo_node_exp, 4709 u16 hdl) 4710 { 4711 union cfg_param_1 cfgp1 = {0}; 4712 union cfg_param_2 cfgp2 = {0}; 4713 struct leapraid_exp_p1 exp_p1; 4714 int i; 4715 4716 cfgp2.handle = hdl; 4717 for (i = 0; i < topo_node_exp->phys_num; i++) { 4718 cfgp1.phy_number = i; 4719 if (leapraid_op_config_page(adapter, &exp_p1, cfgp1, cfgp2, 4720 GET_SAS_EXPANDER_PG1)) 4721 return; 4722 4723 leapraid_transport_update_links( 4724 adapter, 4725 topo_node_exp->sas_address, 4726 le16_to_cpu(exp_p1.attached_dev_hdl), 4727 i, 4728 exp_p1.neg_link_rate >> 4729 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT, 4730 topo_node_exp->card_port); 4731 } 4732 } 4733 4734 static void leapraid_scan_exp_after_reset(struct leapraid_adapter *adapter) 4735 { 4736 union cfg_param_1 cfgp1 = {0}; 4737 union cfg_param_2 cfgp2 = {0}; 4738 struct leapraid_topo_node *topo_node_exp; 4739 struct leapraid_exp_p0 exp_p0; 4740 unsigned long flags; 4741 u16 hdl; 4742 u8 port_id; 4743 4744 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP; 4745 for (hdl = 0xFFFF, cfgp2.handle = hdl; 4746 !leapraid_op_config_page(adapter, &exp_p0, cfgp1, cfgp2, 4747 GET_SAS_EXPANDER_PG0); 4748 cfgp2.handle = hdl) { 4749 hdl = le16_to_cpu(exp_p0.dev_hdl); 4750 port_id = exp_p0.physical_port; 4751 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags); 4752 topo_node_exp = 4753 leapraid_exp_find_by_sas_address( 4754 adapter, 4755 le64_to_cpu(exp_p0.sas_address), 4756 leapraid_get_port_by_id(adapter, 4757 port_id, 4758 false)); 4759 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, 4760 flags); 4761 4762 if (topo_node_exp) { 4763 leapraid_update_exp_links(adapter, topo_node_exp, hdl); 4764 } else { 4765 leapraid_exp_add(adapter, hdl); 4766 4767 dev_info(&adapter->pdev->dev, 4768 "add exp: hdl=0x%04x, SAS addr=0x%016llx\n", 4769 hdl, 4770 (unsigned long long)le64_to_cpu( 4771 exp_p0.sas_address)); 4772 } 4773 } 4774 } 4775 4776 static void leapraid_scan_phy_disks_after_reset( 4777 struct leapraid_adapter *adapter) 4778 { 4779 union cfg_param_1 cfgp1 = {0}; 4780 union cfg_param_2 cfgp2 = {0}; 4781 union cfg_param_1 cfgp1_extra = {0}; 4782 union cfg_param_2 cfgp2_extra = {0}; 4783 struct leapraid_sas_dev_p0 sas_dev_p0; 4784 struct leapraid_raidpd_p0 raidpd_p0; 4785 struct leapraid_sas_dev *sas_dev; 4786 u8 phys_disk_num, port_id; 4787 u16 hdl, parent_hdl; 4788 u64 sas_addr; 4789 4790 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP; 4791 for (phys_disk_num = 0xFF, cfgp2.form_specific = phys_disk_num; 4792 !leapraid_op_config_page(adapter, &raidpd_p0, 4793 cfgp1, cfgp2, GET_PHY_DISK_PG0); 4794 cfgp2.form_specific = phys_disk_num) { 4795 phys_disk_num = raidpd_p0.phys_disk_num; 4796 hdl = le16_to_cpu(raidpd_p0.dev_hdl); 4797 sas_dev = leapraid_get_sas_dev_by_hdl(adapter, hdl); 4798 if (sas_dev) { 4799 leapraid_sdev_put(sas_dev); 4800 continue; 4801 } 4802 4803 cfgp1_extra.form = LEAPRAID_SAS_DEV_CFG_PGAD_HDL; 4804 cfgp2_extra.handle = hdl; 4805 if (leapraid_op_config_page(adapter, &sas_dev_p0, cfgp1_extra, 4806 cfgp2_extra, GET_SAS_DEVICE_PG0) != 4807 0) 4808 continue; 4809 4810 parent_hdl = le16_to_cpu(sas_dev_p0.parent_dev_hdl); 4811 if (!leapraid_get_sas_address(adapter, 4812 parent_hdl, 4813 &sas_addr)) { 4814 port_id = sas_dev_p0.physical_port; 4815 leapraid_transport_update_links( 4816 adapter, sas_addr, hdl, 4817 sas_dev_p0.phy_num, 4818 LEAPRAID_SAS_NEG_LINK_RATE_1_5, 4819 leapraid_get_port_by_id( 4820 adapter, port_id, false)); 4821 if (!hdl || hdl > 4822 adapter->adapter_attr.features.max_dev_handle) { 4823 dev_warn(&adapter->pdev->dev, 4824 "%s: Invalid device handle\n", 4825 __func__); 4826 } else { 4827 set_bit(hdl, adapter->dev_topo.pd_hdls); 4828 leapraid_add_dev(adapter, hdl); 4829 4830 dev_info(&adapter->pdev->dev, 4831 "add pd hdl=0x%04x saddr=0x%016llx\n", 4832 hdl, 4833 (unsigned long long)le64_to_cpu( 4834 sas_dev_p0.sas_address)); 4835 } 4836 } 4837 } 4838 } 4839 4840 static void leapraid_scan_vol_after_reset(struct leapraid_adapter *adapter) 4841 { 4842 union cfg_param_1 cfgp1 = {0}; 4843 union cfg_param_2 cfgp2 = {0}; 4844 union cfg_param_1 cfgp1_extra = {0}; 4845 union cfg_param_2 cfgp2_extra = {0}; 4846 struct leapraid_evt_data_ir_change evt_data; 4847 struct leapraid_raid_volume *raid_volume; 4848 struct leapraid_raidvol_p1 *vol_p1; 4849 struct leapraid_raidvol_p0 *vol_p0; 4850 u16 hdl; 4851 4852 vol_p0 = kzalloc_obj(*vol_p0); 4853 if (!vol_p0) 4854 return; 4855 4856 vol_p1 = kzalloc_obj(*vol_p1); 4857 if (!vol_p1) { 4858 kfree(vol_p0); 4859 return; 4860 } 4861 4862 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP; 4863 for (hdl = 0xFFFF, cfgp2.handle = hdl; 4864 !leapraid_op_config_page(adapter, vol_p1, cfgp1, 4865 cfgp2, GET_RAID_VOLUME_PG1); 4866 cfgp2.handle = hdl) { 4867 hdl = le16_to_cpu(vol_p1->dev_hdl); 4868 raid_volume = leapraid_raid_volume_find_by_wwid( 4869 adapter, 4870 le64_to_cpu(vol_p1->wwid)); 4871 if (raid_volume) { 4872 leapraid_raid_volume_put(raid_volume); 4873 continue; 4874 } 4875 4876 cfgp1_extra.size = sizeof(struct leapraid_raidvol_p0); 4877 cfgp2_extra.handle = hdl; 4878 if (leapraid_op_config_page(adapter, vol_p0, cfgp1_extra, 4879 cfgp2_extra, GET_RAID_VOLUME_PG0)) 4880 continue; 4881 4882 if (vol_p0->volume_state == LEAPRAID_VOL_STATE_OPTIMAL || 4883 vol_p0->volume_state == LEAPRAID_VOL_STATE_ONLINE || 4884 vol_p0->volume_state == LEAPRAID_VOL_STATE_DEGRADED) { 4885 memset(&evt_data, 0, 4886 sizeof(struct leapraid_evt_data_ir_change)); 4887 evt_data.reason_code = LEAPRAID_EVT_IR_RC_VOLUME_ADD; 4888 evt_data.vol_dev_hdl = vol_p1->dev_hdl; 4889 leapraid_sas_volume_add(adapter, &evt_data); 4890 dev_info(&adapter->pdev->dev, 4891 "add volume: hdl=0x%04x\n", 4892 vol_p1->dev_hdl); 4893 } 4894 } 4895 4896 kfree(vol_p0); 4897 kfree(vol_p1); 4898 } 4899 4900 static void leapraid_scan_sas_dev_after_reset(struct leapraid_adapter *adapter) 4901 { 4902 union cfg_param_1 cfgp1 = {0}; 4903 union cfg_param_2 cfgp2 = {0}; 4904 struct leapraid_sas_dev_p0 sas_dev_p0; 4905 struct leapraid_sas_dev *sas_dev; 4906 u16 hdl, parent_hdl; 4907 u64 sas_address; 4908 u8 port_id; 4909 4910 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP; 4911 for (hdl = 0xFFFF, cfgp2.handle = hdl; 4912 !leapraid_op_config_page(adapter, &sas_dev_p0, cfgp1, cfgp2, 4913 GET_SAS_DEVICE_PG0); 4914 cfgp2.handle = hdl) { 4915 hdl = le16_to_cpu(sas_dev_p0.dev_hdl); 4916 if (!hdl || 4917 hdl > adapter->adapter_attr.features.max_dev_handle) { 4918 dev_warn(&adapter->pdev->dev, 4919 "%s: Invalid device handle\n", __func__); 4920 continue; 4921 } 4922 4923 if (!(leapraid_is_end_dev(le32_to_cpu(sas_dev_p0.dev_info)))) 4924 continue; 4925 4926 port_id = sas_dev_p0.physical_port; 4927 sas_dev = leapraid_get_sas_dev_by_addr( 4928 adapter, 4929 le64_to_cpu(sas_dev_p0.sas_address), 4930 leapraid_get_port_by_id( 4931 adapter, 4932 port_id, 4933 false)); 4934 if (sas_dev) { 4935 leapraid_sdev_put(sas_dev); 4936 continue; 4937 } 4938 4939 parent_hdl = le16_to_cpu(sas_dev_p0.parent_dev_hdl); 4940 if (!leapraid_get_sas_address(adapter, parent_hdl, 4941 &sas_address)) { 4942 leapraid_transport_update_links( 4943 adapter, 4944 sas_address, 4945 hdl, 4946 sas_dev_p0.phy_num, 4947 LEAPRAID_SAS_NEG_LINK_RATE_1_5, 4948 leapraid_get_port_by_id(adapter, 4949 port_id, 4950 false)); 4951 leapraid_add_dev(adapter, hdl); 4952 dev_info(&adapter->pdev->dev, 4953 "Add SAS dev: hdl=0x%04x, saddr=0x%016llx\n", 4954 hdl, 4955 (unsigned long long)le64_to_cpu( 4956 sas_dev_p0.sas_address)); 4957 } 4958 } 4959 } 4960 4961 static void leapraid_scan_all_dev_after_reset(struct leapraid_adapter *adapter) 4962 { 4963 leapraid_sas_host_add(adapter, adapter->dev_topo.card.phys_num > 0); 4964 leapraid_scan_exp_after_reset(adapter); 4965 if (adapter->adapter_attr.raid_support) { 4966 leapraid_scan_phy_disks_after_reset(adapter); 4967 leapraid_scan_vol_after_reset(adapter); 4968 } 4969 leapraid_scan_sas_dev_after_reset(adapter); 4970 } 4971 4972 static void leapraid_hardreset_async_logic(struct leapraid_adapter *adapter) 4973 { 4974 unsigned long flags; 4975 4976 leapraid_remove_unresp_dev(adapter); 4977 leapraid_del_dirty_vphy(adapter); 4978 leapraid_del_dirty_card_port(adapter); 4979 leapraid_update_dev_qdepth(adapter); 4980 leapraid_scan_all_dev_after_reset(adapter); 4981 4982 if (adapter->scan_dev_desc.driver_loading) 4983 leapraid_scan_dev_done(adapter); 4984 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags); 4985 adapter->access_ctrl.shost_recover_async = 0; 4986 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags); 4987 wake_up(&adapter->access_ctrl.shost_recover_wq); 4988 } 4989 4990 static int leapraid_send_enc_cmd(struct leapraid_adapter *adapter, 4991 struct leapraid_sep_rep *sep_rep, 4992 struct leapraid_sep_req *sep_req) 4993 { 4994 void *req; 4995 bool reset_flg = false; 4996 int rc; 4997 u16 smid; 4998 4999 mutex_lock(&adapter->driver_cmds.enc_cmd.mutex); 5000 rc = leapraid_check_adapter_is_op(adapter, LEAPRAID_DB_WAIT_OP_SHORT, 5001 __func__); 5002 if (rc) 5003 goto unlock; 5004 5005 adapter->driver_cmds.enc_cmd.status = LEAPRAID_CMD_PENDING; 5006 smid = adapter->driver_cmds.enc_cmd.inter_taskid; 5007 req = leapraid_get_task_desc(adapter, smid); 5008 memset(req, 0, LEAPRAID_REQUEST_SIZE); 5009 memcpy(req, sep_req, sizeof(struct leapraid_sep_req)); 5010 init_completion(&adapter->driver_cmds.enc_cmd.done); 5011 leapraid_fire_task(adapter, smid); 5012 wait_for_completion_timeout(&adapter->driver_cmds.enc_cmd.done, 5013 LEAPRAID_ENC_CMD_TIMEOUT * HZ); 5014 if (!(adapter->driver_cmds.enc_cmd.status & LEAPRAID_CMD_DONE)) { 5015 dev_err(&adapter->pdev->dev, 5016 "%s: SEP command timeout, status=0x%x\n", 5017 __func__, adapter->driver_cmds.enc_cmd.status); 5018 leapraid_log_req_context(adapter, smid, sep_req); 5019 reset_flg = 5020 leapraid_check_reset( 5021 adapter->driver_cmds.enc_cmd.status); 5022 rc = -EFAULT; 5023 goto do_hard_reset; 5024 } 5025 5026 if (adapter->driver_cmds.enc_cmd.status & LEAPRAID_CMD_REPLY_VALID) 5027 memcpy(sep_rep, &adapter->driver_cmds.enc_cmd.reply, 5028 sizeof(struct leapraid_sep_rep)); 5029 do_hard_reset: 5030 if (reset_flg) { 5031 dev_info(&adapter->pdev->dev, "%s:%d: call hard_reset\n", 5032 __func__, __LINE__); 5033 leapraid_hard_reset_handler(adapter, FULL_RESET); 5034 } 5035 5036 adapter->driver_cmds.enc_cmd.status = LEAPRAID_CMD_NOT_USED; 5037 unlock: 5038 mutex_unlock(&adapter->driver_cmds.enc_cmd.mutex); 5039 return rc; 5040 } 5041 5042 static void leapraid_set_led(struct leapraid_adapter *adapter, 5043 struct leapraid_sas_dev *sas_dev, bool on) 5044 { 5045 struct leapraid_sep_rep sep_rep; 5046 struct leapraid_sep_req sep_req; 5047 5048 if (!sas_dev) 5049 return; 5050 5051 memset(&sep_req, 0, sizeof(struct leapraid_sep_req)); 5052 memset(&sep_rep, 0, sizeof(struct leapraid_sep_rep)); 5053 sep_req.func = LEAPRAID_FUNC_SCSI_ENC_PROCESSOR; 5054 sep_req.act = LEAPRAID_SEP_REQ_ACT_WRITE_STATUS; 5055 if (on) { 5056 u32 status = LEAPRAID_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT; 5057 5058 sep_req.slot_status = cpu_to_le32(status); 5059 sep_req.dev_hdl = cpu_to_le16(sas_dev->hdl); 5060 sep_req.flg = LEAPRAID_SEP_REQ_FLG_DEVHDL_ADDRESS; 5061 if (leapraid_send_enc_cmd(adapter, &sep_rep, &sep_req)) { 5062 leapraid_sdev_put(sas_dev); 5063 return; 5064 } 5065 5066 sas_dev->led_on = 1; 5067 leapraid_sdev_put(sas_dev); 5068 } else { 5069 sep_req.slot_status = 0; 5070 sep_req.slot = cpu_to_le16(sas_dev->slot); 5071 sep_req.dev_hdl = 0; 5072 sep_req.enc_hdl = cpu_to_le16(sas_dev->enc_hdl); 5073 sep_req.flg = LEAPRAID_SEP_REQ_FLG_ENCLOSURE_SLOT_ADDRESS; 5074 leapraid_send_enc_cmd(adapter, &sep_rep, &sep_req); 5075 } 5076 } 5077 5078 static int leapraid_wait_adapter_recovery(struct leapraid_adapter *adapter) 5079 { 5080 unsigned long flags; 5081 5082 while (leapraid_shost_in_recovery(adapter->shost) || 5083 READ_ONCE(adapter->access_ctrl.shost_recovering)) { 5084 if (READ_ONCE(adapter->access_ctrl.host_removing) || 5085 READ_ONCE(adapter->fw_evt_s.fw_evt_cleanup)) { 5086 spin_lock_irqsave( 5087 &adapter->reset_desc.adapter_reset_lock, 5088 flags); 5089 adapter->access_ctrl.shost_recover_async = 0; 5090 spin_unlock_irqrestore( 5091 &adapter->reset_desc.adapter_reset_lock, 5092 flags); 5093 5094 wake_up(&adapter->access_ctrl.shost_recover_wq); 5095 5096 dev_warn(&adapter->pdev->dev, 5097 "%s: Failed, shost %d, host %d\n", 5098 __func__, 5099 adapter->access_ctrl.shost_recovering, 5100 adapter->access_ctrl.host_removing); 5101 5102 return -EFAULT; 5103 } 5104 5105 wait_event_timeout( 5106 adapter->access_ctrl.recovery_waitq, 5107 (!leapraid_shost_in_recovery(adapter->shost) && 5108 !READ_ONCE(adapter->access_ctrl.shost_recovering)), 5109 msecs_to_jiffies(1000)); 5110 } 5111 5112 return 0; 5113 } 5114 5115 static void leapraid_fw_work(struct leapraid_adapter *adapter, 5116 struct leapraid_fw_evt_work *fw_evt) 5117 { 5118 struct leapraid_sas_dev *sas_dev; 5119 unsigned long flags; 5120 5121 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags); 5122 adapter->fw_evt_s.cur_evt = fw_evt; 5123 adapter->fw_evt_s.cur_evt_task = current; 5124 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags); 5125 leapraid_del_fw_evt_from_list(adapter, fw_evt); 5126 if (adapter->access_ctrl.host_removing || 5127 adapter->access_ctrl.pcie_recovering) { 5128 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags); 5129 leapraid_fw_evt_put(fw_evt); 5130 adapter->fw_evt_s.cur_evt = NULL; 5131 adapter->fw_evt_s.cur_evt_task = NULL; 5132 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags); 5133 return; 5134 } 5135 switch (fw_evt->evt_type) { 5136 case LEAPRAID_EVT_SAS_TOPO_CHANGE_LIST: 5137 leapraid_sas_topo_chg_evt(adapter, fw_evt); 5138 break; 5139 case LEAPRAID_EVT_IR_CHANGE: 5140 leapraid_sas_ir_chg_evt(adapter, fw_evt); 5141 break; 5142 case LEAPRAID_EVT_SAS_ENCL_DEV_STATUS_CHANGE: 5143 leapraid_sas_enc_dev_stat_chg_evt(adapter, fw_evt); 5144 break; 5145 case LEAPRAID_EVT_REMOVE_DEAD_DEV: 5146 if (leapraid_wait_adapter_recovery(adapter)) 5147 goto out_cleanup; 5148 5149 leapraid_hardreset_async_logic(adapter); 5150 break; 5151 case LEAPRAID_EVT_TURN_ON_PFA_LED: 5152 sas_dev = leapraid_get_sas_dev_by_hdl(adapter, 5153 fw_evt->dev_handle); 5154 leapraid_set_led(adapter, sas_dev, true); 5155 break; 5156 case LEAPRAID_EVT_SCAN_DEV_DONE: 5157 adapter->scan_dev_desc.scan_start = 0; 5158 break; 5159 default: 5160 break; 5161 } 5162 out_cleanup: 5163 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags); 5164 leapraid_fw_evt_put(fw_evt); 5165 adapter->fw_evt_s.cur_evt = NULL; 5166 adapter->fw_evt_s.cur_evt_task = NULL; 5167 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags); 5168 } 5169 5170 static void leapraid_sas_dev_stat_chg_evt( 5171 struct leapraid_adapter *adapter, 5172 struct leapraid_evt_data_sas_dev_status_change *event_data) 5173 { 5174 struct leapraid_starget_priv *starget_priv; 5175 struct leapraid_sas_dev *sas_dev; 5176 u64 sas_address; 5177 unsigned long flags; 5178 5179 switch (event_data->reason_code) { 5180 case LEAPRAID_EVT_SAS_DEV_STAT_RC_INTERNAL_DEV_RESET: 5181 case LEAPRAID_EVT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET: 5182 break; 5183 default: 5184 return; 5185 } 5186 5187 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 5188 5189 sas_address = le64_to_cpu(event_data->sas_address); 5190 sas_dev = leapraid_hold_lock_get_sas_dev_by_addr( 5191 adapter, 5192 sas_address, 5193 leapraid_get_port_by_id(adapter, 5194 event_data->physical_port, 5195 false)); 5196 if (!sas_dev || !sas_dev->starget) 5197 goto out_unlock; 5198 5199 starget_priv = sas_dev->starget->hostdata; 5200 if (starget_priv) { 5201 switch (event_data->reason_code) { 5202 case LEAPRAID_EVT_SAS_DEV_STAT_RC_INTERNAL_DEV_RESET: 5203 starget_priv->tm_busy = 1; 5204 break; 5205 case LEAPRAID_EVT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET: 5206 starget_priv->tm_busy = 0; 5207 break; 5208 } 5209 } 5210 5211 out_unlock: 5212 if (sas_dev) 5213 leapraid_sdev_put(sas_dev); 5214 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 5215 } 5216 5217 static void leapraid_set_volume_delete_flag(struct leapraid_adapter *adapter, 5218 u16 handle) 5219 { 5220 struct leapraid_raid_volume *raid_volume; 5221 struct leapraid_starget_priv *sas_target_priv_data; 5222 unsigned long flags; 5223 5224 raid_volume = leapraid_raid_volume_find_by_hdl(adapter, handle); 5225 if (raid_volume) { 5226 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags); 5227 if (raid_volume->starget && 5228 raid_volume->starget->hostdata) { 5229 sas_target_priv_data = raid_volume->starget->hostdata; 5230 sas_target_priv_data->deleted = 1; 5231 } 5232 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, 5233 flags); 5234 leapraid_raid_volume_put(raid_volume); 5235 } 5236 } 5237 5238 static void leapraid_check_ir_change_evt( 5239 struct leapraid_adapter *adapter, 5240 struct leapraid_evt_data_ir_change *evt_data) 5241 { 5242 u16 phys_disk_dev_hdl; 5243 5244 switch (evt_data->reason_code) { 5245 case LEAPRAID_EVT_IR_RC_VOLUME_DELETE: 5246 leapraid_set_volume_delete_flag( 5247 adapter, 5248 le16_to_cpu(evt_data->vol_dev_hdl)); 5249 break; 5250 case LEAPRAID_EVT_IR_RC_PD_UNHIDDEN_TO_DELETE: 5251 phys_disk_dev_hdl = 5252 le16_to_cpu(evt_data->phys_disk_dev_hdl); 5253 if (!phys_disk_dev_hdl || 5254 phys_disk_dev_hdl > 5255 adapter->adapter_attr.features.max_dev_handle) { 5256 dev_warn(&adapter->pdev->dev, 5257 "%s: Invalid device handle\n", __func__); 5258 } else { 5259 clear_bit(phys_disk_dev_hdl, 5260 adapter->dev_topo.pd_hdls); 5261 leapraid_tgt_rst_send(adapter, phys_disk_dev_hdl); 5262 } 5263 break; 5264 } 5265 } 5266 5267 static void leapraid_topo_del_evts_process_exp_status( 5268 struct leapraid_adapter *adapter, 5269 struct leapraid_evt_data_sas_topo_change_list *evt_data) 5270 { 5271 struct leapraid_fw_evt_work *fw_evt = NULL; 5272 struct leapraid_evt_data_sas_topo_change_list *loc_evt_data; 5273 unsigned long flags; 5274 u16 exp_hdl; 5275 5276 exp_hdl = le16_to_cpu(evt_data->exp_dev_hdl); 5277 5278 switch (evt_data->exp_status) { 5279 case LEAPRAID_EVT_SAS_TOPO_ES_NOT_RESPONDING: 5280 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags); 5281 list_for_each_entry(fw_evt, 5282 &adapter->fw_evt_s.fw_evt_list, list) { 5283 if (fw_evt->evt_type != 5284 LEAPRAID_EVT_SAS_TOPO_CHANGE_LIST || 5285 fw_evt->ignore) 5286 continue; 5287 5288 loc_evt_data = fw_evt->evt_data; 5289 if ((loc_evt_data->exp_status == 5290 LEAPRAID_EVT_SAS_TOPO_ES_ADDED || 5291 loc_evt_data->exp_status == 5292 LEAPRAID_EVT_SAS_TOPO_ES_RESPONDING) && 5293 le16_to_cpu(loc_evt_data->exp_dev_hdl) == exp_hdl) 5294 fw_evt->ignore = 1; 5295 } 5296 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags); 5297 break; 5298 default: 5299 break; 5300 } 5301 } 5302 5303 static void leapraid_check_topo_del_evts( 5304 struct leapraid_adapter *adapter, 5305 struct leapraid_evt_data_sas_topo_change_list *evt_data) 5306 { 5307 int reason_code; 5308 u16 hdl; 5309 int i; 5310 5311 for (i = 0; i < evt_data->entry_num; i++) { 5312 hdl = le16_to_cpu(evt_data->phy[i].attached_dev_hdl); 5313 if (!hdl) 5314 continue; 5315 5316 reason_code = evt_data->phy[i].phy_status & 5317 LEAPRAID_EVT_SAS_TOPO_RC_MASK; 5318 if (reason_code == 5319 LEAPRAID_EVT_SAS_TOPO_RC_TARG_NOT_RESPONDING) 5320 leapraid_tgt_not_responding(adapter, hdl); 5321 } 5322 leapraid_topo_del_evts_process_exp_status(adapter, evt_data); 5323 } 5324 5325 static bool leapraid_async_evt_validate( 5326 struct leapraid_adapter *adapter, 5327 struct leapraid_evt_notify_rep *event_notify_rep) 5328 { 5329 size_t msg_len; 5330 size_t evt_sz; 5331 size_t evt_avail; 5332 u16 evt; 5333 5334 msg_len = event_notify_rep->msg_len * sizeof(u32); 5335 if (msg_len > LEAPRAID_REPLY_SIZE || 5336 msg_len < offsetof(struct leapraid_evt_notify_rep, evt_data)) { 5337 dev_warn(&adapter->pdev->dev, 5338 "%s: Invalid async event msg_len=%zu\n", 5339 __func__, msg_len); 5340 return false; 5341 } 5342 5343 evt_sz = le16_to_cpu(event_notify_rep->evt_data_len) * sizeof(u32); 5344 evt_avail = msg_len - 5345 offsetof(struct leapraid_evt_notify_rep, evt_data); 5346 if (evt_sz > evt_avail) { 5347 dev_warn(&adapter->pdev->dev, 5348 "%s: Invalid async event evt_data_len=%zu\n", 5349 __func__, evt_sz); 5350 return false; 5351 } 5352 5353 evt = le16_to_cpu(event_notify_rep->evt); 5354 switch (evt) { 5355 case LEAPRAID_EVT_SAS_DEV_STATUS_CHANGE: 5356 if (evt_sz < 5357 sizeof(struct leapraid_evt_data_sas_dev_status_change)) 5358 goto invalid_evt_sz; 5359 break; 5360 case LEAPRAID_EVT_IR_CHANGE: 5361 if (evt_sz < sizeof(struct leapraid_evt_data_ir_change)) 5362 goto invalid_evt_sz; 5363 break; 5364 case LEAPRAID_EVT_SAS_TOPO_CHANGE_LIST: 5365 { 5366 struct leapraid_evt_data_sas_topo_change_list *evt_data = 5367 (void *)event_notify_rep->evt_data; 5368 size_t hdr_sz; 5369 5370 hdr_sz = 5371 offsetof(struct leapraid_evt_data_sas_topo_change_list, 5372 phy); 5373 if (evt_sz < hdr_sz) 5374 goto invalid_evt_sz; 5375 5376 if (evt_data->entry_num > 5377 (evt_sz - hdr_sz) / sizeof(evt_data->phy[0])) 5378 goto invalid_evt_sz; 5379 break; 5380 } 5381 case LEAPRAID_EVT_SAS_ENCL_DEV_STATUS_CHANGE: 5382 if (evt_sz < 5383 sizeof(struct leapraid_evt_data_sas_enc_dev_status_change)) 5384 goto invalid_evt_sz; 5385 break; 5386 default: 5387 break; 5388 } 5389 5390 return true; 5391 5392 invalid_evt_sz: 5393 dev_warn(&adapter->pdev->dev, 5394 "%s: Invalid async event size=%zu for evt=0x%x\n", 5395 __func__, evt_sz, evt); 5396 return false; 5397 } 5398 5399 static bool leapraid_async_process_evt( 5400 struct leapraid_adapter *adapter, 5401 struct leapraid_evt_notify_rep *event_notify_rep) 5402 { 5403 u16 evt = le16_to_cpu(event_notify_rep->evt); 5404 bool exit_flag = false; 5405 5406 if (adapter->access_ctrl.host_removing || 5407 adapter->access_ctrl.pcie_recovering) 5408 return true; 5409 5410 switch (evt) { 5411 case LEAPRAID_EVT_SAS_DEV_STATUS_CHANGE: 5412 leapraid_sas_dev_stat_chg_evt( 5413 adapter, 5414 (struct leapraid_evt_data_sas_dev_status_change 5415 *)event_notify_rep->evt_data); 5416 break; 5417 case LEAPRAID_EVT_IR_CHANGE: 5418 leapraid_check_ir_change_evt( 5419 adapter, 5420 (struct leapraid_evt_data_ir_change 5421 *)event_notify_rep->evt_data); 5422 break; 5423 case LEAPRAID_EVT_SAS_TOPO_CHANGE_LIST: 5424 leapraid_check_topo_del_evts( 5425 adapter, 5426 (struct leapraid_evt_data_sas_topo_change_list 5427 *)event_notify_rep->evt_data); 5428 if (adapter->access_ctrl.shost_recovering) { 5429 exit_flag = true; 5430 return exit_flag; 5431 } 5432 break; 5433 case LEAPRAID_EVT_SAS_ENCL_DEV_STATUS_CHANGE: 5434 break; 5435 default: 5436 exit_flag = true; 5437 return exit_flag; 5438 } 5439 5440 return exit_flag; 5441 } 5442 5443 static void leapraid_async_evt_cb_enqueue( 5444 struct leapraid_adapter *adapter, 5445 struct leapraid_evt_notify_rep *evt_notify_rep) 5446 { 5447 struct leapraid_fw_evt_work *fw_evt; 5448 u16 evt_sz; 5449 5450 fw_evt = leapraid_alloc_fw_evt_work(); 5451 if (!fw_evt) 5452 return; 5453 5454 evt_sz = le16_to_cpu(evt_notify_rep->evt_data_len) * sizeof(u32); 5455 fw_evt->evt_data = kmemdup(evt_notify_rep->evt_data, 5456 evt_sz, GFP_ATOMIC); 5457 if (!fw_evt->evt_data) { 5458 leapraid_fw_evt_put(fw_evt); 5459 return; 5460 } 5461 fw_evt->adapter = adapter; 5462 fw_evt->evt_type = le16_to_cpu(evt_notify_rep->evt); 5463 leapraid_fw_evt_add(adapter, fw_evt); 5464 leapraid_fw_evt_put(fw_evt); 5465 } 5466 5467 static void leapraid_async_evt_cb(struct leapraid_adapter *adapter, 5468 u8 msix_index, u32 rep_paddr) 5469 { 5470 struct leapraid_evt_notify_rep *evt_notify_rep; 5471 5472 if (adapter->access_ctrl.host_removing || 5473 adapter->access_ctrl.pcie_recovering) 5474 return; 5475 5476 evt_notify_rep = leapraid_get_reply_vaddr(adapter, rep_paddr); 5477 if (unlikely(!evt_notify_rep)) 5478 return; 5479 5480 if (!leapraid_async_evt_validate(adapter, evt_notify_rep)) 5481 return; 5482 5483 if (leapraid_async_process_evt(adapter, evt_notify_rep)) 5484 return; 5485 5486 leapraid_async_evt_cb_enqueue(adapter, evt_notify_rep); 5487 } 5488 5489 static void leapraid_handle_async_event(struct leapraid_adapter *adapter, 5490 u8 msix_index, u32 reply) 5491 { 5492 struct leapraid_evt_notify_rep *leap_mpi_rep = 5493 leapraid_get_reply_vaddr(adapter, reply); 5494 5495 if (!leap_mpi_rep) 5496 return; 5497 5498 if (leap_mpi_rep->func != LEAPRAID_FUNC_EVENT_NOTIFY) 5499 return; 5500 5501 leapraid_async_evt_cb(adapter, msix_index, reply); 5502 } 5503 5504 void leapraid_async_turn_on_led(struct leapraid_adapter *adapter, u16 handle) 5505 { 5506 struct leapraid_fw_evt_work *fw_event; 5507 5508 fw_event = leapraid_alloc_fw_evt_work(); 5509 if (!fw_event) 5510 return; 5511 5512 fw_event->dev_handle = handle; 5513 fw_event->adapter = adapter; 5514 fw_event->evt_type = LEAPRAID_EVT_TURN_ON_PFA_LED; 5515 leapraid_fw_evt_add(adapter, fw_event); 5516 leapraid_fw_evt_put(fw_event); 5517 } 5518 5519 static void leapraid_hardreset_barrier(struct leapraid_adapter *adapter) 5520 { 5521 struct leapraid_fw_evt_work *fw_event; 5522 5523 fw_event = leapraid_alloc_fw_evt_work(); 5524 if (!fw_event) 5525 return; 5526 5527 fw_event->adapter = adapter; 5528 fw_event->evt_type = LEAPRAID_EVT_REMOVE_DEAD_DEV; 5529 leapraid_fw_evt_add(adapter, fw_event); 5530 leapraid_fw_evt_put(fw_event); 5531 } 5532 5533 static void leapraid_scan_dev_complete(struct leapraid_adapter *adapter) 5534 { 5535 struct leapraid_fw_evt_work *fw_evt; 5536 5537 fw_evt = leapraid_alloc_fw_evt_work(); 5538 if (!fw_evt) 5539 return; 5540 5541 fw_evt->evt_type = LEAPRAID_EVT_SCAN_DEV_DONE; 5542 fw_evt->adapter = adapter; 5543 leapraid_fw_evt_add(adapter, fw_evt); 5544 leapraid_fw_evt_put(fw_evt); 5545 } 5546 5547 static void leapraid_handle_scan_cb(struct leapraid_adapter *adapter, 5548 struct leapraid_driver_cmd *cmd, 5549 struct leapraid_rep *rep) 5550 { 5551 u16 status; 5552 5553 cmd->status &= ~LEAPRAID_CMD_PENDING; 5554 5555 status = le16_to_cpu(rep->adapter_status) & 5556 LEAPRAID_ADAPTER_STATUS_MASK; 5557 if (status != LEAPRAID_ADAPTER_STATUS_SUCCESS) 5558 adapter->scan_dev_desc.scan_dev_failed = 1; 5559 5560 if (!cmd->async_scan_dev) { 5561 complete(&cmd->done); 5562 return; 5563 } 5564 5565 if (status == LEAPRAID_ADAPTER_STATUS_SUCCESS) 5566 leapraid_scan_dev_complete(adapter); 5567 else 5568 adapter->scan_dev_desc.scan_start_failed = status; 5569 } 5570 5571 static void leapraid_handle_ctl_cb(struct leapraid_adapter *adapter, 5572 struct leapraid_rep *rep, 5573 u16 taskid) 5574 { 5575 struct leapraid_scsiio_rep *scsiio_reply; 5576 5577 if (rep->function != LEAPRAID_FUNC_SCSIIO && 5578 rep->function != LEAPRAID_FUNC_SCSIIO_RAID_PASSTHROUGH) 5579 return; 5580 5581 scsiio_reply = (struct leapraid_scsiio_rep *)rep; 5582 if (!(scsiio_reply->scsi_state & 5583 LEAPRAID_SCSI_STATE_AUTOSENSE_VALID)) 5584 return; 5585 5586 memcpy(&adapter->driver_cmds.ctl_cmd.sense, 5587 leapraid_get_sense_buffer(adapter, taskid), 5588 min_t(u32, SCSI_SENSE_BUFFERSIZE, 5589 le32_to_cpu(scsiio_reply->sense_count))); 5590 } 5591 5592 static bool leapraid_driver_cmds_done(struct leapraid_adapter *adapter, 5593 u16 taskid, u8 msix_index, 5594 u32 rep_paddr, u8 cb_idx) 5595 { 5596 struct leapraid_rep *leap_mpi_rep = 5597 leapraid_get_reply_vaddr(adapter, rep_paddr); 5598 struct leapraid_driver_cmd *sp_cmd, *_sp_cmd = NULL; 5599 u8 reply_len; 5600 5601 list_for_each_entry(sp_cmd, &adapter->driver_cmds.special_cmd_list, 5602 list) 5603 if (cb_idx == sp_cmd->cb_idx) { 5604 _sp_cmd = sp_cmd; 5605 break; 5606 } 5607 5608 if (WARN_ON(!_sp_cmd)) 5609 return true; 5610 if (WARN_ON(_sp_cmd->status == LEAPRAID_CMD_NOT_USED)) 5611 return true; 5612 if (WARN_ON(taskid != _sp_cmd->hp_taskid && 5613 taskid != _sp_cmd->taskid && 5614 taskid != _sp_cmd->inter_taskid)) 5615 return true; 5616 _sp_cmd->status |= LEAPRAID_CMD_DONE; 5617 if (leap_mpi_rep) { 5618 reply_len = leap_mpi_rep->msg_len * sizeof(u32); 5619 if (reply_len > LEAPRAID_REPLY_SIZE) 5620 reply_len = LEAPRAID_REPLY_SIZE; 5621 memcpy(&_sp_cmd->reply, leap_mpi_rep, reply_len); 5622 _sp_cmd->status |= LEAPRAID_CMD_REPLY_VALID; 5623 5624 if (_sp_cmd->cb_idx == LEAPRAID_SCAN_DEV_CB_IDX) { 5625 leapraid_handle_scan_cb(adapter, _sp_cmd, 5626 leap_mpi_rep); 5627 return true; 5628 } 5629 5630 if (_sp_cmd->cb_idx == LEAPRAID_CTL_CB_IDX) 5631 leapraid_handle_ctl_cb(adapter, leap_mpi_rep, taskid); 5632 } 5633 5634 _sp_cmd->status &= ~LEAPRAID_CMD_PENDING; 5635 complete(&_sp_cmd->done); 5636 5637 return true; 5638 } 5639 5640 static void leapraid_complete_task(struct leapraid_adapter *adapter, 5641 u16 taskid, u8 msix_idx, u32 rep) 5642 { 5643 bool scsiio_task = taskid <= adapter->shost->can_queue; 5644 5645 if (scsiio_task) { 5646 if (leapraid_scsiio_done(adapter, taskid, msix_idx, rep)) 5647 leapraid_free_taskid(adapter, taskid); 5648 return; 5649 } 5650 5651 if (leapraid_driver_cmds_done(adapter, taskid, msix_idx, rep, 5652 leapraid_get_cb_idx(adapter, taskid))) 5653 leapraid_free_taskid(adapter, taskid); 5654 } 5655 5656 static void leapraid_request_descript_handler( 5657 struct leapraid_adapter *adapter, 5658 union leapraid_rep_desc_union *rpf, 5659 u8 req_desc_type, u8 msix_idx) 5660 { 5661 u32 rep; 5662 u16 taskid; 5663 5664 rep = 0; 5665 taskid = le16_to_cpu(rpf->dflt_rep.taskid); 5666 switch (req_desc_type) { 5667 case LEAPRAID_RPY_DESC_FLG_FP_SCSI_IO_SUCCESS: 5668 case LEAPRAID_RPY_DESC_FLG_SCSI_IO_SUCCESS: 5669 leapraid_complete_task(adapter, taskid, msix_idx, 0); 5670 break; 5671 case LEAPRAID_RPY_DESC_FLG_ADDRESS_REPLY: 5672 rep = le32_to_cpu(rpf->addr_rep.rep_frame_addr); 5673 if (rep > (u32)adapter->mem_desc.rep_msg_dma + 5674 adapter->adapter_attr.rep_msg_qd * 5675 LEAPRAID_REPLY_SIZE || 5676 rep < (u32)adapter->mem_desc.rep_msg_dma) 5677 rep = 0; 5678 5679 if (taskid) 5680 leapraid_complete_task(adapter, taskid, msix_idx, rep); 5681 else 5682 leapraid_handle_async_event(adapter, msix_idx, rep); 5683 5684 if (!rep) 5685 return; 5686 5687 adapter->rep_msg_host_idx = 5688 (adapter->rep_msg_host_idx == 5689 (adapter->adapter_attr.rep_msg_qd - 1)) ? 5690 0 : adapter->rep_msg_host_idx + 1; 5691 adapter->mem_desc.rep_msg_addr[adapter->rep_msg_host_idx] = 5692 cpu_to_le32(rep); 5693 wmb(); /* Make sure that all write ops are in order */ 5694 writel(adapter->rep_msg_host_idx, 5695 &adapter->iomem_base->rep_msg_host_idx); 5696 5697 break; 5698 default: 5699 break; 5700 } 5701 } 5702 5703 int leapraid_rep_queue_handler(struct leapraid_rq *rq) 5704 { 5705 struct leapraid_adapter *adapter = rq->adapter; 5706 union leapraid_rep_desc_union *rep_desc; 5707 u8 req_desc_type; 5708 u64 finish_cmds; 5709 u8 msix_idx; 5710 5711 msix_idx = rq->msix_idx; 5712 finish_cmds = 0; 5713 if (!atomic_add_unless(&rq->busy, LEAPRAID_BUSY_LIMIT, 5714 LEAPRAID_BUSY_LIMIT)) 5715 return finish_cmds; 5716 5717 rep_desc = &rq->rep_desc[rq->rep_post_host_idx]; 5718 req_desc_type = rep_desc->dflt_rep.rep_flg & 5719 LEAPRAID_RPY_DESC_FLG_TYPE_MASK; 5720 if (req_desc_type == LEAPRAID_RPY_DESC_FLG_UNUSED) { 5721 atomic_dec(&rq->busy); 5722 return finish_cmds; 5723 } 5724 5725 for (;;) { 5726 if (rep_desc->u.low == UINT_MAX || 5727 rep_desc->u.high == UINT_MAX) 5728 break; 5729 5730 leapraid_request_descript_handler(adapter, rep_desc, 5731 req_desc_type, msix_idx); 5732 dev_dbg(&adapter->pdev->dev, 5733 "LEAPRAID_SCSIIO: Handled Desc taskid %d, msix %d\n", 5734 rep_desc->dflt_rep.taskid, msix_idx); 5735 rep_desc->words = cpu_to_le64(ULLONG_MAX); 5736 rq->rep_post_host_idx = 5737 (rq->rep_post_host_idx == 5738 (adapter->adapter_attr.rep_desc_qd - 5739 LEAPRAID_BUSY_LIMIT)) ? 5740 0 : rq->rep_post_host_idx + 1; 5741 req_desc_type = 5742 rq->rep_desc[rq->rep_post_host_idx].dflt_rep.rep_flg & 5743 LEAPRAID_RPY_DESC_FLG_TYPE_MASK; 5744 finish_cmds++; 5745 if (req_desc_type == LEAPRAID_RPY_DESC_FLG_UNUSED) 5746 break; 5747 rep_desc = rq->rep_desc + rq->rep_post_host_idx; 5748 } 5749 5750 if (!finish_cmds) { 5751 atomic_dec(&rq->busy); 5752 return finish_cmds; 5753 } 5754 5755 wmb(); /* Make sure that all write ops are in order */ 5756 writel(rq->rep_post_host_idx | ((msix_idx & LEAPRAID_MSIX_GROUP_MASK) << 5757 LEAPRAID_RPHI_MSIX_IDX_SHIFT), 5758 &adapter->iomem_base->rep_post_reg_idx[ 5759 msix_idx / LEAPRAID_MSIX_GROUP_SIZE].idx); 5760 atomic_dec(&rq->busy); 5761 return finish_cmds; 5762 } 5763 5764 static irqreturn_t leapraid_irq_handler(int irq, void *bus_id) 5765 { 5766 struct leapraid_rq *rq = bus_id; 5767 struct leapraid_adapter *adapter = rq->adapter; 5768 5769 dev_dbg(&adapter->pdev->dev, 5770 "LEAPRAID_SCSIIO: Receive a interrupt, irq %d msix %d\n", 5771 irq, rq->msix_idx); 5772 5773 if (adapter->mask_int) 5774 return IRQ_NONE; 5775 5776 return (leapraid_rep_queue_handler(rq) > 0 ? 5777 IRQ_HANDLED : IRQ_NONE); 5778 } 5779 5780 void leapraid_sync_irqs(struct leapraid_adapter *adapter, bool poll) 5781 { 5782 struct leapraid_int_rq *int_rq; 5783 struct leapraid_blk_mq_poll_rq *blk_mq_poll_rq; 5784 unsigned int i; 5785 5786 if (!adapter->notification_desc.msix_enable) 5787 return; 5788 5789 if (adapter->access_ctrl.shost_recovering || 5790 adapter->access_ctrl.host_removing || 5791 adapter->access_ctrl.pcie_recovering) 5792 return; 5793 5794 for (i = 0; i < adapter->notification_desc.iopoll_qdex; i++) { 5795 int_rq = &adapter->notification_desc.int_rqs[i]; 5796 if (adapter->access_ctrl.shost_recovering || 5797 adapter->access_ctrl.host_removing || 5798 adapter->access_ctrl.pcie_recovering) 5799 return; 5800 5801 if (int_rq->rq.msix_idx == 0) 5802 continue; 5803 5804 synchronize_irq(pci_irq_vector(adapter->pdev, 5805 int_rq->rq.msix_idx)); 5806 if (poll) 5807 leapraid_rep_queue_handler(&int_rq->rq); 5808 } 5809 5810 for (i = 0; i < adapter->notification_desc.iopoll_qcnt; i++) { 5811 blk_mq_poll_rq = 5812 &adapter->notification_desc.blk_mq_poll_rqs[i]; 5813 if (adapter->access_ctrl.shost_recovering || 5814 adapter->access_ctrl.host_removing || 5815 adapter->access_ctrl.pcie_recovering) 5816 return; 5817 5818 if (blk_mq_poll_rq->rq.msix_idx == 0) 5819 continue; 5820 5821 leapraid_rep_queue_handler(&blk_mq_poll_rq->rq); 5822 } 5823 } 5824 5825 static void leapraid_sync_irqs_for_cleanup(struct leapraid_adapter *adapter) 5826 { 5827 struct leapraid_notification_desc *desc = &adapter->notification_desc; 5828 struct leapraid_int_rq *int_rq; 5829 unsigned int i; 5830 5831 if (!adapter->mask_int && leapraid_pci_active(adapter)) 5832 leapraid_mask_int(adapter); 5833 5834 for (i = 0; i < desc->int_rqs_allocated; i++) { 5835 int_rq = &desc->int_rqs[i]; 5836 synchronize_irq(pci_irq_vector(adapter->pdev, 5837 int_rq->rq.msix_idx)); 5838 } 5839 } 5840 5841 void leapraid_mq_polling_pause(struct leapraid_adapter *adapter) 5842 { 5843 struct leapraid_notification_desc *desc; 5844 int iopoll_q_count; 5845 int qid; 5846 5847 desc = &adapter->notification_desc; 5848 iopoll_q_count = adapter->adapter_attr.rq_cnt - desc->iopoll_qdex; 5849 5850 for (qid = 0; qid < iopoll_q_count; qid++) 5851 atomic_set(&desc->blk_mq_poll_rqs[qid].pause, 1); 5852 5853 for (qid = 0; qid < iopoll_q_count; qid++) { 5854 while (atomic_read(&desc->blk_mq_poll_rqs[qid].busy)) { 5855 cpu_relax(); 5856 udelay(LEAPRAID_IO_POLL_DELAY_US); 5857 } 5858 } 5859 } 5860 5861 void leapraid_mq_polling_resume(struct leapraid_adapter *adapter) 5862 { 5863 struct leapraid_notification_desc *desc; 5864 int iopoll_q_count; 5865 int qid; 5866 5867 desc = &adapter->notification_desc; 5868 iopoll_q_count = adapter->adapter_attr.rq_cnt - desc->iopoll_qdex; 5869 5870 for (qid = 0; qid < iopoll_q_count; qid++) 5871 atomic_set(&desc->blk_mq_poll_rqs[qid].pause, 0); 5872 } 5873 5874 static int leapraid_unlock_host_diag(struct leapraid_adapter *adapter, 5875 u32 *host_diag) 5876 { 5877 const u32 unlock_seq[] = { 5878 LEAPRAID_WRSEQ_FLUSH_KEY_VALUE, 5879 LEAPRAID_WRSEQ_1ST_KEY_VALUE, 5880 LEAPRAID_WRSEQ_2ND_KEY_VALUE, 5881 LEAPRAID_WRSEQ_3RD_KEY_VALUE, 5882 LEAPRAID_WRSEQ_4TH_KEY_VALUE, 5883 LEAPRAID_WRSEQ_5TH_KEY_VALUE, 5884 LEAPRAID_WRSEQ_6TH_KEY_VALUE 5885 }; 5886 5887 const int max_retries = LEAPRAID_UNLOCK_RETRY_LIMIT; 5888 int retry = 0; 5889 unsigned int i; 5890 5891 *host_diag = 0; 5892 while (retry++ <= max_retries) { 5893 for (i = 0; i < ARRAY_SIZE(unlock_seq); i++) 5894 writel(unlock_seq[i], &adapter->iomem_base->ws); 5895 5896 msleep(LEAPRAID_UNLOCK_SLEEP_MS); 5897 5898 *host_diag = leapraid_readl(&adapter->iomem_base->host_diag); 5899 if (*host_diag & LEAPRAID_DIAG_WRITE_ENABLE) 5900 return 0; 5901 } 5902 5903 dev_err(&adapter->pdev->dev, "Try host reset timeout!\n"); 5904 return -EFAULT; 5905 } 5906 5907 static int leapraid_host_diag_reset(struct leapraid_adapter *adapter) 5908 { 5909 u32 host_diag; 5910 5911 pci_cfg_access_lock(adapter->pdev); 5912 5913 mutex_lock(&adapter->reset_desc.host_diag_mutex); 5914 if (leapraid_unlock_host_diag(adapter, &host_diag)) 5915 goto out_cleanup; 5916 5917 writel(host_diag | LEAPRAID_DIAG_RESET, 5918 &adapter->iomem_base->host_diag); 5919 5920 msleep(LEAPRAID_MSLEEP_EXTRA_LONG_MS); 5921 msleep(LEAPRAID_MSLEEP_NORMAL_MS); 5922 5923 host_diag = leapraid_readl(&adapter->iomem_base->host_diag); 5924 if (host_diag == LEAPRAID_INVALID_HOST_DIAG_VAL || 5925 host_diag & LEAPRAID_DIAG_RESET) 5926 goto out_cleanup; 5927 5928 writel(0x0, &adapter->iomem_base->ws); 5929 mutex_unlock(&adapter->reset_desc.host_diag_mutex); 5930 if (!leapraid_wait_adapter_ready(adapter)) 5931 goto out_failed; 5932 5933 pci_cfg_access_unlock(adapter->pdev); 5934 return 0; 5935 5936 out_cleanup: 5937 mutex_unlock(&adapter->reset_desc.host_diag_mutex); 5938 out_failed: 5939 pci_cfg_access_unlock(adapter->pdev); 5940 dev_err(&adapter->pdev->dev, "Host diag failed\n"); 5941 return -EFAULT; 5942 } 5943 5944 static int leapraid_find_matching_port( 5945 struct leapraid_card_port *card_port_table, 5946 u8 count, u8 port_id, u64 sas_addr) 5947 { 5948 int i; 5949 5950 for (i = 0; i < count; i++) 5951 if (card_port_table[i].port_id == port_id && 5952 card_port_table[i].sas_address == sas_addr) 5953 return i; 5954 5955 return LEAPRAID_INVALID_INDEX; 5956 } 5957 5958 static u8 leapraid_fill_card_port_table( 5959 struct leapraid_adapter *adapter, 5960 struct leapraid_sas_io_unit_p0 *sas_iounit_p0, 5961 struct leapraid_card_port *new_card_port_table) 5962 { 5963 u8 port_entry_num = 0, port_id; 5964 u16 attached_hdl; 5965 u64 attached_sas_addr; 5966 int i, idx; 5967 5968 for (i = 0; i < adapter->dev_topo.card.phys_num; i++) { 5969 if (sas_iounit_p0->phy_info[i].neg_link_rate >> 5970 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT < 5971 LEAPRAID_SAS_NEG_LINK_RATE_1_5) 5972 continue; 5973 5974 attached_hdl = le16_to_cpu(sas_iounit_p0->phy_info[i] 5975 .attached_dev_hdl); 5976 if (leapraid_get_sas_address(adapter, 5977 attached_hdl, 5978 &attached_sas_addr) != 0) 5979 continue; 5980 5981 port_id = sas_iounit_p0->phy_info[i].port; 5982 5983 idx = leapraid_find_matching_port(new_card_port_table, 5984 port_entry_num, 5985 port_id, 5986 attached_sas_addr); 5987 if (idx >= 0) { 5988 new_card_port_table[idx].phy_mask |= BIT(i); 5989 } else { 5990 new_card_port_table[port_entry_num].port_id = port_id; 5991 new_card_port_table[port_entry_num].phy_mask = BIT(i); 5992 new_card_port_table[port_entry_num].sas_address = 5993 attached_sas_addr; 5994 port_entry_num++; 5995 } 5996 } 5997 5998 return port_entry_num; 5999 } 6000 6001 static u8 leapraid_set_new_card_port_table_after_reset( 6002 struct leapraid_adapter *adapter, 6003 struct leapraid_card_port *new_card_port_table) 6004 { 6005 union cfg_param_1 cfgp1 = {0}; 6006 union cfg_param_2 cfgp2 = {0}; 6007 struct leapraid_sas_io_unit_p0 *sas_iounit_p0; 6008 u8 port_entry_num = 0; 6009 u16 sz; 6010 6011 sz = offsetof(struct leapraid_sas_io_unit_p0, phy_info) + 6012 (adapter->dev_topo.card.phys_num * 6013 sizeof(struct leapraid_sas_io_unit0_phy_info)); 6014 sas_iounit_p0 = kzalloc(sz, GFP_KERNEL); 6015 if (!sas_iounit_p0) 6016 return port_entry_num; 6017 6018 cfgp1.size = sz; 6019 if (leapraid_op_config_page(adapter, sas_iounit_p0, cfgp1, cfgp2, 6020 GET_SAS_IOUNIT_PG0) != 0) 6021 goto out_free; 6022 6023 port_entry_num = leapraid_fill_card_port_table(adapter, 6024 sas_iounit_p0, 6025 new_card_port_table); 6026 out_free: 6027 kfree(sas_iounit_p0); 6028 return port_entry_num; 6029 } 6030 6031 static void leapraid_update_existing_port(struct leapraid_adapter *adapter, 6032 struct leapraid_card_port *new_table, 6033 int entry_idx, int port_entry_num) 6034 { 6035 struct leapraid_card_port *matched_card_port; 6036 int matched_code; 6037 int count, lcount = 0; 6038 u64 sas_addr; 6039 int i; 6040 6041 matched_code = leapraid_check_card_port(adapter, 6042 &new_table[entry_idx], 6043 &matched_card_port, 6044 &count); 6045 6046 if (!matched_card_port) 6047 return; 6048 6049 if (matched_code == SAME_PORT_WITH_PARTIALLY_CHANGED_PHYS || 6050 matched_code == SAME_ADDR_WITH_PARTIALLY_CHANGED_PHYS) { 6051 leapraid_add_or_del_phys_from_existing_port(adapter, 6052 matched_card_port, 6053 new_table, 6054 entry_idx, 6055 port_entry_num); 6056 } else if (matched_code == SAME_ADDR_ONLY) { 6057 sas_addr = new_table[entry_idx].sas_address; 6058 for (i = 0; i < port_entry_num; i++) 6059 if (new_table[i].sas_address == sas_addr) 6060 lcount++; 6061 6062 if (count > 1 || lcount > 1) 6063 return; 6064 6065 leapraid_add_or_del_phys_from_existing_port(adapter, 6066 matched_card_port, 6067 new_table, 6068 entry_idx, 6069 port_entry_num); 6070 } 6071 6072 if (matched_card_port->port_id != new_table[entry_idx].port_id) 6073 matched_card_port->port_id = new_table[entry_idx].port_id; 6074 6075 matched_card_port->flg &= ~LEAPRAID_CARD_PORT_FLG_DIRTY; 6076 matched_card_port->phy_mask = new_table[entry_idx].phy_mask; 6077 } 6078 6079 static void leapraid_update_card_port_after_reset( 6080 struct leapraid_adapter *adapter) 6081 { 6082 struct leapraid_card_port *new_card_port_table; 6083 struct leapraid_card_port *matched_card_port; 6084 u8 port_entry_num; 6085 u8 nr_phys; 6086 int i; 6087 6088 if (leapraid_get_adapter_phys(adapter, &nr_phys) || !nr_phys) 6089 return; 6090 6091 if (!adapter->dev_topo.card.card_phy) { 6092 adapter->dev_topo.card.card_phy = 6093 kcalloc(nr_phys, sizeof(struct leapraid_card_phy), 6094 GFP_KERNEL); 6095 if (!adapter->dev_topo.card.card_phy) 6096 return; 6097 } 6098 6099 adapter->dev_topo.card.phys_num = nr_phys; 6100 6101 new_card_port_table = kcalloc(adapter->dev_topo.card.phys_num, 6102 sizeof(struct leapraid_card_port), 6103 GFP_KERNEL); 6104 if (!new_card_port_table) 6105 return; 6106 6107 port_entry_num = 6108 leapraid_set_new_card_port_table_after_reset( 6109 adapter, 6110 new_card_port_table); 6111 if (!port_entry_num) 6112 goto out_free_port_table; 6113 6114 list_for_each_entry(matched_card_port, 6115 &adapter->dev_topo.card_port_list, list) 6116 matched_card_port->flg |= LEAPRAID_CARD_PORT_FLG_DIRTY; 6117 6118 matched_card_port = NULL; 6119 for (i = 0; i < port_entry_num; i++) 6120 leapraid_update_existing_port(adapter, 6121 new_card_port_table, 6122 i, port_entry_num); 6123 out_free_port_table: 6124 kfree(new_card_port_table); 6125 } 6126 6127 static bool leapraid_is_valid_vphy( 6128 struct leapraid_adapter *adapter, 6129 struct leapraid_sas_io_unit_p0 *sas_io_unit_p0, 6130 int phy_index) 6131 { 6132 union cfg_param_1 cfgp1 = {0}; 6133 union cfg_param_2 cfgp2 = {0}; 6134 struct leapraid_sas_phy_p0 phy_p0; 6135 u32 dev_info; 6136 6137 if (sas_io_unit_p0->phy_info[phy_index].neg_link_rate >> 6138 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT < 6139 LEAPRAID_SAS_NEG_LINK_RATE_1_5) 6140 return false; 6141 6142 dev_info = le32_to_cpu(sas_io_unit_p0->phy_info[phy_index] 6143 .controller_phy_dev_info); 6144 if (!(dev_info & LEAPRAID_DEVTYP_SEP)) 6145 return false; 6146 6147 cfgp1.phy_number = phy_index; 6148 if (leapraid_op_config_page(adapter, &phy_p0, cfgp1, cfgp2, 6149 GET_PHY_PG0)) 6150 return false; 6151 6152 if (!(le32_to_cpu(phy_p0.phy_info) & LEAPRAID_SAS_PHYINFO_VPHY)) 6153 return false; 6154 6155 return true; 6156 } 6157 6158 static void leapraid_update_vphy_binding(struct leapraid_adapter *adapter, 6159 struct leapraid_card_port *card_port, 6160 struct leapraid_vphy *vphy, 6161 int phy_index, u8 may_new_port_id, 6162 u64 attached_sas_addr) 6163 { 6164 struct leapraid_card_port *may_new_card_port; 6165 struct leapraid_sas_dev *sas_dev; 6166 6167 may_new_card_port = leapraid_get_port_by_id(adapter, 6168 may_new_port_id, 6169 true); 6170 if (!may_new_card_port) { 6171 may_new_card_port = kzalloc_obj(*may_new_card_port); 6172 if (!may_new_card_port) 6173 return; 6174 may_new_card_port->port_id = may_new_port_id; 6175 dev_err(&adapter->pdev->dev, 6176 "%s: New card port %p added, port=%d\n", 6177 __func__, may_new_card_port, may_new_port_id); 6178 list_add_tail(&may_new_card_port->list, 6179 &adapter->dev_topo.card_port_list); 6180 } 6181 6182 if (card_port != may_new_card_port) { 6183 if (!may_new_card_port->vphys_mask) 6184 INIT_LIST_HEAD(&may_new_card_port->vphys_list); 6185 may_new_card_port->vphys_mask |= BIT(phy_index); 6186 card_port->vphys_mask &= ~BIT(phy_index); 6187 list_move(&vphy->list, &may_new_card_port->vphys_list); 6188 6189 sas_dev = leapraid_get_sas_dev_by_addr(adapter, 6190 attached_sas_addr, 6191 card_port); 6192 if (sas_dev) { 6193 sas_dev->card_port = may_new_card_port; 6194 leapraid_sdev_put(sas_dev); 6195 } 6196 } 6197 6198 if (may_new_card_port->flg & LEAPRAID_CARD_PORT_FLG_DIRTY) { 6199 may_new_card_port->sas_address = 0; 6200 may_new_card_port->phy_mask = 0; 6201 may_new_card_port->flg &= ~LEAPRAID_CARD_PORT_FLG_DIRTY; 6202 } 6203 vphy->flg &= ~LEAPRAID_VPHY_FLG_DIRTY; 6204 } 6205 6206 static void leapraid_update_vphys_after_reset(struct leapraid_adapter *adapter) 6207 { 6208 union cfg_param_1 cfgp1 = {0}; 6209 union cfg_param_2 cfgp2 = {0}; 6210 struct leapraid_sas_io_unit_p0 *sas_iounit_p0; 6211 struct leapraid_card_port *card_port, *card_port_next; 6212 struct leapraid_vphy *vphy, *vphy_next; 6213 u64 attached_sas_addr; 6214 u16 sz; 6215 u16 attached_hdl; 6216 bool found = false; 6217 u8 port_id; 6218 int i; 6219 6220 list_for_each_entry_safe(card_port, card_port_next, 6221 &adapter->dev_topo.card_port_list, list) { 6222 if (!card_port->vphys_mask) 6223 continue; 6224 6225 list_for_each_entry_safe(vphy, vphy_next, 6226 &card_port->vphys_list, list) 6227 vphy->flg |= LEAPRAID_VPHY_FLG_DIRTY; 6228 } 6229 6230 sz = offsetof(struct leapraid_sas_io_unit_p0, phy_info) + 6231 (adapter->dev_topo.card.phys_num * 6232 sizeof(struct leapraid_sas_io_unit0_phy_info)); 6233 sas_iounit_p0 = kzalloc(sz, GFP_KERNEL); 6234 if (!sas_iounit_p0) 6235 return; 6236 6237 cfgp1.size = sz; 6238 if (leapraid_op_config_page(adapter, sas_iounit_p0, cfgp1, cfgp2, 6239 GET_SAS_IOUNIT_PG0) != 0) 6240 goto out_free; 6241 6242 for (i = 0; i < adapter->dev_topo.card.phys_num; i++) { 6243 if (!leapraid_is_valid_vphy(adapter, sas_iounit_p0, i)) 6244 continue; 6245 6246 attached_hdl = 6247 le16_to_cpu(sas_iounit_p0->phy_info[i] 6248 .attached_dev_hdl); 6249 if (leapraid_get_sas_address(adapter, attached_hdl, 6250 &attached_sas_addr) != 0) 6251 continue; 6252 6253 found = false; 6254 card_port = NULL; 6255 card_port_next = NULL; 6256 list_for_each_entry_safe(card_port, card_port_next, 6257 &adapter->dev_topo.card_port_list, 6258 list) { 6259 if (!card_port->vphys_mask) 6260 continue; 6261 6262 list_for_each_entry_safe(vphy, vphy_next, 6263 &card_port->vphys_list, 6264 list) { 6265 if (!(vphy->flg & LEAPRAID_VPHY_FLG_DIRTY)) 6266 continue; 6267 6268 if (vphy->sas_address != attached_sas_addr) 6269 continue; 6270 6271 if (!(vphy->phy_mask & BIT(i))) 6272 vphy->phy_mask = BIT(i); 6273 6274 port_id = sas_iounit_p0->phy_info[i].port; 6275 6276 leapraid_update_vphy_binding(adapter, 6277 card_port, 6278 vphy, 6279 i, 6280 port_id, 6281 attached_sas_addr); 6282 6283 found = true; 6284 break; 6285 } 6286 if (found) 6287 break; 6288 } 6289 } 6290 out_free: 6291 kfree(sas_iounit_p0); 6292 } 6293 6294 static void leapraid_mark_all_dev_deleted(struct leapraid_adapter *adapter) 6295 { 6296 struct leapraid_sdev_priv *sdev_priv; 6297 struct scsi_device *sdev; 6298 6299 shost_for_each_device(sdev, adapter->shost) { 6300 sdev_priv = sdev->hostdata; 6301 if (sdev_priv && sdev_priv->starget_priv) 6302 sdev_priv->starget_priv->deleted = 1; 6303 } 6304 } 6305 6306 static void leapraid_free_enc_list(struct leapraid_adapter *adapter) 6307 { 6308 struct leapraid_enc_node *enc_dev, *enc_dev_next; 6309 LIST_HEAD(free_list); 6310 unsigned long flags; 6311 6312 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags); 6313 list_splice_init(&adapter->dev_topo.enc_list, &free_list); 6314 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags); 6315 6316 list_for_each_entry_safe(enc_dev, enc_dev_next, &free_list, list) { 6317 list_del(&enc_dev->list); 6318 kfree(enc_dev); 6319 } 6320 } 6321 6322 static void leapraid_rebuild_enc_list_after_reset( 6323 struct leapraid_adapter *adapter) 6324 { 6325 union cfg_param_1 cfgp1 = {0}; 6326 union cfg_param_2 cfgp2 = {0}; 6327 struct leapraid_enc_node *enc_node; 6328 u16 enc_hdl; 6329 unsigned long flags; 6330 int rc; 6331 6332 leapraid_free_enc_list(adapter); 6333 6334 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP; 6335 for (enc_hdl = 0xFFFF; ; enc_hdl = le16_to_cpu(enc_node->pg0.enc_hdl)) { 6336 enc_node = kzalloc_obj(*enc_node); 6337 if (!enc_node) 6338 return; 6339 6340 cfgp2.handle = enc_hdl; 6341 rc = leapraid_op_config_page(adapter, &enc_node->pg0, cfgp1, 6342 cfgp2, GET_SAS_ENCLOSURE_PG0); 6343 if (rc) { 6344 kfree(enc_node); 6345 return; 6346 } 6347 6348 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags); 6349 list_add_tail(&enc_node->list, &adapter->dev_topo.enc_list); 6350 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags); 6351 } 6352 } 6353 6354 static void leapraid_mark_resp_sas_dev(struct leapraid_adapter *adapter, 6355 struct leapraid_sas_dev_p0 *sas_dev_p0) 6356 { 6357 struct leapraid_starget_priv *starget_priv; 6358 struct leapraid_enc_node *enc_node = NULL; 6359 struct leapraid_card_port *card_port; 6360 struct leapraid_sas_dev *sas_dev; 6361 struct scsi_target *starget; 6362 unsigned long flags; 6363 unsigned long enc_flags = 0; 6364 u16 enc_hdl; 6365 u64 enc_lid = 0; 6366 6367 card_port = leapraid_get_port_by_id(adapter, sas_dev_p0->physical_port, 6368 false); 6369 enc_hdl = le16_to_cpu(sas_dev_p0->enc_hdl); 6370 if (enc_hdl) { 6371 spin_lock_irqsave(&adapter->dev_topo.enc_lock, enc_flags); 6372 enc_node = leapraid_enc_find_by_hdl(adapter, enc_hdl); 6373 if (enc_node) 6374 enc_lid = le64_to_cpu(enc_node->pg0.enc_lid); 6375 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, enc_flags); 6376 if (!enc_node) 6377 dev_info(&adapter->pdev->dev, 6378 "enc hdl 0x%04x has no matched enc dev\n", 6379 enc_hdl); 6380 } 6381 6382 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 6383 list_for_each_entry(sas_dev, &adapter->dev_topo.sas_dev_list, list) { 6384 if (sas_dev->sas_addr != le64_to_cpu(sas_dev_p0->sas_address) || 6385 sas_dev->slot != le16_to_cpu(sas_dev_p0->slot) || 6386 sas_dev->card_port != card_port) 6387 continue; 6388 6389 sas_dev->resp = 1; 6390 starget = sas_dev->starget; 6391 if (starget && starget->hostdata) { 6392 starget_priv = starget->hostdata; 6393 starget_priv->tm_busy = 0; 6394 starget_priv->deleted = 0; 6395 } else { 6396 starget_priv = NULL; 6397 } 6398 6399 if (starget) { 6400 starget_printk( 6401 KERN_INFO, starget, 6402 "dev: hdl=0x%04x saddr=0x%016llx port_id=%d\n", 6403 sas_dev->hdl, 6404 (unsigned long long)sas_dev->sas_addr, 6405 sas_dev->card_port->port_id); 6406 if (sas_dev->enc_hdl != 0) 6407 starget_printk( 6408 KERN_INFO, 6409 starget, 6410 "enc info: enc_lid=0x%016llx slot=%d\n", 6411 (unsigned long long)sas_dev->enc_lid, 6412 sas_dev->slot); 6413 } 6414 6415 if (le16_to_cpu(sas_dev_p0->flg) & 6416 LEAPRAID_SAS_DEV_P0_FLG_ENC_LEVEL_VALID) { 6417 sas_dev->enc_level = sas_dev_p0->enc_level; 6418 memcpy(sas_dev->connector_name, 6419 sas_dev_p0->connector_name, 6420 LEAPRAID_SAS_DEV_P0_CON_NAME_LEN); 6421 sas_dev->connector_name[ 6422 LEAPRAID_SAS_DEV_P0_CON_NAME_LEN] = '\0'; 6423 } else { 6424 sas_dev->enc_level = 0; 6425 sas_dev->connector_name[0] = '\0'; 6426 } 6427 6428 sas_dev->enc_hdl = enc_hdl; 6429 sas_dev->enc_lid = enc_lid; 6430 6431 if (sas_dev->hdl == le16_to_cpu(sas_dev_p0->dev_hdl)) 6432 goto unlock; 6433 6434 dev_info(&adapter->pdev->dev, 6435 "hdl changed: 0x%04x -> 0x%04x\n", 6436 sas_dev->hdl, sas_dev_p0->dev_hdl); 6437 sas_dev->hdl = le16_to_cpu(sas_dev_p0->dev_hdl); 6438 if (starget_priv) 6439 starget_priv->hdl = le16_to_cpu(sas_dev_p0->dev_hdl); 6440 6441 goto unlock; 6442 } 6443 unlock: 6444 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 6445 } 6446 6447 static void leapraid_search_resp_sas_dev(struct leapraid_adapter *adapter) 6448 { 6449 union cfg_param_1 cfgp1 = {0}; 6450 union cfg_param_2 cfgp2 = {0}; 6451 struct leapraid_sas_dev_p0 sas_dev_p0; 6452 u32 device_info; 6453 6454 if (list_empty(&adapter->dev_topo.sas_dev_list)) 6455 return; 6456 6457 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP; 6458 for (cfgp2.handle = 0xFFFF; 6459 !leapraid_op_config_page(adapter, &sas_dev_p0, 6460 cfgp1, cfgp2, GET_SAS_DEVICE_PG0); 6461 cfgp2.handle = le16_to_cpu(sas_dev_p0.dev_hdl)) { 6462 device_info = le32_to_cpu(sas_dev_p0.dev_info); 6463 if (!(leapraid_is_end_dev(device_info))) 6464 continue; 6465 6466 leapraid_mark_resp_sas_dev(adapter, &sas_dev_p0); 6467 } 6468 } 6469 6470 static void leapraid_mark_resp_raid_volume(struct leapraid_adapter *adapter, 6471 u64 wwid, u16 hdl) 6472 { 6473 struct leapraid_raid_volume *raid_volume; 6474 struct leapraid_starget_priv *starget_priv = NULL; 6475 struct scsi_target *starget; 6476 unsigned long flags; 6477 u64 volume_wwid; 6478 u16 old_hdl; 6479 6480 raid_volume = leapraid_raid_volume_find_by_wwid(adapter, wwid); 6481 if (!raid_volume) 6482 return; 6483 6484 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags); 6485 if (!raid_volume->starget) { 6486 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, 6487 flags); 6488 leapraid_raid_volume_put(raid_volume); 6489 return; 6490 } 6491 6492 starget = raid_volume->starget; 6493 if (starget->hostdata) { 6494 starget_priv = starget->hostdata; 6495 starget_priv->deleted = 0; 6496 } 6497 6498 raid_volume->resp = 1; 6499 volume_wwid = raid_volume->wwid; 6500 old_hdl = raid_volume->hdl; 6501 if (old_hdl != hdl) { 6502 raid_volume->hdl = hdl; 6503 if (starget_priv) 6504 starget_priv->hdl = hdl; 6505 } 6506 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags); 6507 6508 starget_printk(KERN_INFO, starget, 6509 "raid volume: hdl=0x%04x, wwid=0x%016llx\n", 6510 hdl, (unsigned long long)volume_wwid); 6511 if (old_hdl != hdl) 6512 dev_info(&adapter->pdev->dev, 6513 "hdl changed: 0x%04x -> 0x%04x\n", 6514 old_hdl, hdl); 6515 6516 leapraid_raid_volume_put(raid_volume); 6517 } 6518 6519 static void leapraid_search_resp_raid_volume(struct leapraid_adapter *adapter) 6520 { 6521 union cfg_param_1 cfgp1 = {0}; 6522 union cfg_param_1 cfgp1_extra = {0}; 6523 union cfg_param_2 cfgp2 = {0}; 6524 union cfg_param_2 cfgp2_extra = {0}; 6525 struct leapraid_raidvol_p1 raidvol_p1; 6526 struct leapraid_raidvol_p0 raidvol_p0; 6527 struct leapraid_raidpd_p0 raidpd_p0; 6528 unsigned long flags; 6529 u16 hdl; 6530 u8 phys_disk_num; 6531 bool is_empty; 6532 6533 if (!adapter->adapter_attr.raid_support) 6534 return; 6535 6536 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags); 6537 is_empty = list_empty(&adapter->dev_topo.raid_volume_list); 6538 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags); 6539 if (is_empty) 6540 return; 6541 6542 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP; 6543 for (hdl = 0xFFFF, cfgp2.handle = hdl; 6544 !leapraid_op_config_page(adapter, &raidvol_p1, cfgp1, cfgp2, 6545 GET_RAID_VOLUME_PG1); 6546 cfgp2.handle = hdl) { 6547 hdl = le16_to_cpu(raidvol_p1.dev_hdl); 6548 cfgp1_extra.size = sizeof(struct leapraid_raidvol_p0); 6549 cfgp2_extra.handle = hdl; 6550 if (leapraid_op_config_page(adapter, &raidvol_p0, cfgp1_extra, 6551 cfgp2_extra, GET_RAID_VOLUME_PG0)) 6552 continue; 6553 6554 if (raidvol_p0.volume_state == LEAPRAID_VOL_STATE_OPTIMAL || 6555 raidvol_p0.volume_state == LEAPRAID_VOL_STATE_ONLINE || 6556 raidvol_p0.volume_state == LEAPRAID_VOL_STATE_DEGRADED) 6557 leapraid_mark_resp_raid_volume( 6558 adapter, 6559 le64_to_cpu(raidvol_p1.wwid), 6560 hdl); 6561 } 6562 6563 memset(adapter->dev_topo.pd_hdls, 0, adapter->dev_topo.pd_hdls_sz); 6564 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP; 6565 for (phys_disk_num = 0xFF, cfgp2.form_specific = phys_disk_num; 6566 !leapraid_op_config_page(adapter, &raidpd_p0, cfgp1, cfgp2, 6567 GET_PHY_DISK_PG0); 6568 cfgp2.form_specific = phys_disk_num) { 6569 phys_disk_num = raidpd_p0.phys_disk_num; 6570 hdl = le16_to_cpu(raidpd_p0.dev_hdl); 6571 if (!hdl || 6572 hdl > adapter->adapter_attr.features.max_dev_handle) 6573 dev_warn(&adapter->pdev->dev, 6574 "%s: Invalid device handle\n", __func__); 6575 else 6576 set_bit(hdl, adapter->dev_topo.pd_hdls); 6577 } 6578 } 6579 6580 static void leapraid_mark_resp_exp(struct leapraid_adapter *adapter, 6581 struct leapraid_exp_p0 *exp_pg0) 6582 { 6583 struct leapraid_enc_node *enc_node = NULL; 6584 struct leapraid_topo_node *topo_node_exp; 6585 u16 enc_hdl = le16_to_cpu(exp_pg0->enc_hdl); 6586 u64 sas_address = le64_to_cpu(exp_pg0->sas_address); 6587 u16 hdl = le16_to_cpu(exp_pg0->dev_hdl); 6588 u8 port_id = exp_pg0->physical_port; 6589 struct leapraid_card_port *card_port = leapraid_get_port_by_id(adapter, 6590 port_id, 6591 false); 6592 unsigned long flags; 6593 unsigned long enc_flags = 0; 6594 u64 enc_lid = 0; 6595 int i; 6596 6597 if (enc_hdl) { 6598 spin_lock_irqsave(&adapter->dev_topo.enc_lock, enc_flags); 6599 enc_node = leapraid_enc_find_by_hdl(adapter, enc_hdl); 6600 if (enc_node) 6601 enc_lid = le64_to_cpu(enc_node->pg0.enc_lid); 6602 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, enc_flags); 6603 } 6604 6605 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags); 6606 list_for_each_entry(topo_node_exp, &adapter->dev_topo.exp_list, list) { 6607 if (topo_node_exp->sas_address != sas_address || 6608 topo_node_exp->card_port != card_port) 6609 continue; 6610 6611 topo_node_exp->resp = 1; 6612 topo_node_exp->enc_hdl = enc_hdl; 6613 topo_node_exp->enc_lid = enc_lid; 6614 if (topo_node_exp->hdl == hdl) 6615 goto unlock; 6616 6617 dev_info(&adapter->pdev->dev, 6618 "hdl changed: 0x%04x -> 0x%04x\n", 6619 topo_node_exp->hdl, hdl); 6620 topo_node_exp->hdl = hdl; 6621 for (i = 0; i < topo_node_exp->phys_num; i++) 6622 topo_node_exp->card_phy[i].hdl = hdl; 6623 goto unlock; 6624 } 6625 unlock: 6626 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags); 6627 } 6628 6629 static void leapraid_search_resp_exp(struct leapraid_adapter *adapter) 6630 { 6631 union cfg_param_1 cfgp1 = {0}; 6632 union cfg_param_2 cfgp2 = {0}; 6633 struct leapraid_exp_p0 exp_p0; 6634 u64 sas_address; 6635 u16 hdl; 6636 u8 port; 6637 6638 if (list_empty(&adapter->dev_topo.exp_list)) 6639 return; 6640 6641 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP; 6642 for (hdl = 0xFFFF, cfgp2.handle = hdl; 6643 !leapraid_op_config_page(adapter, &exp_p0, cfgp1, cfgp2, 6644 GET_SAS_EXPANDER_PG0); 6645 cfgp2.handle = hdl) { 6646 hdl = le16_to_cpu(exp_p0.dev_hdl); 6647 sas_address = le64_to_cpu(exp_p0.sas_address); 6648 port = exp_p0.physical_port; 6649 6650 dev_dbg(&adapter->pdev->dev, 6651 "exp detected: hdl=0x%04x, sas=0x%016llx, port=%u", 6652 hdl, (unsigned long long)sas_address, 6653 adapter->adapter_attr.enable_mp ? port : 6654 LEAPRAID_DISABLE_MP_PORT_ID); 6655 leapraid_mark_resp_exp(adapter, &exp_p0); 6656 } 6657 } 6658 6659 void leapraid_wait_cmds_done(struct leapraid_adapter *adapter) 6660 { 6661 struct leapraid_io_req_tracker *io_req_tracker; 6662 unsigned long flags; 6663 u16 i; 6664 6665 adapter->reset_desc.pending_io_cnt = 0; 6666 if (!leapraid_pci_active(adapter)) { 6667 dev_err(&adapter->pdev->dev, 6668 "%s %s: PCI error, device reset or unplugged!\n", 6669 adapter->adapter_attr.name, __func__); 6670 return; 6671 } 6672 6673 if (leapraid_get_adapter_state(adapter) != LEAPRAID_DB_OPERATIONAL) 6674 return; 6675 6676 spin_lock_irqsave(&adapter->dynamic_task_desc.task_lock, flags); 6677 for (i = 1; i <= adapter->shost->can_queue; i++) { 6678 io_req_tracker = leapraid_get_io_tracker_from_taskid(adapter, 6679 i); 6680 if (io_req_tracker && io_req_tracker->taskid != 0 && 6681 io_req_tracker->scmd) 6682 adapter->reset_desc.pending_io_cnt++; 6683 } 6684 spin_unlock_irqrestore(&adapter->dynamic_task_desc.task_lock, flags); 6685 6686 if (!adapter->reset_desc.pending_io_cnt) 6687 return; 6688 6689 wait_event_timeout(adapter->reset_desc.reset_wait_queue, 6690 adapter->reset_desc.pending_io_cnt == 0, 6691 LEAPRAID_IO_CMD_TIMEOUT * HZ); 6692 } 6693 6694 int leapraid_hard_reset_handler(struct leapraid_adapter *adapter, 6695 enum reset_type type) 6696 { 6697 unsigned long flags; 6698 bool wake = false; 6699 int rc; 6700 6701 mutex_lock(&adapter->reset_desc.adapter_reset_mutex); 6702 6703 if (adapter->access_ctrl.shost_recover_async) { 6704 rc = adapter->reset_desc.adapter_reset_results; 6705 dev_info(&adapter->pdev->dev, 6706 "Skip nested hard reset, async evt running, rc=%d\n", 6707 rc); 6708 mutex_unlock(&adapter->reset_desc.adapter_reset_mutex); 6709 return rc; 6710 } 6711 6712 if (!leapraid_pci_active(adapter)) { 6713 if (leapraid_pci_removed(adapter)) { 6714 dev_info(&adapter->pdev->dev, 6715 "pci_dev removed, pause poll, clean cmds\n"); 6716 leapraid_mq_polling_pause(adapter); 6717 leapraid_clean_active_scsi_cmds(adapter); 6718 leapraid_mq_polling_resume(adapter); 6719 } 6720 dev_err(&adapter->pdev->dev, "PCIe unavailable!\n"); 6721 mutex_unlock(&adapter->reset_desc.adapter_reset_mutex); 6722 return -ENXIO; 6723 } 6724 6725 dev_info(&adapter->pdev->dev, "Starting hard reset\n"); 6726 6727 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags); 6728 adapter->access_ctrl.shost_recovering = 1; 6729 adapter->access_ctrl.shost_recover_async = 1; 6730 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags); 6731 6732 leapraid_wait_cmds_done(adapter); 6733 leapraid_mask_int(adapter); 6734 leapraid_mq_polling_pause(adapter); 6735 rc = leapraid_make_adapter_ready(adapter, type); 6736 if (rc) { 6737 dev_err(&adapter->pdev->dev, 6738 "Failed to make adapter ready, rc=%d\n", rc); 6739 goto out_cleanup; 6740 } 6741 6742 rc = leapraid_fw_log_init(adapter); 6743 if (rc) { 6744 dev_err(&adapter->pdev->dev, "Firmware log init failed\n"); 6745 goto out_cleanup; 6746 } 6747 6748 leapraid_clean_active_cmds(adapter); 6749 if (adapter->scan_dev_desc.driver_loading && 6750 adapter->scan_dev_desc.scan_dev_failed) { 6751 dev_err(&adapter->pdev->dev, 6752 "Previous device scan failed or driver loading\n"); 6753 adapter->access_ctrl.host_removing = 1; 6754 rc = -EFAULT; 6755 goto out_cleanup; 6756 } 6757 6758 rc = leapraid_make_adapter_available(adapter); 6759 if (!rc) { 6760 dev_info(&adapter->pdev->dev, 6761 "Adapter is now available, rebuilding topology\n"); 6762 if (adapter->adapter_attr.enable_mp) { 6763 leapraid_update_card_port_after_reset(adapter); 6764 leapraid_update_vphys_after_reset(adapter); 6765 } 6766 leapraid_mark_all_dev_deleted(adapter); 6767 leapraid_rebuild_enc_list_after_reset(adapter); 6768 leapraid_search_resp_sas_dev(adapter); 6769 leapraid_search_resp_raid_volume(adapter); 6770 leapraid_search_resp_exp(adapter); 6771 leapraid_hardreset_barrier(adapter); 6772 } 6773 out_cleanup: 6774 if (rc) 6775 dev_err(&adapter->pdev->dev, "Hard reset failed\n"); 6776 6777 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags); 6778 adapter->reset_desc.adapter_reset_results = rc; 6779 adapter->access_ctrl.shost_recovering = 0; 6780 wake_up(&adapter->access_ctrl.recovery_waitq); 6781 if (rc) { 6782 adapter->access_ctrl.shost_recover_async = 0; 6783 wake = true; 6784 } 6785 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags); 6786 if (wake) 6787 wake_up(&adapter->access_ctrl.shost_recover_wq); 6788 6789 adapter->reset_desc.reset_cnt++; 6790 mutex_unlock(&adapter->reset_desc.adapter_reset_mutex); 6791 6792 if (rc) 6793 leapraid_clean_active_scsi_cmds(adapter); 6794 leapraid_mq_polling_resume(adapter); 6795 6796 return rc; 6797 } 6798 6799 static int leapraid_get_adapter_features(struct leapraid_adapter *adapter) 6800 { 6801 struct leapraid_adapter_features_req leap_mpi_req; 6802 struct leapraid_adapter_features_rep leap_mpi_rep; 6803 u8 fw_major, fw_minor, fw_build, fw_release; 6804 u32 req_sz; 6805 u32 rep_sz; 6806 u32 db; 6807 int r; 6808 6809 db = leapraid_readl(&adapter->iomem_base->db); 6810 if (db & LEAPRAID_DB_USED || 6811 (db & LEAPRAID_DB_MASK) == LEAPRAID_DB_FAULT) { 6812 dev_err(&adapter->pdev->dev, 6813 "%s: Doorbell used or fault\n", __func__); 6814 return -EFAULT; 6815 } 6816 6817 if ((db & LEAPRAID_DB_MASK) != LEAPRAID_DB_READY && 6818 (db & LEAPRAID_DB_MASK) != LEAPRAID_DB_OPERATIONAL && 6819 !leapraid_wait_adapter_ready(adapter)) { 6820 dev_err(&adapter->pdev->dev, 6821 "%s: adapter not ready\n", __func__); 6822 return -EFAULT; 6823 } 6824 6825 req_sz = sizeof(struct leapraid_adapter_features_req); 6826 rep_sz = sizeof(struct leapraid_adapter_features_rep); 6827 memset(&leap_mpi_req, 0, req_sz); 6828 memset(&leap_mpi_rep, 0, rep_sz); 6829 leap_mpi_req.func = LEAPRAID_FUNC_GET_ADAPTER_FEATURES; 6830 r = leapraid_handshake_func(adapter, 6831 req_sz, 6832 (u32 *)&leap_mpi_req, 6833 rep_sz, 6834 (u16 *)&leap_mpi_rep); 6835 if (r) { 6836 dev_err(&adapter->pdev->dev, 6837 "%s %s: Handshake failed, r=%d\n", 6838 adapter->adapter_attr.name, __func__, r); 6839 return r; 6840 } 6841 6842 memset(&adapter->adapter_attr.features, 0, 6843 sizeof(struct leapraid_adapter_features)); 6844 adapter->adapter_attr.features.req_slot = 6845 le16_to_cpu(leap_mpi_rep.req_slot); 6846 adapter->adapter_attr.features.hp_slot = 6847 le16_to_cpu(leap_mpi_rep.hp_slot); 6848 adapter->adapter_attr.features.adapter_caps = 6849 le32_to_cpu(leap_mpi_rep.adapter_caps); 6850 adapter->adapter_attr.features.max_msix_vectors = 6851 leap_mpi_rep.max_msix_vectors; 6852 adapter->adapter_attr.features.max_volumes = 6853 leap_mpi_rep.max_volumes; 6854 if (!adapter->adapter_attr.features.max_volumes) 6855 adapter->adapter_attr.features.max_volumes = 6856 LEAPRAID_MAX_VOLUMES_DEFAULT; 6857 adapter->adapter_attr.features.max_dev_handle = 6858 le16_to_cpu(leap_mpi_rep.max_dev_hdl); 6859 if (!adapter->adapter_attr.features.max_dev_handle) 6860 adapter->adapter_attr.features.max_dev_handle = 6861 LEAPRAID_MAX_DEV_HANDLE_DEFAULT; 6862 adapter->adapter_attr.features.min_dev_handle = 6863 le16_to_cpu(leap_mpi_rep.min_dev_hdl); 6864 if (adapter->adapter_attr.features.adapter_caps & 6865 LEAPRAID_ADAPTER_FEATURES_CAP_INTEGRATED_RAID) 6866 adapter->adapter_attr.raid_support = 1; 6867 adapter->adapter_attr.wideport_max_queue_depth = 6868 le16_to_cpu(leap_mpi_rep.sas_wide_max_qdepth) ? 6869 le16_to_cpu(leap_mpi_rep.sas_wide_max_qdepth) : 6870 LEAPRAID_SAS_QUEUE_DEPTH; 6871 adapter->adapter_attr.narrowport_max_queue_depth = 6872 le16_to_cpu(leap_mpi_rep.sas_narrow_max_qdepth) ? 6873 le16_to_cpu(leap_mpi_rep.sas_narrow_max_qdepth) : 6874 LEAPRAID_SAS_QUEUE_DEPTH; 6875 adapter->adapter_attr.sata_max_queue_depth = 6876 leap_mpi_rep.sata_max_qdepth ? 6877 leap_mpi_rep.sata_max_qdepth : 6878 LEAPRAID_SATA_QUEUE_DEPTH; 6879 adapter->adapter_attr.raid_volume_max_queue_depth = 6880 LEAPRAID_RAID_QUEUE_DEPTH; 6881 dev_info(&adapter->pdev->dev, 6882 "max: wp qd=%d, np qd=%d, SATA qd=%d, raid qd=%d\n", 6883 adapter->adapter_attr.wideport_max_queue_depth, 6884 adapter->adapter_attr.narrowport_max_queue_depth, 6885 adapter->adapter_attr.sata_max_queue_depth, 6886 adapter->adapter_attr.raid_volume_max_queue_depth); 6887 if (WARN_ON(!(adapter->adapter_attr.features.adapter_caps & 6888 LEAPRAID_ADAPTER_FEATURES_CAP_ATOMIC_REQ))) 6889 return -EFAULT; 6890 adapter->adapter_attr.features.fw_version = 6891 le32_to_cpu(leap_mpi_rep.fw_version); 6892 6893 fw_major = (adapter->adapter_attr.features.fw_version >> 6894 LEAPRAID_VER_MAJOR_SHIFT) & LEAPRAID_VER_MASK; 6895 fw_minor = (adapter->adapter_attr.features.fw_version >> 6896 LEAPRAID_VER_MINOR_SHIFT) & LEAPRAID_VER_MASK; 6897 fw_build = (adapter->adapter_attr.features.fw_version >> 6898 LEAPRAID_VER_BUILD_SHIFT) & LEAPRAID_VER_MASK; 6899 fw_release = 6900 adapter->adapter_attr.features.fw_version & LEAPRAID_VER_MASK; 6901 6902 dev_info(&adapter->pdev->dev, 6903 "Firmware version: %u.%u.%u.%u (0x%08x)\n", 6904 fw_major, fw_minor, fw_build, fw_release, 6905 adapter->adapter_attr.features.fw_version); 6906 6907 adapter->adapter_attr.features.msg_ver = 6908 le16_to_cpu(leap_mpi_rep.msg_ver); 6909 adapter->adapter_attr.features.product_id = 6910 le16_to_cpu(leap_mpi_rep.product_id); 6911 dev_info(&adapter->pdev->dev, 6912 "message version: 0x%x, product id 0x%x\n", 6913 adapter->adapter_attr.features.msg_ver, 6914 adapter->adapter_attr.features.product_id); 6915 6916 if (adapter->adapter_attr.features.msg_ver < 0x1000) { 6917 dev_err(&adapter->pdev->dev, "Device not supported\n"); 6918 return -EFAULT; 6919 } 6920 adapter->shost->max_id = LEAPRAID_INVALID_INITIAL_VALUE; 6921 6922 return 0; 6923 } 6924 6925 static inline void leapraid_disable_pcie(struct leapraid_adapter *adapter) 6926 { 6927 mutex_lock(&adapter->access_ctrl.pci_access_lock); 6928 if (adapter->iomem_base) { 6929 iounmap(adapter->iomem_base); 6930 adapter->iomem_base = NULL; 6931 } 6932 if (pci_is_enabled(adapter->pdev)) { 6933 pci_release_regions(adapter->pdev); 6934 pci_disable_device(adapter->pdev); 6935 } 6936 mutex_unlock(&adapter->access_ctrl.pci_access_lock); 6937 } 6938 6939 static int leapraid_enable_pcie(struct leapraid_adapter *adapter) 6940 { 6941 u64 dma_mask; 6942 int rc; 6943 6944 rc = pci_enable_device(adapter->pdev); 6945 if (rc) { 6946 dev_err(&adapter->pdev->dev, "Failed to enable PCI device\n"); 6947 return rc; 6948 } 6949 6950 rc = pci_request_regions(adapter->pdev, LEAPRAID_DRIVER_NAME); 6951 if (rc) { 6952 dev_err(&adapter->pdev->dev, 6953 "Failed to obtain PCI resources\n"); 6954 return rc; 6955 } 6956 6957 if (sizeof(dma_addr_t) > 4) { 6958 dma_mask = DMA_BIT_MASK(DMA_64_BITS); 6959 adapter->adapter_attr.use_32_dma_mask = 0; 6960 } else { 6961 dma_mask = DMA_BIT_MASK(DMA_32_BITS); 6962 adapter->adapter_attr.use_32_dma_mask = 1; 6963 } 6964 6965 rc = dma_set_mask_and_coherent(&adapter->pdev->dev, dma_mask); 6966 if (rc) { 6967 dev_err(&adapter->pdev->dev, 6968 "Failed to set %lld DMA mask\n", dma_mask); 6969 return rc; 6970 } 6971 adapter->iomem_base = ioremap(pci_resource_start(adapter->pdev, 0), 6972 sizeof(struct leapraid_reg_base)); 6973 if (!adapter->iomem_base) { 6974 dev_err(&adapter->pdev->dev, 6975 "Failed to map memory for controller registers\n"); 6976 return -ENOMEM; 6977 } 6978 6979 pci_set_master(adapter->pdev); 6980 6981 return 0; 6982 } 6983 6984 static void leapraid_cpus_on_irq(struct leapraid_adapter *adapter) 6985 { 6986 struct leapraid_int_rq *int_rq; 6987 unsigned int i, base_group, this_group; 6988 unsigned int cpu, nr_cpus, total_msix, index; 6989 6990 total_msix = adapter->notification_desc.iopoll_qdex; 6991 nr_cpus = num_online_cpus(); 6992 6993 if (!nr_cpus || !total_msix) 6994 return; 6995 base_group = nr_cpus / total_msix; 6996 6997 cpu = cpumask_first(cpu_online_mask); 6998 for (index = 0; index < adapter->notification_desc.iopoll_qdex; 6999 index++) { 7000 int_rq = &adapter->notification_desc.int_rqs[index]; 7001 7002 if (cpu >= adapter->notification_desc.msix_cpu_map_sz) 7003 break; 7004 7005 this_group = base_group + 7006 (index < (nr_cpus % total_msix) ? 1 : 0); 7007 7008 for (i = 0 ; i < this_group ; i++) { 7009 if (cpu >= adapter->notification_desc.msix_cpu_map_sz) 7010 break; 7011 7012 adapter->notification_desc.msix_cpu_map[cpu] = 7013 int_rq->rq.msix_idx; 7014 cpu = cpumask_next(cpu, cpu_online_mask); 7015 } 7016 } 7017 } 7018 7019 static void leapraid_map_msix_to_cpu(struct leapraid_adapter *adapter) 7020 { 7021 struct leapraid_int_rq *int_rq; 7022 const cpumask_t *affinity_mask; 7023 int cpu; 7024 u32 i; 7025 7026 if (!adapter->adapter_attr.rq_cnt) 7027 return; 7028 7029 for (i = 0; i < adapter->notification_desc.iopoll_qdex; i++) { 7030 int_rq = &adapter->notification_desc.int_rqs[i]; 7031 affinity_mask = pci_irq_get_affinity(adapter->pdev, 7032 int_rq->rq.msix_idx); 7033 if (!affinity_mask) { 7034 dev_warn(&adapter->pdev->dev, 7035 "%s: IRQ affinity NULL, msix_idx=%d\n", 7036 __func__, int_rq->rq.msix_idx); 7037 goto out_apply_irq_affinity; 7038 } 7039 7040 for_each_cpu_and(cpu, affinity_mask, cpu_online_mask) { 7041 if (cpu >= adapter->notification_desc.msix_cpu_map_sz) 7042 continue; 7043 7044 adapter->notification_desc.msix_cpu_map[cpu] = 7045 int_rq->rq.msix_idx; 7046 } 7047 } 7048 return; 7049 out_apply_irq_affinity: 7050 leapraid_cpus_on_irq(adapter); 7051 } 7052 7053 static int leapraid_alloc_msix_cpu_map(struct leapraid_adapter *adapter) 7054 { 7055 adapter->notification_desc.msix_cpu_map_sz = nr_cpu_ids; 7056 adapter->notification_desc.msix_cpu_map = 7057 kzalloc(adapter->notification_desc.msix_cpu_map_sz, 7058 GFP_KERNEL); 7059 if (!adapter->notification_desc.msix_cpu_map) 7060 return -ENOMEM; 7061 7062 return 0; 7063 } 7064 7065 static void leapraid_configure_reply_queue_affinity( 7066 struct leapraid_adapter *adapter) 7067 { 7068 if (!adapter || !adapter->notification_desc.msix_enable) 7069 return; 7070 7071 leapraid_map_msix_to_cpu(adapter); 7072 } 7073 7074 static void leapraid_free_irq(struct leapraid_adapter *adapter) 7075 { 7076 struct leapraid_int_rq *int_rq; 7077 unsigned int i; 7078 int irq; 7079 7080 for (i = 0; adapter->notification_desc.int_rqs && 7081 i < adapter->notification_desc.int_rqs_allocated; i++) { 7082 int_rq = &adapter->notification_desc.int_rqs[i]; 7083 if (!int_rq) 7084 continue; 7085 7086 irq = pci_irq_vector(adapter->pdev, int_rq->rq.msix_idx); 7087 irq_set_affinity_hint(irq, NULL); 7088 free_irq(irq, &int_rq->rq); 7089 } 7090 adapter->notification_desc.int_rqs_allocated = 0; 7091 7092 if (adapter->notification_desc.irq_vectors_allocated) { 7093 pci_free_irq_vectors(adapter->pdev); 7094 adapter->notification_desc.irq_vectors_allocated = 0; 7095 } 7096 7097 adapter->notification_desc.msix_enable = 0; 7098 7099 kfree(adapter->notification_desc.blk_mq_poll_rqs); 7100 adapter->notification_desc.blk_mq_poll_rqs = NULL; 7101 7102 kfree(adapter->notification_desc.int_rqs); 7103 adapter->notification_desc.int_rqs = NULL; 7104 7105 kfree(adapter->notification_desc.msix_cpu_map); 7106 adapter->notification_desc.msix_cpu_map = NULL; 7107 adapter->notification_desc.msix_cpu_map_sz = 0; 7108 adapter->notification_desc.iopoll_qdex = 0; 7109 adapter->notification_desc.iopoll_qcnt = 0; 7110 } 7111 7112 static int leapraid_setup_irqs(struct leapraid_adapter *adapter) 7113 { 7114 int irq_mode = adapter->notification_desc.irq_mode; 7115 unsigned int i; 7116 int rc = 0; 7117 7118 if (irq_mode == LEAPRAID_INTERRUPT_MODE_MSIX) { 7119 rc = pci_alloc_irq_vectors_affinity( 7120 adapter->pdev, 7121 adapter->notification_desc.iopoll_qdex, 7122 adapter->notification_desc.iopoll_qdex, 7123 PCI_IRQ_MSIX | PCI_IRQ_AFFINITY, NULL); 7124 if (rc < 0) { 7125 dev_err(&adapter->pdev->dev, 7126 "%d MSI/MSIX vectors allocated failed!\n", 7127 adapter->notification_desc.iopoll_qdex); 7128 return rc; 7129 } 7130 7131 adapter->notification_desc.irq_vectors_allocated = 1; 7132 } 7133 7134 for (i = 0; i < adapter->notification_desc.iopoll_qdex; i++) { 7135 adapter->notification_desc.int_rqs[i].rq.adapter = adapter; 7136 adapter->notification_desc.int_rqs[i].rq.msix_idx = i; 7137 atomic_set(&adapter->notification_desc.int_rqs[i].rq.busy, 0); 7138 if (irq_mode == LEAPRAID_INTERRUPT_MODE_MSIX) 7139 snprintf(adapter->notification_desc.int_rqs[i].rq.name, 7140 LEAPRAID_NAME_LENGTH, "%s%u-MSIx%u", 7141 LEAPRAID_DRIVER_NAME, 7142 adapter->adapter_attr.id, i); 7143 else if (irq_mode == LEAPRAID_INTERRUPT_MODE_MSI) 7144 snprintf(adapter->notification_desc.int_rqs[i].rq.name, 7145 LEAPRAID_NAME_LENGTH, "%s%u-MSI%u", 7146 LEAPRAID_DRIVER_NAME, 7147 adapter->adapter_attr.id, i); 7148 7149 rc = request_irq(pci_irq_vector(adapter->pdev, i), 7150 leapraid_irq_handler, 7151 IRQF_SHARED, 7152 adapter->notification_desc.int_rqs[i].rq.name, 7153 &adapter->notification_desc.int_rqs[i].rq); 7154 if (rc) { 7155 dev_err(&adapter->pdev->dev, 7156 "MSI/MSIx: request_irq %s failed!\n", 7157 adapter->notification_desc.int_rqs[i].rq.name); 7158 return rc; 7159 } 7160 adapter->notification_desc.int_rqs_allocated++; 7161 } 7162 7163 return 0; 7164 } 7165 7166 static int leapraid_setup_legacy_int(struct leapraid_adapter *adapter) 7167 { 7168 int rc; 7169 7170 adapter->notification_desc.int_rqs[0].rq.adapter = adapter; 7171 adapter->notification_desc.int_rqs[0].rq.msix_idx = 0; 7172 atomic_set(&adapter->notification_desc.int_rqs[0].rq.busy, 0); 7173 snprintf(adapter->notification_desc.int_rqs[0].rq.name, 7174 LEAPRAID_NAME_LENGTH, "%s%d-LegacyInt", 7175 LEAPRAID_DRIVER_NAME, adapter->adapter_attr.id); 7176 7177 rc = pci_alloc_irq_vectors_affinity( 7178 adapter->pdev, 7179 adapter->notification_desc.iopoll_qdex, 7180 adapter->notification_desc.iopoll_qdex, 7181 PCI_IRQ_INTX | PCI_IRQ_AFFINITY, 7182 NULL); 7183 if (rc < 0) { 7184 dev_err(&adapter->pdev->dev, 7185 "Legacy irq allocated failed!\n"); 7186 return rc; 7187 } 7188 7189 adapter->notification_desc.irq_vectors_allocated = 1; 7190 adapter->notification_desc.irq_mode = LEAPRAID_INTERRUPT_MODE_LEGACY; 7191 rc = request_irq(pci_irq_vector(adapter->pdev, 0), 7192 leapraid_irq_handler, 7193 IRQF_SHARED, 7194 adapter->notification_desc.int_rqs[0].rq.name, 7195 &adapter->notification_desc.int_rqs[0].rq); 7196 if (rc) { 7197 irq_set_affinity_hint(pci_irq_vector(adapter->pdev, 0), NULL); 7198 pci_free_irq_vectors(adapter->pdev); 7199 adapter->notification_desc.irq_vectors_allocated = 0; 7200 dev_err(&adapter->pdev->dev, 7201 "Legacy Int: request_irq %s failed!\n", 7202 adapter->notification_desc.int_rqs[0].rq.name); 7203 return -EBUSY; 7204 } 7205 adapter->notification_desc.int_rqs_allocated = 1; 7206 return rc; 7207 } 7208 7209 static int leapraid_set_legacy_int(struct leapraid_adapter *adapter) 7210 { 7211 int rc; 7212 7213 rc = leapraid_alloc_msix_cpu_map(adapter); 7214 if (rc) 7215 return rc; 7216 7217 adapter->adapter_attr.rq_cnt = 1; 7218 adapter->notification_desc.iopoll_qdex = 7219 adapter->adapter_attr.rq_cnt; 7220 adapter->notification_desc.iopoll_qcnt = 0; 7221 dev_info(&adapter->pdev->dev, 7222 "Legacy Intr: req queue cnt=%d intr=%d/poll=%d rep queues!\n", 7223 adapter->adapter_attr.rq_cnt, 7224 adapter->notification_desc.iopoll_qdex, 7225 adapter->notification_desc.iopoll_qcnt); 7226 adapter->notification_desc.int_rqs = 7227 kcalloc(adapter->notification_desc.iopoll_qdex, 7228 sizeof(struct leapraid_int_rq), GFP_KERNEL); 7229 if (!adapter->notification_desc.int_rqs) 7230 return -ENOMEM; 7231 7232 return leapraid_setup_legacy_int(adapter); 7233 } 7234 7235 static int leapraid_set_msix(struct leapraid_adapter *adapter) 7236 { 7237 int iopoll_qcnt = 0; 7238 unsigned int i; 7239 int rc, msix_cnt; 7240 7241 msix_cnt = pci_msix_vec_count(adapter->pdev); 7242 if (msix_cnt <= 0 || 7243 adapter->adapter_attr.features.max_msix_vectors == 0) { 7244 dev_info(&adapter->pdev->dev, "MSIX unsupported!\n"); 7245 return -EOPNOTSUPP; 7246 } 7247 7248 msix_cnt = min_t(int, msix_cnt, 7249 adapter->adapter_attr.features.max_msix_vectors); 7250 7251 if (reset_devices) 7252 adapter->adapter_attr.rq_cnt = 1; 7253 else 7254 adapter->adapter_attr.rq_cnt = min_t(int, 7255 num_online_cpus(), 7256 msix_cnt); 7257 7258 if (max_msix_vectors > 0) 7259 adapter->adapter_attr.rq_cnt = min_t( 7260 int, max_msix_vectors, adapter->adapter_attr.rq_cnt); 7261 7262 if (adapter->adapter_attr.rq_cnt <= 1) 7263 adapter->shost->host_tagset = 0; 7264 if (adapter->shost->host_tagset) { 7265 iopoll_qcnt = poll_queues; 7266 if (iopoll_qcnt >= adapter->adapter_attr.rq_cnt) 7267 iopoll_qcnt = 0; 7268 } 7269 if (iopoll_qcnt) { 7270 adapter->notification_desc.blk_mq_poll_rqs = 7271 kcalloc(iopoll_qcnt, 7272 sizeof(struct leapraid_blk_mq_poll_rq), 7273 GFP_KERNEL); 7274 if (!adapter->notification_desc.blk_mq_poll_rqs) 7275 return -ENOMEM; 7276 adapter->adapter_attr.rq_cnt = 7277 min(adapter->adapter_attr.rq_cnt + iopoll_qcnt, 7278 msix_cnt); 7279 } 7280 7281 adapter->notification_desc.iopoll_qdex = 7282 adapter->adapter_attr.rq_cnt - iopoll_qcnt; 7283 7284 adapter->notification_desc.iopoll_qcnt = iopoll_qcnt; 7285 dev_info(&adapter->pdev->dev, 7286 "MSIx: req queue cnt=%d, intr=%d/poll=%d rep queues!\n", 7287 adapter->adapter_attr.rq_cnt, 7288 adapter->notification_desc.iopoll_qdex, 7289 adapter->notification_desc.iopoll_qcnt); 7290 7291 adapter->notification_desc.int_rqs = 7292 kcalloc(adapter->notification_desc.iopoll_qdex, 7293 sizeof(struct leapraid_int_rq), GFP_KERNEL); 7294 if (!adapter->notification_desc.int_rqs) 7295 return -ENOMEM; 7296 7297 for (i = 0; i < adapter->notification_desc.iopoll_qcnt; i++) { 7298 adapter->notification_desc.blk_mq_poll_rqs[i].rq.adapter = 7299 adapter; 7300 adapter->notification_desc.blk_mq_poll_rqs[i].rq.msix_idx = 7301 i + adapter->notification_desc.iopoll_qdex; 7302 atomic_set( 7303 &adapter->notification_desc.blk_mq_poll_rqs[i].rq.busy, 7304 0); 7305 snprintf(adapter->notification_desc.blk_mq_poll_rqs[i].rq.name, 7306 LEAPRAID_NAME_LENGTH, 7307 "%s%u-MQ-Poll%u", LEAPRAID_DRIVER_NAME, 7308 adapter->adapter_attr.id, i); 7309 atomic_set(&adapter->notification_desc.blk_mq_poll_rqs[i].busy, 7310 0); 7311 atomic_set(&adapter->notification_desc.blk_mq_poll_rqs[i].pause, 7312 0); 7313 } 7314 7315 rc = leapraid_alloc_msix_cpu_map(adapter); 7316 if (rc) 7317 return rc; 7318 7319 adapter->notification_desc.irq_mode = LEAPRAID_INTERRUPT_MODE_MSIX; 7320 adapter->notification_desc.msix_enable = 1; 7321 rc = leapraid_setup_irqs(adapter); 7322 if (rc) { 7323 leapraid_free_irq(adapter); 7324 adapter->notification_desc.msix_enable = 0; 7325 return rc; 7326 } 7327 7328 return 0; 7329 } 7330 7331 static int leapraid_set_msi(struct leapraid_adapter *adapter) 7332 { 7333 int iopoll_qcnt = 0; 7334 unsigned int i; 7335 int rc, msi_cnt; 7336 7337 msi_cnt = pci_msi_vec_count(adapter->pdev); 7338 if (msi_cnt <= 0 || 7339 adapter->adapter_attr.features.max_msix_vectors == 0) { 7340 dev_info(&adapter->pdev->dev, "MSI unsupported!\n"); 7341 return -EOPNOTSUPP; 7342 } 7343 7344 msi_cnt = min_t(int, msi_cnt, 7345 adapter->adapter_attr.features.max_msix_vectors); 7346 7347 if (reset_devices) 7348 adapter->adapter_attr.rq_cnt = 1; 7349 else 7350 adapter->adapter_attr.rq_cnt = min_t(int, 7351 num_online_cpus(), 7352 msi_cnt); 7353 7354 if (max_msix_vectors > 0) 7355 adapter->adapter_attr.rq_cnt = min_t( 7356 int, max_msix_vectors, adapter->adapter_attr.rq_cnt); 7357 7358 if (adapter->adapter_attr.rq_cnt <= 1) 7359 adapter->shost->host_tagset = 0; 7360 if (adapter->shost->host_tagset) { 7361 iopoll_qcnt = poll_queues; 7362 if (iopoll_qcnt >= adapter->adapter_attr.rq_cnt) 7363 iopoll_qcnt = 0; 7364 } 7365 7366 if (iopoll_qcnt) { 7367 adapter->notification_desc.blk_mq_poll_rqs = 7368 kcalloc(iopoll_qcnt, 7369 sizeof(struct leapraid_blk_mq_poll_rq), 7370 GFP_KERNEL); 7371 if (!adapter->notification_desc.blk_mq_poll_rqs) 7372 return -ENOMEM; 7373 7374 adapter->adapter_attr.rq_cnt = 7375 min(adapter->adapter_attr.rq_cnt + iopoll_qcnt, 7376 msi_cnt); 7377 } 7378 7379 adapter->notification_desc.iopoll_qdex = 7380 adapter->adapter_attr.rq_cnt - iopoll_qcnt; 7381 rc = pci_alloc_irq_vectors_affinity( 7382 adapter->pdev, 7383 1, 7384 adapter->notification_desc.iopoll_qdex, 7385 PCI_IRQ_MSI | PCI_IRQ_AFFINITY, NULL); 7386 if (rc < 0) { 7387 dev_err(&adapter->pdev->dev, 7388 "%d MSI vectors allocated failed!\n", 7389 adapter->notification_desc.iopoll_qdex); 7390 leapraid_free_irq(adapter); 7391 return rc; 7392 } 7393 adapter->notification_desc.irq_vectors_allocated = 1; 7394 if (rc != adapter->notification_desc.iopoll_qdex) { 7395 adapter->notification_desc.iopoll_qdex = rc; 7396 adapter->adapter_attr.rq_cnt = 7397 adapter->notification_desc.iopoll_qdex + iopoll_qcnt; 7398 } 7399 adapter->notification_desc.iopoll_qcnt = iopoll_qcnt; 7400 dev_info(&adapter->pdev->dev, 7401 "MSI: req queue cnt=%d, intr=%d/poll=%d rep queues!\n", 7402 adapter->adapter_attr.rq_cnt, 7403 adapter->notification_desc.iopoll_qdex, 7404 adapter->notification_desc.iopoll_qcnt); 7405 7406 adapter->notification_desc.int_rqs = 7407 kcalloc(adapter->notification_desc.iopoll_qdex, 7408 sizeof(struct leapraid_int_rq), 7409 GFP_KERNEL); 7410 if (!adapter->notification_desc.int_rqs) 7411 return -ENOMEM; 7412 7413 for (i = 0; i < adapter->notification_desc.iopoll_qcnt; i++) { 7414 adapter->notification_desc.blk_mq_poll_rqs[i].rq.adapter = 7415 adapter; 7416 adapter->notification_desc.blk_mq_poll_rqs[i].rq.msix_idx = 7417 i + adapter->notification_desc.iopoll_qdex; 7418 atomic_set( 7419 &adapter->notification_desc.blk_mq_poll_rqs[i].rq.busy, 7420 0); 7421 snprintf(adapter->notification_desc.blk_mq_poll_rqs[i].rq.name, 7422 LEAPRAID_NAME_LENGTH, 7423 "%s%u-MQ-Poll%u", LEAPRAID_DRIVER_NAME, 7424 adapter->adapter_attr.id, i); 7425 atomic_set( 7426 &adapter->notification_desc.blk_mq_poll_rqs[i].busy, 7427 0); 7428 atomic_set( 7429 &adapter->notification_desc.blk_mq_poll_rqs[i].pause, 7430 0); 7431 } 7432 7433 rc = leapraid_alloc_msix_cpu_map(adapter); 7434 if (rc) 7435 return rc; 7436 7437 adapter->notification_desc.irq_mode = LEAPRAID_INTERRUPT_MODE_MSI; 7438 adapter->notification_desc.msix_enable = 1; 7439 rc = leapraid_setup_irqs(adapter); 7440 if (rc) { 7441 leapraid_free_irq(adapter); 7442 adapter->notification_desc.msix_enable = 0; 7443 return rc; 7444 } 7445 7446 return 0; 7447 } 7448 7449 static int leapraid_set_notification_auto(struct leapraid_adapter *adapter) 7450 { 7451 int rc; 7452 7453 rc = leapraid_set_msix(adapter); 7454 if (!rc) 7455 return 0; 7456 7457 leapraid_free_irq(adapter); 7458 dev_info(&adapter->pdev->dev, 7459 "MSI-X setup failed (%d), trying MSI\n", rc); 7460 7461 rc = leapraid_set_msi(adapter); 7462 if (!rc) 7463 return 0; 7464 7465 leapraid_free_irq(adapter); 7466 dev_info(&adapter->pdev->dev, 7467 "MSI setup failed (%d), back to legacy INTx\n", rc); 7468 7469 rc = leapraid_set_legacy_int(adapter); 7470 if (rc) 7471 dev_err(&adapter->pdev->dev, 7472 "%s: Enable legacy irq failed!\n", __func__); 7473 7474 return rc; 7475 } 7476 7477 int leapraid_set_pcie_and_notification(struct leapraid_adapter *adapter) 7478 { 7479 int rc; 7480 7481 rc = leapraid_enable_pcie(adapter); 7482 if (rc) 7483 goto out_fail; 7484 7485 leapraid_mask_int(adapter); 7486 7487 rc = leapraid_make_adapter_ready(adapter, PART_RESET); 7488 if (rc) { 7489 dev_err(&adapter->pdev->dev, "Make adapter ready failure\n"); 7490 goto out_fail; 7491 } 7492 7493 rc = leapraid_get_adapter_features(adapter); 7494 if (rc) { 7495 dev_err(&adapter->pdev->dev, "Get adapter feature failure\n"); 7496 goto out_fail; 7497 } 7498 7499 rc = leapraid_set_notification_auto(adapter); 7500 if (rc) 7501 goto out_fail; 7502 7503 pci_save_state(adapter->pdev); 7504 7505 return 0; 7506 7507 out_fail: 7508 leapraid_free_irq(adapter); 7509 leapraid_disable_pcie(adapter); 7510 return rc; 7511 } 7512 7513 void leapraid_disable_controller(struct leapraid_adapter *adapter) 7514 { 7515 if (!adapter->iomem_base) 7516 return; 7517 7518 leapraid_mask_int(adapter); 7519 7520 adapter->access_ctrl.shost_recovering = 1; 7521 leapraid_make_adapter_ready(adapter, PART_RESET); 7522 adapter->access_ctrl.shost_recovering = 0; 7523 wake_up(&adapter->access_ctrl.recovery_waitq); 7524 7525 leapraid_free_irq(adapter); 7526 leapraid_disable_pcie(adapter); 7527 } 7528 7529 static int leapraid_adapter_unit_reset(struct leapraid_adapter *adapter) 7530 { 7531 int rc = 0; 7532 7533 writel(LEAPRAID_FUNC_ADAPTER_UNIT_RESET << LEAPRAID_DB_FUNC_SHIFT, 7534 &adapter->iomem_base->db); 7535 if (leapraid_db_wait_ack_and_clear_int(adapter)) 7536 rc = -EFAULT; 7537 7538 if (!leapraid_wait_adapter_ready(adapter)) { 7539 dev_err(&adapter->pdev->dev, "unit reset failed\n"); 7540 return -EFAULT; 7541 } 7542 7543 return rc; 7544 } 7545 7546 static int leapraid_make_adapter_ready(struct leapraid_adapter *adapter, 7547 enum reset_type type) 7548 { 7549 u32 db; 7550 int count; 7551 7552 if (!leapraid_pci_active(adapter)) 7553 return 0; 7554 7555 count = 0; 7556 db = leapraid_readl(&adapter->iomem_base->db); 7557 if ((db & LEAPRAID_DB_MASK) == LEAPRAID_DB_RESET) { 7558 while ((db & LEAPRAID_DB_MASK) != LEAPRAID_DB_READY) { 7559 if (count++ == LEAPRAID_DB_RETRY_COUNT_MAX) { 7560 dev_err(&adapter->pdev->dev, 7561 "Wait adapter ready timeout\n"); 7562 return -EFAULT; 7563 } 7564 ssleep(1); 7565 db = leapraid_readl(&adapter->iomem_base->db); 7566 dev_info(&adapter->pdev->dev, 7567 "Wait adapter ready, count=%d, db=0x%x\n", 7568 count, db); 7569 } 7570 } 7571 if ((db & LEAPRAID_DB_MASK) == LEAPRAID_DB_READY) 7572 return 0; 7573 7574 if (db & LEAPRAID_DB_USED) 7575 goto full_reset; 7576 7577 if ((db & LEAPRAID_DB_MASK) == LEAPRAID_DB_FAULT) 7578 goto full_reset; 7579 7580 if (type == FULL_RESET) 7581 goto full_reset; 7582 7583 if ((db & LEAPRAID_DB_MASK) == LEAPRAID_DB_OPERATIONAL && 7584 !leapraid_adapter_unit_reset(adapter)) 7585 return 0; 7586 7587 full_reset: 7588 return leapraid_host_diag_reset(adapter); 7589 } 7590 7591 static void leapraid_fw_log_exit(struct leapraid_adapter *adapter) 7592 { 7593 if (!adapter->fw_log_desc.open_pcie_trace) 7594 return; 7595 7596 if (adapter->fw_log_desc.fw_log_buffer) { 7597 wait_event(adapter->fw_log_desc.mmap_waitq, 7598 !atomic_read(&adapter->fw_log_desc.mmap_refcnt)); 7599 dma_free_coherent(&adapter->pdev->dev, 7600 (LEAPRAID_SYS_LOG_BUF_SIZE + 7601 LEAPRAID_SYS_LOG_BUF_RESERVE), 7602 adapter->fw_log_desc.fw_log_buffer, 7603 adapter->fw_log_desc.fw_log_buffer_dma); 7604 adapter->fw_log_desc.fw_log_buffer = NULL; 7605 } 7606 } 7607 7608 static int leapraid_fw_log_init(struct leapraid_adapter *adapter) 7609 { 7610 struct leapraid_adapter_log_req adapter_log_req; 7611 struct leapraid_adapter_log_rep adapter_log_rep; 7612 u16 adapter_status; 7613 u64 buf_addr; 7614 u32 rc; 7615 7616 if (!adapter->fw_log_desc.open_pcie_trace) 7617 return 0; 7618 7619 if (!adapter->fw_log_desc.fw_log_buffer) { 7620 adapter->fw_log_desc.fw_log_buffer = 7621 dma_alloc_coherent( 7622 &adapter->pdev->dev, 7623 (LEAPRAID_SYS_LOG_BUF_SIZE + 7624 LEAPRAID_SYS_LOG_BUF_RESERVE), 7625 &adapter->fw_log_desc.fw_log_buffer_dma, 7626 GFP_KERNEL); 7627 if (!adapter->fw_log_desc.fw_log_buffer) 7628 return -ENOMEM; 7629 } 7630 7631 memset(&adapter_log_req, 0, sizeof(struct leapraid_adapter_log_req)); 7632 adapter_log_req.func = LEAPRAID_FUNC_LOGBUF_INIT; 7633 buf_addr = adapter->fw_log_desc.fw_log_buffer_dma; 7634 7635 adapter_log_req.mbox.w[0] = 7636 cpu_to_le32((u32)(buf_addr & 0xFFFFFFFF)); 7637 adapter_log_req.mbox.w[1] = 7638 cpu_to_le32((u32)((buf_addr >> 32) & 0xFFFFFFFF)); 7639 adapter_log_req.mbox.w[2] = 7640 cpu_to_le32(LEAPRAID_SYS_LOG_BUF_SIZE); 7641 rc = leapraid_handshake_func(adapter, 7642 sizeof(struct leapraid_adapter_log_req), 7643 (u32 *)&adapter_log_req, 7644 sizeof(struct leapraid_adapter_log_rep), 7645 (u16 *)&adapter_log_rep); 7646 if (rc != 0) { 7647 dev_err(&adapter->pdev->dev, "%s: Handshake failed, rc=%d\n", 7648 __func__, rc); 7649 return rc; 7650 } 7651 7652 adapter_status = le16_to_cpu(adapter_log_rep.adapter_status) & 7653 LEAPRAID_ADAPTER_STATUS_MASK; 7654 if (adapter_status != LEAPRAID_ADAPTER_STATUS_SUCCESS) { 7655 dev_err(&adapter->pdev->dev, "%s: failed!\n", __func__); 7656 rc = -EIO; 7657 } 7658 7659 return rc; 7660 } 7661 7662 static void leapraid_free_host_memory(struct leapraid_adapter *adapter) 7663 { 7664 unsigned int i; 7665 7666 if (adapter->mem_desc.task_desc) { 7667 dma_free_coherent(&adapter->pdev->dev, 7668 adapter->adapter_attr.task_desc_dma_size, 7669 adapter->mem_desc.task_desc, 7670 adapter->mem_desc.task_desc_dma); 7671 adapter->mem_desc.task_desc = NULL; 7672 } 7673 7674 if (adapter->mem_desc.sense_data) { 7675 dma_free_coherent( 7676 &adapter->pdev->dev, 7677 adapter->adapter_attr.io_qd * SCSI_SENSE_BUFFERSIZE, 7678 adapter->mem_desc.sense_data, 7679 adapter->mem_desc.sense_data_dma); 7680 adapter->mem_desc.sense_data = NULL; 7681 } 7682 7683 if (adapter->mem_desc.rep_msg) { 7684 dma_free_coherent( 7685 &adapter->pdev->dev, 7686 adapter->adapter_attr.rep_msg_qd * LEAPRAID_REPLY_SIZE, 7687 adapter->mem_desc.rep_msg, 7688 adapter->mem_desc.rep_msg_dma); 7689 adapter->mem_desc.rep_msg = NULL; 7690 } 7691 7692 if (adapter->mem_desc.rep_msg_addr) { 7693 dma_free_coherent(&adapter->pdev->dev, 7694 adapter->adapter_attr.rep_msg_qd * 7695 LEAPRAID_REP_MSG_ADDR_SIZE, 7696 adapter->mem_desc.rep_msg_addr, 7697 adapter->mem_desc.rep_msg_addr_dma); 7698 adapter->mem_desc.rep_msg_addr = NULL; 7699 } 7700 7701 if (adapter->mem_desc.rep_desc_seg_maint) { 7702 for (i = 0; i < adapter->adapter_attr.rep_desc_q_seg_cnt; 7703 i++) { 7704 if (adapter->mem_desc.rep_desc_seg_maint[i] 7705 .rep_desc_seg) { 7706 dma_free_coherent( 7707 &adapter->pdev->dev, 7708 (adapter->adapter_attr.rep_desc_qd * 7709 LEAPRAID_REP_DESC_ENTRY_SIZE) * 7710 LEAPRAID_REP_DESC_CHUNK_SIZE, 7711 adapter->mem_desc.rep_desc_seg_maint[i] 7712 .rep_desc_seg, 7713 adapter->mem_desc.rep_desc_seg_maint[i] 7714 .rep_desc_seg_dma); 7715 adapter->mem_desc.rep_desc_seg_maint[i] 7716 .rep_desc_seg = NULL; 7717 } 7718 } 7719 7720 if (adapter->mem_desc.rep_desc_q_arr) { 7721 dma_free_coherent( 7722 &adapter->pdev->dev, 7723 adapter->adapter_attr.rq_cnt * 7724 LEAPRAID_REP_RQ_CNT_SIZE, 7725 adapter->mem_desc.rep_desc_q_arr, 7726 adapter->mem_desc.rep_desc_q_arr_dma); 7727 adapter->mem_desc.rep_desc_q_arr = NULL; 7728 } 7729 7730 for (i = 0; i < adapter->adapter_attr.rep_desc_q_seg_cnt; i++) { 7731 struct leapraid_mem_desc *mem_desc = 7732 &adapter->mem_desc; 7733 kfree(adapter->mem_desc.rep_desc_seg_maint[i] 7734 .rep_desc_maint); 7735 mem_desc->rep_desc_seg_maint[i].rep_desc_maint = NULL; 7736 } 7737 kfree(adapter->mem_desc.rep_desc_seg_maint); 7738 adapter->mem_desc.rep_desc_seg_maint = NULL; 7739 } 7740 7741 kfree(adapter->mem_desc.taskid_to_uniq_tag); 7742 adapter->mem_desc.taskid_to_uniq_tag = NULL; 7743 7744 dma_pool_destroy(adapter->mem_desc.sg_chain_pool); 7745 adapter->mem_desc.sg_chain_pool = NULL; 7746 } 7747 7748 static inline bool leapraid_is_in_same_4g_seg(dma_addr_t start, u32 size) 7749 { 7750 return upper_32_bits(start) == upper_32_bits(start + size - 1); 7751 } 7752 7753 int leapraid_internal_init_cmd_priv(struct leapraid_adapter *adapter, 7754 struct leapraid_io_req_tracker *io_tracker) 7755 { 7756 io_tracker->chain = 7757 dma_pool_alloc(adapter->mem_desc.sg_chain_pool, 7758 GFP_KERNEL, 7759 &io_tracker->chain_dma); 7760 7761 if (!io_tracker->chain) 7762 return -ENOMEM; 7763 7764 return 0; 7765 } 7766 7767 void leapraid_internal_exit_cmd_priv(struct leapraid_adapter *adapter, 7768 struct leapraid_io_req_tracker *io_tracker) 7769 { 7770 if (io_tracker && io_tracker->chain) 7771 dma_pool_free(adapter->mem_desc.sg_chain_pool, 7772 io_tracker->chain, 7773 io_tracker->chain_dma); 7774 } 7775 7776 static int leapraid_request_host_memory(struct leapraid_adapter *adapter) 7777 { 7778 struct leapraid_adapter_features *facts = 7779 &adapter->adapter_attr.features; 7780 u16 rep_desc_q_cnt_allocated; 7781 unsigned int i, j; 7782 int rc; 7783 7784 /* Scatter-gather table size. */ 7785 adapter->shost->sg_tablesize = LEAPRAID_SG_DEPTH; 7786 if (reset_devices) 7787 adapter->shost->sg_tablesize = 7788 LEAPRAID_KDUMP_MIN_PHYS_SEGMENTS; 7789 /* High-priority commands queue depth. */ 7790 adapter->dynamic_task_desc.hp_cmd_qd = LEAPRAID_FIXED_HP_CMDS; 7791 /* Internal commands queue depth. */ 7792 adapter->dynamic_task_desc.inter_cmd_qd = LEAPRAID_FIXED_INTER_CMDS; 7793 /* Adapter commands total queue depth. */ 7794 if (reset_devices) 7795 adapter->adapter_attr.adapter_total_qd = 7796 LEAPRAID_DEFAULT_CMD_QD_OFFSET + 7797 adapter->dynamic_task_desc.inter_cmd_qd + 7798 adapter->dynamic_task_desc.hp_cmd_qd; 7799 else 7800 adapter->adapter_attr.adapter_total_qd = facts->req_slot + 7801 adapter->dynamic_task_desc.hp_cmd_qd; 7802 /* Reply message queue depth. */ 7803 adapter->adapter_attr.rep_msg_qd = 7804 adapter->adapter_attr.adapter_total_qd + 7805 LEAPRAID_DEFAULT_CMD_QD_OFFSET; 7806 /* Reply descriptor queue depth. */ 7807 adapter->adapter_attr.rep_desc_qd = 7808 round_up(adapter->adapter_attr.adapter_total_qd + 7809 adapter->adapter_attr.rep_msg_qd + 7810 LEAPRAID_TASKID_OFFSET_CTRL_CMD, 7811 LEAPRAID_REPLY_QD_ALIGNMENT); 7812 /* SCSI command I/O depth. */ 7813 adapter->adapter_attr.io_qd = 7814 adapter->adapter_attr.adapter_total_qd - 7815 adapter->dynamic_task_desc.hp_cmd_qd - 7816 adapter->dynamic_task_desc.inter_cmd_qd; 7817 /* SCSI host can queue. */ 7818 adapter->shost->can_queue = adapter->adapter_attr.io_qd - 7819 LEAPRAID_TASKID_OFFSET_CTRL_CMD; 7820 adapter->driver_cmds.ctl_cmd.taskid = adapter->shost->can_queue + 7821 LEAPRAID_TASKID_OFFSET_CTRL_CMD; 7822 7823 /* Allocate task descriptor. */ 7824 try_again: 7825 adapter->adapter_attr.task_desc_dma_size = 7826 (adapter->adapter_attr.adapter_total_qd + 7827 LEAPRAID_TASKID_OFFSET_CTRL_CMD) * 7828 LEAPRAID_REQUEST_SIZE; 7829 adapter->mem_desc.task_desc = 7830 dma_alloc_coherent(&adapter->pdev->dev, 7831 adapter->adapter_attr.task_desc_dma_size, 7832 &adapter->mem_desc.task_desc_dma, 7833 GFP_KERNEL); 7834 if (!adapter->mem_desc.task_desc) 7835 return -ENOMEM; 7836 7837 /* Allocate chain message pool. */ 7838 adapter->mem_desc.sg_chain_pool_size = 7839 LEAPRAID_DEFAULT_CHAINS_PER_IO * LEAPRAID_CHAIN_SEG_SIZE; 7840 adapter->mem_desc.sg_chain_pool = 7841 dma_pool_create("leapraid chain pool", 7842 &adapter->pdev->dev, 7843 adapter->mem_desc.sg_chain_pool_size, 7844 LEAPRAID_DMA_ALIGN, 0); 7845 if (!adapter->mem_desc.sg_chain_pool) 7846 return -ENOMEM; 7847 7848 /* Allocate I/O tracker to SCSI I/O. */ 7849 adapter->mem_desc.taskid_to_uniq_tag = 7850 kcalloc(adapter->shost->can_queue, sizeof(u16), GFP_KERNEL); 7851 if (!adapter->mem_desc.taskid_to_uniq_tag) 7852 return -ENOMEM; 7853 7854 adapter->dynamic_task_desc.hp_taskid = 7855 adapter->adapter_attr.io_qd + 7856 LEAPRAID_HP_TASKID_OFFSET_CTL_CMD; 7857 /* Allocate static high-priority task ID. */ 7858 adapter->driver_cmds.ctl_cmd.hp_taskid = 7859 adapter->dynamic_task_desc.hp_taskid; 7860 adapter->driver_cmds.tm_cmd.hp_taskid = 7861 adapter->dynamic_task_desc.hp_taskid + 7862 LEAPRAID_HP_TASKID_OFFSET_TM_CMD; 7863 7864 adapter->dynamic_task_desc.inter_taskid = 7865 adapter->dynamic_task_desc.hp_taskid + 7866 adapter->dynamic_task_desc.hp_cmd_qd; 7867 adapter->driver_cmds.scan_dev_cmd.inter_taskid = 7868 adapter->dynamic_task_desc.inter_taskid; 7869 adapter->driver_cmds.cfg_op_cmd.inter_taskid = 7870 adapter->dynamic_task_desc.inter_taskid + 7871 LEAPRAID_TASKID_OFFSET_CFG_OP_CMD; 7872 adapter->driver_cmds.transport_cmd.inter_taskid = 7873 adapter->dynamic_task_desc.inter_taskid + 7874 LEAPRAID_TASKID_OFFSET_TRANSPORT_CMD; 7875 adapter->driver_cmds.enc_cmd.inter_taskid = 7876 adapter->dynamic_task_desc.inter_taskid + 7877 LEAPRAID_TASKID_OFFSET_ENC_CMD; 7878 adapter->driver_cmds.notify_event_cmd.inter_taskid = 7879 adapter->dynamic_task_desc.inter_taskid + 7880 LEAPRAID_TASKID_OFFSET_NOTIFY_EVENT_CMD; 7881 dev_info(&adapter->pdev->dev, "queue depth:\n"); 7882 dev_info(&adapter->pdev->dev, " host->can_queue: %d\n", 7883 adapter->shost->can_queue); 7884 dev_info(&adapter->pdev->dev, " io_qd: %d\n", 7885 adapter->adapter_attr.io_qd); 7886 dev_info(&adapter->pdev->dev, " hpr_cmd_qd: %d\n", 7887 adapter->dynamic_task_desc.hp_cmd_qd); 7888 dev_info(&adapter->pdev->dev, " inter_cmd_qd: %d\n", 7889 adapter->dynamic_task_desc.inter_cmd_qd); 7890 dev_info(&adapter->pdev->dev, " adapter_total_qd: %d\n", 7891 adapter->adapter_attr.adapter_total_qd); 7892 7893 dev_info(&adapter->pdev->dev, "taskid range:\n"); 7894 dev_info(&adapter->pdev->dev, 7895 " adapter->dynamic_task_desc.hp_taskid: %d\n", 7896 adapter->dynamic_task_desc.hp_taskid); 7897 dev_info(&adapter->pdev->dev, 7898 " adapter->dynamic_task_desc.inter_taskid: %d\n", 7899 adapter->dynamic_task_desc.inter_taskid); 7900 7901 /* 7902 * Allocate sense data DMA buffer. 7903 * Constraint: Must reside within the same 4GB segment 7904 * (driver-maintained). 7905 */ 7906 adapter->mem_desc.sense_data = 7907 dma_alloc_coherent( 7908 &adapter->pdev->dev, 7909 adapter->adapter_attr.io_qd * SCSI_SENSE_BUFFERSIZE, 7910 &adapter->mem_desc.sense_data_dma, 7911 GFP_KERNEL); 7912 if (!adapter->mem_desc.sense_data) 7913 return -ENOMEM; 7914 7915 if (!leapraid_is_in_same_4g_seg(adapter->mem_desc.sense_data_dma, 7916 adapter->adapter_attr.io_qd * 7917 SCSI_SENSE_BUFFERSIZE)) { 7918 dev_warn(&adapter->pdev->dev, 7919 "Try 32bit DMA: Sense not in same 4G\n"); 7920 rc = -EAGAIN; 7921 goto out_fail; 7922 } 7923 7924 /* 7925 * Allocate reply frame buffer. 7926 * Constraint: Must reside in the same 4GB segment as the sense DMA. 7927 */ 7928 adapter->mem_desc.rep_msg = 7929 dma_alloc_coherent(&adapter->pdev->dev, 7930 adapter->adapter_attr.rep_msg_qd * 7931 LEAPRAID_REPLY_SIZE, 7932 &adapter->mem_desc.rep_msg_dma, 7933 GFP_KERNEL); 7934 if (!adapter->mem_desc.rep_msg) { 7935 rc = -ENOMEM; 7936 goto out_fail; 7937 } 7938 7939 if (!leapraid_is_in_same_4g_seg(adapter->mem_desc.rep_msg_dma, 7940 adapter->adapter_attr.rep_msg_qd * 7941 LEAPRAID_REPLY_SIZE)) { 7942 dev_warn(&adapter->pdev->dev, 7943 "Use 32 bit DMA due to rep msg is not in same 4g!\n"); 7944 rc = -EAGAIN; 7945 goto out_fail; 7946 } 7947 7948 /* Address of reply frame. */ 7949 adapter->mem_desc.rep_msg_addr = 7950 dma_alloc_coherent(&adapter->pdev->dev, 7951 adapter->adapter_attr.rep_msg_qd * 7952 LEAPRAID_REP_MSG_ADDR_SIZE, 7953 &adapter->mem_desc.rep_msg_addr_dma, 7954 GFP_KERNEL); 7955 if (!adapter->mem_desc.rep_msg_addr) 7956 return -ENOMEM; 7957 adapter->adapter_attr.rep_desc_q_seg_cnt = 7958 DIV_ROUND_UP(adapter->adapter_attr.rq_cnt, 7959 LEAPRAID_REP_DESC_CHUNK_SIZE); 7960 adapter->mem_desc.rep_desc_seg_maint = 7961 kcalloc(adapter->adapter_attr.rep_desc_q_seg_cnt, 7962 sizeof(struct leapraid_rep_desc_seg_maint), 7963 GFP_KERNEL); 7964 if (!adapter->mem_desc.rep_desc_seg_maint) 7965 return -ENOMEM; 7966 7967 rep_desc_q_cnt_allocated = 0; 7968 for (i = 0; i < adapter->adapter_attr.rep_desc_q_seg_cnt; i++) { 7969 adapter->mem_desc.rep_desc_seg_maint[i].rep_desc_maint = 7970 kcalloc(LEAPRAID_REP_DESC_CHUNK_SIZE, 7971 sizeof(struct leapraid_rep_desc_maint), 7972 GFP_KERNEL); 7973 if (!adapter->mem_desc.rep_desc_seg_maint[i].rep_desc_maint) 7974 return -ENOMEM; 7975 7976 adapter->mem_desc.rep_desc_seg_maint[i].rep_desc_seg = 7977 dma_alloc_coherent( 7978 &adapter->pdev->dev, 7979 (adapter->adapter_attr.rep_desc_qd * 7980 LEAPRAID_REP_DESC_ENTRY_SIZE) * 7981 LEAPRAID_REP_DESC_CHUNK_SIZE, 7982 &adapter->mem_desc.rep_desc_seg_maint[i] 7983 .rep_desc_seg_dma, 7984 GFP_KERNEL); 7985 if (!adapter->mem_desc.rep_desc_seg_maint[i].rep_desc_seg) 7986 return -ENOMEM; 7987 7988 for (j = 0; j < LEAPRAID_REP_DESC_CHUNK_SIZE; j++) { 7989 if (rep_desc_q_cnt_allocated >= 7990 adapter->adapter_attr.rq_cnt) 7991 break; 7992 adapter->mem_desc 7993 .rep_desc_seg_maint[i] 7994 .rep_desc_maint[j] 7995 .rep_desc = 7996 (void *)((u8 *)( 7997 adapter->mem_desc 7998 .rep_desc_seg_maint[i] 7999 .rep_desc_seg) + 8000 j * 8001 (adapter->adapter_attr.rep_desc_qd * 8002 LEAPRAID_REP_DESC_ENTRY_SIZE)); 8003 adapter->mem_desc 8004 .rep_desc_seg_maint[i] 8005 .rep_desc_maint[j] 8006 .rep_desc_dma = 8007 adapter->mem_desc 8008 .rep_desc_seg_maint[i] 8009 .rep_desc_seg_dma + 8010 j * 8011 (adapter->adapter_attr.rep_desc_qd * 8012 LEAPRAID_REP_DESC_ENTRY_SIZE); 8013 rep_desc_q_cnt_allocated++; 8014 } 8015 } 8016 8017 if (!reset_devices) { 8018 adapter->mem_desc.rep_desc_q_arr = 8019 dma_alloc_coherent( 8020 &adapter->pdev->dev, 8021 adapter->adapter_attr.rq_cnt * 8022 LEAPRAID_REP_RQ_CNT_SIZE, 8023 &adapter->mem_desc.rep_desc_q_arr_dma, 8024 GFP_KERNEL); 8025 if (!adapter->mem_desc.rep_desc_q_arr) 8026 return -ENOMEM; 8027 } 8028 8029 return 0; 8030 out_fail: 8031 if (rc == -EAGAIN) { 8032 leapraid_free_host_memory(adapter); 8033 adapter->adapter_attr.use_32_dma_mask = 1; 8034 rc = dma_set_mask_and_coherent(&adapter->pdev->dev, 8035 DMA_BIT_MASK(DMA_32_BITS)); 8036 if (rc) { 8037 dev_err(&adapter->pdev->dev, 8038 "Failed to set 32 DMA mask\n"); 8039 return rc; 8040 } 8041 goto try_again; 8042 } 8043 return rc; 8044 } 8045 8046 static int leapraid_alloc_dev_topo_bitmaps(struct leapraid_adapter *adapter) 8047 { 8048 u16 pd_hdls_sz; 8049 8050 pd_hdls_sz = 8051 BITS_TO_LONGS( 8052 adapter->adapter_attr.features.max_dev_handle + 1) * 8053 sizeof(unsigned long); 8054 8055 adapter->dev_topo.pd_hdls_sz = pd_hdls_sz; 8056 adapter->dev_topo.pd_hdls = 8057 kzalloc(adapter->dev_topo.pd_hdls_sz, GFP_KERNEL); 8058 if (!adapter->dev_topo.pd_hdls) 8059 return -ENOMEM; 8060 8061 adapter->dev_topo.blocking_hdls = 8062 kzalloc(adapter->dev_topo.pd_hdls_sz, GFP_KERNEL); 8063 if (!adapter->dev_topo.blocking_hdls) 8064 return -ENOMEM; 8065 8066 return 0; 8067 } 8068 8069 static void leapraid_free_dev_topo_bitmaps(struct leapraid_adapter *adapter) 8070 { 8071 kfree(adapter->dev_topo.pd_hdls); 8072 kfree(adapter->dev_topo.blocking_hdls); 8073 } 8074 8075 static int leapraid_init_driver_cmds(struct leapraid_adapter *adapter) 8076 { 8077 INIT_LIST_HEAD(&adapter->driver_cmds.special_cmd_list); 8078 8079 adapter->driver_cmds.scan_dev_cmd.status = LEAPRAID_CMD_NOT_USED; 8080 adapter->driver_cmds.scan_dev_cmd.cb_idx = LEAPRAID_SCAN_DEV_CB_IDX; 8081 list_add_tail(&adapter->driver_cmds.scan_dev_cmd.list, 8082 &adapter->driver_cmds.special_cmd_list); 8083 8084 adapter->driver_cmds.cfg_op_cmd.status = LEAPRAID_CMD_NOT_USED; 8085 adapter->driver_cmds.cfg_op_cmd.cb_idx = LEAPRAID_CONFIG_CB_IDX; 8086 mutex_init(&adapter->driver_cmds.cfg_op_cmd.mutex); 8087 list_add_tail(&adapter->driver_cmds.cfg_op_cmd.list, 8088 &adapter->driver_cmds.special_cmd_list); 8089 8090 adapter->driver_cmds.transport_cmd.status = LEAPRAID_CMD_NOT_USED; 8091 adapter->driver_cmds.transport_cmd.cb_idx = LEAPRAID_TRANSPORT_CB_IDX; 8092 mutex_init(&adapter->driver_cmds.transport_cmd.mutex); 8093 list_add_tail(&adapter->driver_cmds.transport_cmd.list, 8094 &adapter->driver_cmds.special_cmd_list); 8095 8096 adapter->driver_cmds.enc_cmd.status = LEAPRAID_CMD_NOT_USED; 8097 adapter->driver_cmds.enc_cmd.cb_idx = LEAPRAID_ENC_CB_IDX; 8098 mutex_init(&adapter->driver_cmds.enc_cmd.mutex); 8099 list_add_tail(&adapter->driver_cmds.enc_cmd.list, 8100 &adapter->driver_cmds.special_cmd_list); 8101 8102 adapter->driver_cmds.notify_event_cmd.status = LEAPRAID_CMD_NOT_USED; 8103 adapter->driver_cmds.notify_event_cmd.cb_idx = 8104 LEAPRAID_NOTIFY_EVENT_CB_IDX; 8105 mutex_init(&adapter->driver_cmds.notify_event_cmd.mutex); 8106 list_add_tail(&adapter->driver_cmds.notify_event_cmd.list, 8107 &adapter->driver_cmds.special_cmd_list); 8108 8109 adapter->driver_cmds.ctl_cmd.status = LEAPRAID_CMD_NOT_USED; 8110 adapter->driver_cmds.ctl_cmd.cb_idx = LEAPRAID_CTL_CB_IDX; 8111 mutex_init(&adapter->driver_cmds.ctl_cmd.mutex); 8112 list_add_tail(&adapter->driver_cmds.ctl_cmd.list, 8113 &adapter->driver_cmds.special_cmd_list); 8114 8115 adapter->driver_cmds.tm_cmd.status = LEAPRAID_CMD_NOT_USED; 8116 adapter->driver_cmds.tm_cmd.cb_idx = LEAPRAID_TM_CB_IDX; 8117 mutex_init(&adapter->driver_cmds.tm_cmd.mutex); 8118 list_add_tail(&adapter->driver_cmds.tm_cmd.list, 8119 &adapter->driver_cmds.special_cmd_list); 8120 8121 return 0; 8122 } 8123 8124 static void leapraid_unmask_evts(struct leapraid_adapter *adapter, u16 evt) 8125 { 8126 if (evt >= LEAPRAID_MAX_EVENT_NUM) 8127 return; 8128 8129 clear_bit(evt, (unsigned long *)adapter->fw_evt_s.leapraid_evt_masks); 8130 } 8131 8132 static void leapraid_init_event_mask(struct leapraid_adapter *adapter) 8133 { 8134 int i; 8135 8136 for (i = 0; i < LEAPRAID_EVT_MASK_COUNT; i++) 8137 adapter->fw_evt_s.leapraid_evt_masks[i] = 8138 LEAPRAID_INVALID_INITIAL_VALUE; 8139 8140 leapraid_unmask_evts(adapter, LEAPRAID_EVT_SAS_TOPO_CHANGE_LIST); 8141 leapraid_unmask_evts(adapter, LEAPRAID_EVT_SAS_ENCL_DEV_STATUS_CHANGE); 8142 leapraid_unmask_evts(adapter, LEAPRAID_EVT_SAS_DEV_STATUS_CHANGE); 8143 leapraid_unmask_evts(adapter, LEAPRAID_EVT_IR_CHANGE); 8144 } 8145 8146 static void leapraid_prepare_adapter_init_req( 8147 struct leapraid_adapter *adapter, 8148 struct leapraid_adapter_init_req *init_req) 8149 { 8150 ktime_t cur_time; 8151 int i, chunk; 8152 u32 reply_post_free_ary_sz; 8153 8154 memset(init_req, 0, sizeof(struct leapraid_adapter_init_req)); 8155 init_req->func = LEAPRAID_FUNC_ADAPTER_INIT; 8156 init_req->who_init = LEAPRAID_WHOINIT_LINUX_DRIVER; 8157 init_req->msg_ver = cpu_to_le16(LEAPRAID_MSG_VERSION); 8158 init_req->header_ver = cpu_to_le16(LEAPRAID_HEADER_VERSION); 8159 init_req->driver_ver = 8160 cpu_to_le32((LEAPRAID_MAJOR_VERSION << 8161 LEAPRAID_VER_MAJOR_SHIFT) | 8162 (LEAPRAID_MINOR_VERSION << LEAPRAID_VER_MINOR_SHIFT) | 8163 (LEAPRAID_BUILD_VERSION << LEAPRAID_VER_BUILD_SHIFT) | 8164 LEAPRAID_RELEASE_VERSION); 8165 if (adapter->notification_desc.msix_enable) 8166 init_req->host_msix_vectors = adapter->adapter_attr.rq_cnt; 8167 8168 init_req->req_frame_size = 8169 cpu_to_le16(LEAPRAID_REQUEST_SIZE / LEAPRAID_DWORDS_BYTE_SIZE); 8170 init_req->rep_desc_qd = 8171 cpu_to_le16(adapter->adapter_attr.rep_desc_qd); 8172 init_req->rep_msg_qd = 8173 cpu_to_le16(adapter->adapter_attr.rep_msg_qd); 8174 init_req->sense_buffer_add_high = 8175 cpu_to_le32((u64)adapter->mem_desc.sense_data_dma >> 32); 8176 init_req->rep_msg_dma_high = 8177 cpu_to_le32((u64)adapter->mem_desc.rep_msg_dma >> 32); 8178 init_req->task_desc_base_addr = 8179 cpu_to_le64((u64)adapter->mem_desc.task_desc_dma); 8180 init_req->rep_msg_addr_dma = 8181 cpu_to_le64((u64)adapter->mem_desc.rep_msg_addr_dma); 8182 if (!reset_devices) { 8183 reply_post_free_ary_sz = 8184 adapter->adapter_attr.rq_cnt * LEAPRAID_REP_RQ_CNT_SIZE; 8185 memset(adapter->mem_desc.rep_desc_q_arr, 0, 8186 reply_post_free_ary_sz); 8187 8188 chunk = LEAPRAID_REP_DESC_CHUNK_SIZE; 8189 for (i = 0; i < adapter->adapter_attr.rq_cnt; i++) 8190 adapter->mem_desc.rep_desc_q_arr[i].rep_desc_base_addr = 8191 cpu_to_le64 ((u64)adapter->mem_desc 8192 .rep_desc_seg_maint[i / chunk] 8193 .rep_desc_maint[i % chunk] 8194 .rep_desc_dma); 8195 8196 init_req->msg_flg = 8197 LEAPRAID_ADAPTER_INIT_MSGFLG_RDPQ_ARRAY_MODE; 8198 init_req->rep_desc_q_arr_addr = 8199 cpu_to_le64((u64)adapter->mem_desc.rep_desc_q_arr_dma); 8200 } else { 8201 init_req->rep_desc_q_arr_addr = 8202 cpu_to_le64((u64)adapter->mem_desc 8203 .rep_desc_seg_maint[0] 8204 .rep_desc_maint[0] 8205 .rep_desc_dma); 8206 } 8207 cur_time = ktime_get_real(); 8208 init_req->time_stamp = cpu_to_le64(ktime_to_ms(cur_time)); 8209 } 8210 8211 static int leapraid_send_adapter_init(struct leapraid_adapter *adapter) 8212 { 8213 struct leapraid_adapter_init_req init_req; 8214 struct leapraid_adapter_init_rep init_rep; 8215 u16 adapter_status; 8216 int rc; 8217 8218 leapraid_prepare_adapter_init_req(adapter, &init_req); 8219 8220 rc = leapraid_handshake_func(adapter, 8221 sizeof(struct leapraid_adapter_init_req), 8222 (u32 *)&init_req, 8223 sizeof(struct leapraid_adapter_init_rep), 8224 (u16 *)&init_rep); 8225 if (rc != 0) { 8226 dev_err(&adapter->pdev->dev, "%s: Handshake failed, rc=%d\n", 8227 __func__, rc); 8228 return rc; 8229 } 8230 8231 adapter_status = 8232 le16_to_cpu(init_rep.adapter_status) & 8233 LEAPRAID_ADAPTER_STATUS_MASK; 8234 if (adapter_status != LEAPRAID_ADAPTER_STATUS_SUCCESS) { 8235 dev_err(&adapter->pdev->dev, "%s: failed\n", __func__); 8236 rc = -EIO; 8237 } 8238 8239 return rc; 8240 } 8241 8242 static int leapraid_cfg_pages(struct leapraid_adapter *adapter) 8243 { 8244 union cfg_param_1 cfgp1 = {0}; 8245 union cfg_param_2 cfgp2 = {0}; 8246 union { 8247 struct leapraid_manufacturing_p0 manufacturing_page0; 8248 struct leapraid_bios_page3 bios_page3; 8249 struct leapraid_bios_page2 bios_page2; 8250 } cfg_page; 8251 int rc; 8252 8253 rc = leapraid_op_config_page(adapter, &cfg_page.bios_page3, cfgp1, 8254 cfgp2, GET_BIOS_PG3); 8255 if (rc) 8256 return rc; 8257 8258 adapter->adapter_attr.bios_version = 8259 le32_to_cpu(cfg_page.bios_page3.bios_version); 8260 8261 rc = leapraid_op_config_page(adapter, &cfg_page.bios_page2, cfgp1, 8262 cfgp2, GET_BIOS_PG2); 8263 if (rc) 8264 return rc; 8265 8266 adapter->boot_devs.requested_boot_dev.form = 8267 cfg_page.bios_page2.requested_boot_dev_form; 8268 memcpy(adapter->boot_devs.requested_boot_dev.pg_dev, 8269 &cfg_page.bios_page2.requested_boot_dev, 8270 LEAPRAID_BOOT_DEV_SIZE); 8271 adapter->boot_devs.requested_alt_boot_dev.form = 8272 cfg_page.bios_page2.requested_alt_boot_dev_form; 8273 memcpy(adapter->boot_devs.requested_alt_boot_dev.pg_dev, 8274 &cfg_page.bios_page2.requested_alt_boot_dev, 8275 LEAPRAID_BOOT_DEV_SIZE); 8276 adapter->boot_devs.current_boot_dev.form = 8277 cfg_page.bios_page2.current_boot_dev_form; 8278 memcpy(adapter->boot_devs.current_boot_dev.pg_dev, 8279 &cfg_page.bios_page2.current_boot_dev, 8280 LEAPRAID_BOOT_DEV_SIZE); 8281 8282 rc = leapraid_op_config_page(adapter, &cfg_page.manufacturing_page0, 8283 cfgp1, cfgp2, GET_MANUFACTURING_PG0); 8284 if (rc) 8285 return rc; 8286 8287 snprintf(adapter->adapter_attr.board_name, 8288 sizeof(adapter->adapter_attr.board_name), 8289 "%.*s", 8290 (int)sizeof(cfg_page.manufacturing_page0.board_name), 8291 cfg_page.manufacturing_page0.board_name); 8292 return rc; 8293 } 8294 8295 static int leapraid_evt_notify(struct leapraid_adapter *adapter) 8296 { 8297 struct leapraid_evt_notify_req *evt_notify_req; 8298 struct leapraid_evt_notify_rep *evt_notify_rep; 8299 u16 adapter_status; 8300 int rc = 0; 8301 int i; 8302 8303 mutex_lock(&adapter->driver_cmds.notify_event_cmd.mutex); 8304 adapter->driver_cmds.notify_event_cmd.status = LEAPRAID_CMD_PENDING; 8305 evt_notify_req = 8306 leapraid_get_task_desc( 8307 adapter, 8308 adapter->driver_cmds.notify_event_cmd.inter_taskid); 8309 memset(evt_notify_req, 0, sizeof(struct leapraid_evt_notify_req)); 8310 evt_notify_req->func = LEAPRAID_FUNC_EVENT_NOTIFY; 8311 for (i = 0; i < LEAPRAID_EVT_MASK_COUNT; i++) 8312 evt_notify_req->evt_masks[i] = 8313 cpu_to_le32(adapter->fw_evt_s.leapraid_evt_masks[i]); 8314 init_completion(&adapter->driver_cmds.notify_event_cmd.done); 8315 leapraid_fire_task(adapter, 8316 adapter->driver_cmds.notify_event_cmd.inter_taskid); 8317 wait_for_completion_timeout( 8318 &adapter->driver_cmds.notify_event_cmd.done, 8319 LEAPRAID_NOTIFY_EVENT_CMD_TIMEOUT * HZ); 8320 8321 if (!(adapter->driver_cmds.notify_event_cmd.status & 8322 LEAPRAID_CMD_DONE)) { 8323 rc = -EFAULT; 8324 goto out_cleanup; 8325 } 8326 8327 if (!(adapter->driver_cmds.notify_event_cmd.status & 8328 LEAPRAID_CMD_REPLY_VALID)) { 8329 rc = -EFAULT; 8330 goto out_cleanup; 8331 } 8332 8333 evt_notify_rep = (void *)&adapter->driver_cmds.notify_event_cmd.reply; 8334 adapter_status = le16_to_cpu(evt_notify_rep->adapter_status) & 8335 LEAPRAID_ADAPTER_STATUS_MASK; 8336 if (adapter_status != LEAPRAID_ADAPTER_STATUS_SUCCESS) 8337 rc = -EFAULT; 8338 8339 out_cleanup: 8340 adapter->driver_cmds.notify_event_cmd.status = LEAPRAID_CMD_NOT_USED; 8341 mutex_unlock(&adapter->driver_cmds.notify_event_cmd.mutex); 8342 8343 return rc; 8344 } 8345 8346 int leapraid_scan_dev(struct leapraid_adapter *adapter, bool async_scan_dev) 8347 { 8348 struct leapraid_scan_dev_req *scan_dev_req; 8349 struct leapraid_scan_dev_rep *scan_dev_rep; 8350 u16 adapter_status; 8351 int rc = 0; 8352 8353 dev_info(&adapter->pdev->dev, 8354 "Send device scan, async_scan_dev=%d!\n", async_scan_dev); 8355 8356 adapter->driver_cmds.scan_dev_cmd.status = LEAPRAID_CMD_PENDING; 8357 adapter->driver_cmds.scan_dev_cmd.async_scan_dev = async_scan_dev; 8358 scan_dev_req = 8359 leapraid_get_task_desc( 8360 adapter, 8361 adapter->driver_cmds.scan_dev_cmd.inter_taskid); 8362 memset(scan_dev_req, 0, sizeof(struct leapraid_scan_dev_req)); 8363 scan_dev_req->func = LEAPRAID_FUNC_SCAN_DEV; 8364 8365 if (async_scan_dev) { 8366 adapter->scan_dev_desc.first_scan_dev_fired = 1; 8367 leapraid_fire_task( 8368 adapter, 8369 adapter->driver_cmds.scan_dev_cmd.inter_taskid); 8370 return 0; 8371 } 8372 8373 init_completion(&adapter->driver_cmds.scan_dev_cmd.done); 8374 leapraid_fire_task(adapter, 8375 adapter->driver_cmds.scan_dev_cmd.inter_taskid); 8376 wait_for_completion_timeout(&adapter->driver_cmds.scan_dev_cmd.done, 8377 LEAPRAID_SCAN_DEV_CMD_TIMEOUT * HZ); 8378 if (!(adapter->driver_cmds.scan_dev_cmd.status & LEAPRAID_CMD_DONE)) { 8379 dev_err(&adapter->pdev->dev, "Device scan timeout!\n"); 8380 if (adapter->driver_cmds.scan_dev_cmd.status & 8381 LEAPRAID_CMD_RESET) 8382 rc = -EFAULT; 8383 else 8384 rc = -ETIME; 8385 goto out_cleanup; 8386 } 8387 8388 scan_dev_rep = (void *)&adapter->driver_cmds.scan_dev_cmd.reply; 8389 adapter_status = 8390 le16_to_cpu(scan_dev_rep->adapter_status) & 8391 LEAPRAID_ADAPTER_STATUS_MASK; 8392 if (adapter_status != LEAPRAID_ADAPTER_STATUS_SUCCESS) { 8393 dev_err(&adapter->pdev->dev, "Device scan failure!\n"); 8394 rc = -EFAULT; 8395 goto out_cleanup; 8396 } 8397 8398 out_cleanup: 8399 adapter->driver_cmds.scan_dev_cmd.status = LEAPRAID_CMD_NOT_USED; 8400 return rc; 8401 } 8402 8403 static void leapraid_init_task_tracker(struct leapraid_adapter *adapter) 8404 { 8405 unsigned long flags; 8406 8407 spin_lock_irqsave(&adapter->dynamic_task_desc.task_lock, flags); 8408 8409 spin_unlock_irqrestore(&adapter->dynamic_task_desc.task_lock, flags); 8410 } 8411 8412 static void leapraid_init_rep_msg_addr(struct leapraid_adapter *adapter) 8413 { 8414 u32 reply_address; 8415 unsigned int i; 8416 8417 for (i = 0, reply_address = (u32)adapter->mem_desc.rep_msg_dma; 8418 i < adapter->adapter_attr.rep_msg_qd; 8419 i++, reply_address += LEAPRAID_REPLY_SIZE) 8420 adapter->mem_desc.rep_msg_addr[i] = cpu_to_le32(reply_address); 8421 } 8422 8423 static void init_rep_desc( 8424 struct leapraid_rq *rq, 8425 int index, 8426 union leapraid_rep_desc_union *reply_post_free_contig) 8427 { 8428 struct leapraid_adapter *adapter = rq->adapter; 8429 unsigned int i; 8430 8431 if (!reset_devices) 8432 rq->rep_desc = 8433 adapter->mem_desc 8434 .rep_desc_seg_maint[index / 8435 LEAPRAID_REP_DESC_CHUNK_SIZE] 8436 .rep_desc_maint[index % 8437 LEAPRAID_REP_DESC_CHUNK_SIZE] 8438 .rep_desc; 8439 else 8440 rq->rep_desc = reply_post_free_contig; 8441 8442 rq->rep_post_host_idx = 0; 8443 for (i = 0; i < adapter->adapter_attr.rep_desc_qd; i++) 8444 rq->rep_desc[i].words = cpu_to_le64(ULLONG_MAX); 8445 } 8446 8447 static void leapraid_init_rep_desc(struct leapraid_adapter *adapter) 8448 { 8449 union leapraid_rep_desc_union *reply_post_free_contig; 8450 struct leapraid_int_rq *int_rq; 8451 struct leapraid_blk_mq_poll_rq *blk_mq_poll_rq; 8452 unsigned int i; 8453 int index; 8454 8455 index = 0; 8456 reply_post_free_contig = adapter->mem_desc 8457 .rep_desc_seg_maint[0] 8458 .rep_desc_maint[0] 8459 .rep_desc; 8460 8461 for (i = 0; i < adapter->notification_desc.iopoll_qdex; i++) { 8462 int_rq = &adapter->notification_desc.int_rqs[i]; 8463 init_rep_desc(&int_rq->rq, index, reply_post_free_contig); 8464 if (!reset_devices) 8465 index++; 8466 else 8467 reply_post_free_contig += 8468 adapter->adapter_attr.rep_desc_qd; 8469 } 8470 8471 for (i = 0; i < adapter->notification_desc.iopoll_qcnt; i++) { 8472 blk_mq_poll_rq = &adapter->notification_desc.blk_mq_poll_rqs[i]; 8473 init_rep_desc(&blk_mq_poll_rq->rq, 8474 index, reply_post_free_contig); 8475 if (!reset_devices) 8476 index++; 8477 else 8478 reply_post_free_contig += 8479 adapter->adapter_attr.rep_desc_qd; 8480 } 8481 } 8482 8483 static void leapraid_init_bar_idx_regs(struct leapraid_adapter *adapter) 8484 { 8485 struct leapraid_int_rq *int_rq; 8486 struct leapraid_blk_mq_poll_rq *blk_mq_poll_rq; 8487 unsigned int i, j; 8488 8489 adapter->rep_msg_host_idx = adapter->adapter_attr.rep_msg_qd - 1; 8490 writel(adapter->rep_msg_host_idx, 8491 &adapter->iomem_base->rep_msg_host_idx); 8492 8493 for (i = 0; i < adapter->notification_desc.iopoll_qdex; i++) { 8494 int_rq = &adapter->notification_desc.int_rqs[i]; 8495 for (j = 0; j < REP_POST_HOST_IDX_REG_CNT; j++) 8496 writel((int_rq->rq.msix_idx & 7) << 8497 LEAPRAID_RPHI_MSIX_IDX_SHIFT, 8498 &adapter->iomem_base->rep_post_reg_idx[j].idx); 8499 } 8500 8501 for (i = 0; i < adapter->notification_desc.iopoll_qcnt; i++) { 8502 blk_mq_poll_rq = 8503 &adapter->notification_desc.blk_mq_poll_rqs[i]; 8504 for (j = 0; j < REP_POST_HOST_IDX_REG_CNT; j++) 8505 writel((blk_mq_poll_rq->rq.msix_idx & 7) << 8506 LEAPRAID_RPHI_MSIX_IDX_SHIFT, 8507 &adapter->iomem_base->rep_post_reg_idx[j].idx); 8508 } 8509 } 8510 8511 static int leapraid_make_adapter_available(struct leapraid_adapter *adapter) 8512 { 8513 int rc; 8514 8515 leapraid_init_task_tracker(adapter); 8516 leapraid_init_rep_msg_addr(adapter); 8517 8518 if (adapter->scan_dev_desc.driver_loading) 8519 leapraid_configure_reply_queue_affinity(adapter); 8520 8521 leapraid_init_rep_desc(adapter); 8522 rc = leapraid_send_adapter_init(adapter); 8523 if (rc) 8524 return rc; 8525 8526 leapraid_init_bar_idx_regs(adapter); 8527 leapraid_unmask_int(adapter); 8528 rc = leapraid_cfg_pages(adapter); 8529 if (rc) 8530 return rc; 8531 8532 rc = leapraid_evt_notify(adapter); 8533 if (rc) 8534 return rc; 8535 8536 if (!adapter->access_ctrl.shost_recovering) { 8537 adapter->scan_dev_desc.wait_scan_dev_done = 1; 8538 return 0; 8539 } 8540 8541 return leapraid_scan_dev(adapter, false); 8542 } 8543 8544 int leapraid_ctrl_init(struct leapraid_adapter *adapter) 8545 { 8546 u32 cap; 8547 int rc; 8548 8549 rc = leapraid_init_driver_cmds(adapter); 8550 if (rc) { 8551 dev_err(&adapter->pdev->dev, "Init driver cmds failure\n"); 8552 goto out_free; 8553 } 8554 8555 rc = leapraid_set_pcie_and_notification(adapter); 8556 if (rc) 8557 goto out_free; 8558 8559 pci_set_drvdata(adapter->pdev, adapter->shost); 8560 8561 pcie_capability_read_dword(adapter->pdev, PCI_EXP_DEVCAP, &cap); 8562 8563 if (cap & PCI_EXP_DEVCAP_EXT_TAG) 8564 pcie_capability_set_word(adapter->pdev, PCI_EXP_DEVCTL, 8565 PCI_EXP_DEVCTL_EXT_TAG); 8566 8567 rc = leapraid_fw_log_init(adapter); 8568 if (rc) { 8569 dev_err(&adapter->pdev->dev, "FW log init failure\n"); 8570 goto out_free; 8571 } 8572 8573 rc = leapraid_request_host_memory(adapter); 8574 if (rc) { 8575 dev_err(&adapter->pdev->dev, "Request host memory failure\n"); 8576 goto out_free; 8577 } 8578 8579 init_waitqueue_head(&adapter->reset_desc.reset_wait_queue); 8580 init_waitqueue_head(&adapter->access_ctrl.shost_recover_wq); 8581 8582 rc = leapraid_alloc_dev_topo_bitmaps(adapter); 8583 if (rc) { 8584 dev_err(&adapter->pdev->dev, "Alloc topo bitmaps failure\n"); 8585 goto out_free; 8586 } 8587 8588 leapraid_init_event_mask(adapter); 8589 8590 rc = leapraid_make_adapter_available(adapter); 8591 if (rc) { 8592 dev_err(&adapter->pdev->dev, 8593 "Make adapter available failure\n"); 8594 goto out_free; 8595 } 8596 8597 leapraid_overheat_init(adapter); 8598 if (!adapter->overheat_desc.fault_overheat_wq) { 8599 rc = -ENOMEM; 8600 goto out_free; 8601 } 8602 8603 return 0; 8604 8605 out_free: 8606 adapter->access_ctrl.host_removing = 1; 8607 leapraid_fw_log_exit(adapter); 8608 leapraid_disable_controller(adapter); 8609 leapraid_free_host_memory(adapter); 8610 leapraid_free_dev_topo_bitmaps(adapter); 8611 pci_set_drvdata(adapter->pdev, NULL); 8612 return rc; 8613 } 8614 8615 void leapraid_remove_ctrl(struct leapraid_adapter *adapter) 8616 { 8617 leapraid_overheat_cleanup(adapter); 8618 leapraid_check_scheduled_fault_stop(adapter); 8619 leapraid_fw_log_stop(adapter); 8620 leapraid_fw_log_exit(adapter); 8621 leapraid_disable_controller(adapter); 8622 leapraid_free_host_memory(adapter); 8623 leapraid_free_dev_topo_bitmaps(adapter); 8624 leapraid_free_enc_list(adapter); 8625 pci_set_drvdata(adapter->pdev, NULL); 8626 } 8627