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 = scsi_get_host_state(shost); 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 = kzalloc_obj(*fw_evt, GFP_ATOMIC); 2988 2989 if (fw_evt) 2990 kref_init(&fw_evt->refcnt); 2991 2992 return fw_evt; 2993 } 2994 2995 static void leapraid_run_fw_evt_work(struct work_struct *work) 2996 { 2997 struct leapraid_fw_evt_work *fw_evt = 2998 container_of(work, struct leapraid_fw_evt_work, work); 2999 3000 leapraid_fw_work(fw_evt->adapter, fw_evt); 3001 } 3002 3003 static void leapraid_fw_evt_add(struct leapraid_adapter *adapter, 3004 struct leapraid_fw_evt_work *fw_evt) 3005 { 3006 unsigned long flags; 3007 3008 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags); 3009 if (adapter->access_ctrl.host_removing || 3010 adapter->access_ctrl.pcie_recovering || 3011 !adapter->fw_evt_s.fw_evt_thread) { 3012 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags); 3013 return; 3014 } 3015 3016 leapraid_fw_evt_get(fw_evt); 3017 INIT_LIST_HEAD(&fw_evt->list); 3018 list_add_tail(&fw_evt->list, &adapter->fw_evt_s.fw_evt_list); 3019 INIT_WORK(&fw_evt->work, leapraid_run_fw_evt_work); 3020 leapraid_fw_evt_get(fw_evt); 3021 queue_work(adapter->fw_evt_s.fw_evt_thread, &fw_evt->work); 3022 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags); 3023 } 3024 3025 static void leapraid_del_fw_evt_from_list(struct leapraid_adapter *adapter, 3026 struct leapraid_fw_evt_work *fw_evt) 3027 { 3028 unsigned long flags; 3029 3030 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags); 3031 if (!list_empty(&fw_evt->list)) { 3032 list_del_init(&fw_evt->list); 3033 leapraid_fw_evt_put(fw_evt); 3034 } 3035 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags); 3036 } 3037 3038 static struct leapraid_fw_evt_work *leapraid_next_fw_evt( 3039 struct leapraid_adapter *adapter) 3040 { 3041 struct leapraid_fw_evt_work *fw_evt = NULL; 3042 unsigned long flags; 3043 3044 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags); 3045 if (!list_empty(&adapter->fw_evt_s.fw_evt_list)) { 3046 fw_evt = list_first_entry(&adapter->fw_evt_s.fw_evt_list, 3047 struct leapraid_fw_evt_work, list); 3048 list_del_init(&fw_evt->list); 3049 } 3050 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags); 3051 return fw_evt; 3052 } 3053 3054 void leapraid_clean_active_fw_evt(struct leapraid_adapter *adapter) 3055 { 3056 struct leapraid_fw_evt_work *fw_evt; 3057 unsigned long flags; 3058 bool in_fw_evt_context; 3059 bool rc; 3060 3061 if ((list_empty(&adapter->fw_evt_s.fw_evt_list) && 3062 !adapter->fw_evt_s.cur_evt) || !adapter->fw_evt_s.fw_evt_thread) 3063 return; 3064 3065 adapter->fw_evt_s.fw_evt_cleanup = 1; 3066 if (adapter->access_ctrl.shost_recovering && 3067 adapter->fw_evt_s.cur_evt) 3068 adapter->fw_evt_s.cur_evt->ignore = 1; 3069 3070 while ((fw_evt = leapraid_next_fw_evt(adapter))) { 3071 rc = cancel_work_sync(&fw_evt->work); 3072 if (rc) 3073 leapraid_fw_evt_put(fw_evt); 3074 leapraid_fw_evt_put(fw_evt); 3075 } 3076 3077 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags); 3078 fw_evt = adapter->fw_evt_s.cur_evt; 3079 if (fw_evt) { 3080 in_fw_evt_context = adapter->fw_evt_s.cur_evt_task == current; 3081 leapraid_fw_evt_get(fw_evt); 3082 } 3083 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags); 3084 if (fw_evt) { 3085 if (!in_fw_evt_context) 3086 cancel_work_sync(&fw_evt->work); 3087 leapraid_fw_evt_put(fw_evt); 3088 } 3089 3090 adapter->fw_evt_s.fw_evt_cleanup = 0; 3091 } 3092 3093 static void leapraid_internal_dev_ublk(struct scsi_device *sdev, 3094 struct leapraid_sdev_priv *sdev_priv) 3095 { 3096 int rc; 3097 3098 sdev_printk(KERN_WARNING, sdev, 3099 "hdl 0x%04x: Now internal unblkg dev\n", 3100 sdev_priv->starget_priv->hdl); 3101 sdev_priv->block = 0; 3102 rc = scsi_internal_device_unblock_nowait(sdev, SDEV_RUNNING); 3103 if (rc == -EINVAL) { 3104 sdev_printk(KERN_WARNING, sdev, 3105 "hdl 0x%04x: unblkg failed, rc=%d\n", 3106 sdev_priv->starget_priv->hdl, rc); 3107 sdev_priv->block = 1; 3108 rc = scsi_internal_device_block_nowait(sdev); 3109 if (rc) 3110 sdev_printk(KERN_WARNING, sdev, 3111 "hdl 0x%04x: Earlier ublkg err, rc=%d\n", 3112 sdev_priv->starget_priv->hdl, rc); 3113 3114 sdev_priv->block = 0; 3115 rc = scsi_internal_device_unblock_nowait(sdev, SDEV_RUNNING); 3116 if (rc) 3117 sdev_printk(KERN_WARNING, sdev, 3118 "hdl 0x%04x: ublkg failed again, rc=%d\n", 3119 sdev_priv->starget_priv->hdl, rc); 3120 } 3121 } 3122 3123 static void leapraid_ublk_io_dev(struct leapraid_adapter *adapter, 3124 u64 sas_addr, 3125 struct leapraid_card_port *card_port) 3126 { 3127 struct leapraid_sdev_priv *sdev_priv; 3128 struct scsi_device *sdev; 3129 3130 shost_for_each_device(sdev, adapter->shost) { 3131 sdev_priv = sdev->hostdata; 3132 if (!sdev_priv || !sdev_priv->starget_priv) 3133 continue; 3134 3135 if (sdev_priv->starget_priv->sas_address != sas_addr) 3136 continue; 3137 3138 if (sdev_priv->starget_priv->card_port != card_port) 3139 continue; 3140 3141 if (sdev_priv->block) 3142 leapraid_internal_dev_ublk(sdev, sdev_priv); 3143 3144 scsi_device_set_state(sdev, SDEV_OFFLINE); 3145 } 3146 } 3147 3148 static void leapraid_ublk_io_all_dev(struct leapraid_adapter *adapter) 3149 { 3150 struct leapraid_sdev_priv *sdev_priv; 3151 struct leapraid_starget_priv *stgt_priv; 3152 struct scsi_device *sdev; 3153 3154 shost_for_each_device(sdev, adapter->shost) { 3155 sdev_priv = sdev->hostdata; 3156 3157 if (!sdev_priv) 3158 continue; 3159 3160 stgt_priv = sdev_priv->starget_priv; 3161 if (!stgt_priv || stgt_priv->deleted) 3162 continue; 3163 3164 if (!sdev_priv->block) 3165 continue; 3166 3167 sdev_printk(KERN_WARNING, sdev, "hdl 0x%04x: blkg...\n", 3168 sdev_priv->starget_priv->hdl); 3169 leapraid_internal_dev_ublk(sdev, sdev_priv); 3170 continue; 3171 } 3172 } 3173 3174 static void leapraid_internal_dev_blk( 3175 struct scsi_device *sdev, 3176 struct leapraid_sdev_priv *sdev_priv) 3177 { 3178 int rc; 3179 3180 sdev_printk(KERN_INFO, sdev, "Internal blkg hdl 0x%04x\n", 3181 sdev_priv->starget_priv->hdl); 3182 sdev_priv->block = 1; 3183 rc = scsi_internal_device_block_nowait(sdev); 3184 if (rc == -EINVAL) 3185 sdev_printk(KERN_WARNING, sdev, 3186 "hdl 0x%04x: blkg failed, rc=%d\n", 3187 rc, sdev_priv->starget_priv->hdl); 3188 } 3189 3190 static void leapraid_imm_blkio_to_end_dev(struct leapraid_adapter *adapter, 3191 struct leapraid_sas_port *sas_port) 3192 { 3193 struct leapraid_sdev_priv *sdev_priv; 3194 struct leapraid_sas_dev *sas_dev; 3195 struct scsi_device *sdev; 3196 unsigned long flags; 3197 3198 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 3199 sas_dev = leapraid_hold_lock_get_sas_dev_by_addr( 3200 adapter, 3201 sas_port->remote_identify.sas_address, 3202 sas_port->card_port); 3203 3204 if (sas_dev) { 3205 shost_for_each_device(sdev, adapter->shost) { 3206 sdev_priv = sdev->hostdata; 3207 if (!sdev_priv) 3208 continue; 3209 3210 if (sdev_priv->starget_priv->hdl != sas_dev->hdl) 3211 continue; 3212 3213 if (sdev_priv->block) 3214 continue; 3215 3216 if (sas_dev && sas_dev->pend_sas_rphy_add) 3217 continue; 3218 3219 if (sdev_priv->sep) { 3220 sdev_printk(KERN_INFO, sdev, 3221 "skip dev blk: sep hdl 0x%04x\n", 3222 sdev_priv->starget_priv->hdl); 3223 continue; 3224 } 3225 3226 leapraid_internal_dev_blk(sdev, sdev_priv); 3227 } 3228 3229 leapraid_sdev_put(sas_dev); 3230 } 3231 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 3232 } 3233 3234 static void leapraid_imm_blkio_set_end_dev_blk_hdls( 3235 struct leapraid_adapter *adapter, 3236 struct leapraid_topo_node *topo_node_exp) 3237 { 3238 struct leapraid_sas_port *sas_port; 3239 3240 list_for_each_entry(sas_port, 3241 &topo_node_exp->sas_port_list, port_list) { 3242 if (sas_port->remote_identify.device_type == SAS_END_DEVICE) 3243 leapraid_imm_blkio_to_end_dev(adapter, sas_port); 3244 } 3245 } 3246 3247 static void leapraid_imm_blkio_to_kids_attchd_to_ex( 3248 struct leapraid_adapter *adapter, 3249 struct leapraid_topo_node *topo_node_exp); 3250 3251 static void leapraid_imm_blkio_to_sib_exp( 3252 struct leapraid_adapter *adapter, 3253 struct leapraid_topo_node *topo_node_exp) 3254 { 3255 struct leapraid_topo_node *topo_node_exp_sib; 3256 struct leapraid_sas_port *sas_port; 3257 3258 list_for_each_entry(sas_port, 3259 &topo_node_exp->sas_port_list, port_list) { 3260 if (sas_port->remote_identify.device_type == 3261 SAS_EDGE_EXPANDER_DEVICE || 3262 sas_port->remote_identify.device_type == 3263 SAS_FANOUT_EXPANDER_DEVICE) { 3264 topo_node_exp_sib = 3265 leapraid_exp_find_by_sas_address( 3266 adapter, 3267 sas_port->remote_identify.sas_address, 3268 sas_port->card_port); 3269 leapraid_imm_blkio_to_kids_attchd_to_ex( 3270 adapter, 3271 topo_node_exp_sib); 3272 } 3273 } 3274 } 3275 3276 static void leapraid_imm_blkio_to_kids_attchd_to_ex( 3277 struct leapraid_adapter *adapter, 3278 struct leapraid_topo_node *topo_node_exp) 3279 { 3280 if (!topo_node_exp) 3281 return; 3282 3283 leapraid_imm_blkio_set_end_dev_blk_hdls(adapter, topo_node_exp); 3284 3285 leapraid_imm_blkio_to_sib_exp(adapter, topo_node_exp); 3286 } 3287 3288 static void leapraid_report_sdev_directly(struct leapraid_adapter *adapter, 3289 struct leapraid_sas_dev *sas_dev) 3290 { 3291 struct leapraid_sas_port *sas_port; 3292 3293 sas_port = leapraid_transport_port_add(adapter, 3294 sas_dev->hdl, 3295 sas_dev->parent_sas_addr, 3296 sas_dev->card_port); 3297 if (!sas_port) { 3298 leapraid_sas_dev_remove(adapter, sas_dev); 3299 return; 3300 } 3301 3302 if (!sas_dev->starget) { 3303 if (!adapter->scan_dev_desc.driver_loading) { 3304 leapraid_transport_port_remove( 3305 adapter, 3306 sas_dev->sas_addr, 3307 sas_dev->parent_sas_addr, 3308 sas_dev->card_port); 3309 leapraid_sas_dev_remove(adapter, sas_dev); 3310 } 3311 return; 3312 } 3313 } 3314 3315 static struct leapraid_sas_dev *leapraid_init_sas_dev( 3316 struct leapraid_adapter *adapter, 3317 struct leapraid_sas_dev_p0 *sas_dev_pg0, 3318 struct leapraid_card_port *card_port, u16 hdl, 3319 u64 parent_sas_addr, u64 sas_addr, u32 dev_info) 3320 { 3321 struct leapraid_sas_dev *sas_dev; 3322 struct leapraid_enc_node *enc_dev; 3323 unsigned long flags; 3324 3325 sas_dev = kzalloc_obj(*sas_dev); 3326 if (!sas_dev) 3327 return NULL; 3328 3329 kref_init(&sas_dev->refcnt); 3330 sas_dev->hdl = hdl; 3331 sas_dev->dev_info = dev_info; 3332 sas_dev->sas_addr = sas_addr; 3333 sas_dev->card_port = card_port; 3334 sas_dev->parent_sas_addr = parent_sas_addr; 3335 sas_dev->phy = sas_dev_pg0->phy_num; 3336 sas_dev->enc_hdl = le16_to_cpu(sas_dev_pg0->enc_hdl); 3337 sas_dev->dev_name = le64_to_cpu(sas_dev_pg0->dev_name); 3338 sas_dev->port_connection = sas_dev_pg0->max_port_connections; 3339 sas_dev->slot = sas_dev->enc_hdl ? le16_to_cpu(sas_dev_pg0->slot) : 0; 3340 if (le16_to_cpu(sas_dev_pg0->flg) & 3341 LEAPRAID_SAS_DEV_P0_FLG_ENC_LEVEL_VALID) { 3342 sas_dev->enc_level = sas_dev_pg0->enc_level; 3343 memcpy(sas_dev->connector_name, 3344 sas_dev_pg0->connector_name, 3345 LEAPRAID_SAS_DEV_P0_CON_NAME_LEN); 3346 sas_dev->connector_name[LEAPRAID_SAS_DEV_P0_CON_NAME_LEN] = 3347 '\0'; 3348 } else { 3349 sas_dev->enc_level = 0; 3350 sas_dev->connector_name[0] = '\0'; 3351 } 3352 if (sas_dev->enc_hdl) { 3353 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags); 3354 enc_dev = leapraid_enc_find_by_hdl(adapter, sas_dev->enc_hdl); 3355 if (enc_dev) 3356 sas_dev->enc_lid = le64_to_cpu(enc_dev->pg0.enc_lid); 3357 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags); 3358 } 3359 dev_info(&adapter->pdev->dev, 3360 "add dev: hdl=0x%x, SAS addr=0x%016llx, port connect=0x%x\n", 3361 hdl, sas_dev->sas_addr, sas_dev->port_connection); 3362 3363 return sas_dev; 3364 } 3365 3366 static void leapraid_add_dev(struct leapraid_adapter *adapter, u16 hdl) 3367 { 3368 union cfg_param_1 cfgp1 = {0}; 3369 union cfg_param_2 cfgp2 = {0}; 3370 struct leapraid_sas_dev_p0 sas_dev_pg0; 3371 struct leapraid_card_port *card_port; 3372 struct leapraid_sas_dev *sas_dev; 3373 unsigned long flags; 3374 u64 parent_sas_addr; 3375 u32 dev_info; 3376 u64 sas_addr; 3377 u8 port_id; 3378 3379 cfgp1.form = LEAPRAID_SAS_DEV_CFG_PGAD_HDL; 3380 cfgp2.handle = hdl; 3381 if (leapraid_op_config_page(adapter, &sas_dev_pg0, 3382 cfgp1, cfgp2, GET_SAS_DEVICE_PG0)) 3383 return; 3384 3385 dev_info = le32_to_cpu(sas_dev_pg0.dev_info); 3386 if (!(leapraid_is_end_dev(dev_info))) 3387 return; 3388 3389 sas_addr = le64_to_cpu(sas_dev_pg0.sas_address); 3390 if (!(le16_to_cpu(sas_dev_pg0.flg) & 3391 LEAPRAID_SAS_DEV_P0_FLG_DEV_PRESENT)) 3392 return; 3393 3394 port_id = sas_dev_pg0.physical_port; 3395 card_port = leapraid_get_port_by_id(adapter, port_id, false); 3396 if (!card_port) 3397 return; 3398 3399 sas_dev = leapraid_get_sas_dev_by_addr(adapter, sas_addr, card_port); 3400 if (sas_dev) { 3401 leapraid_sdev_put(sas_dev); 3402 return; 3403 } 3404 3405 if (leapraid_get_sas_address(adapter, 3406 le16_to_cpu(sas_dev_pg0.parent_dev_hdl), 3407 &parent_sas_addr)) 3408 return; 3409 3410 sas_dev = leapraid_init_sas_dev(adapter, &sas_dev_pg0, card_port, 3411 hdl, parent_sas_addr, sas_addr, 3412 dev_info); 3413 if (!sas_dev) 3414 return; 3415 3416 if (adapter->scan_dev_desc.wait_scan_dev_done) { 3417 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 3418 leapraid_sdev_get(sas_dev); 3419 list_add_tail(&sas_dev->list, 3420 &adapter->dev_topo.sas_dev_init_list); 3421 leapraid_check_boot_dev(adapter, sas_dev, 0); 3422 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 3423 } else { 3424 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 3425 leapraid_sdev_get(sas_dev); 3426 list_add_tail(&sas_dev->list, &adapter->dev_topo.sas_dev_list); 3427 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 3428 leapraid_report_sdev_directly(adapter, sas_dev); 3429 } 3430 leapraid_sdev_put(sas_dev); 3431 } 3432 3433 static void leapraid_remove_device(struct leapraid_adapter *adapter, 3434 struct leapraid_sas_dev *sas_dev) 3435 { 3436 struct leapraid_starget_priv *starget_priv; 3437 3438 leapraid_clear_cached_boot_dev(adapter, sas_dev, 0); 3439 if (sas_dev->led_on) { 3440 leapraid_set_led(adapter, sas_dev, false); 3441 sas_dev->led_on = 0; 3442 } 3443 3444 if (sas_dev->starget && sas_dev->starget->hostdata) { 3445 starget_priv = sas_dev->starget->hostdata; 3446 starget_priv->deleted = 1; 3447 leapraid_ublk_io_dev(adapter, 3448 sas_dev->sas_addr, sas_dev->card_port); 3449 starget_priv->hdl = LEAPRAID_INVALID_DEV_HANDLE; 3450 } 3451 3452 leapraid_transport_port_remove(adapter, 3453 sas_dev->sas_addr, 3454 sas_dev->parent_sas_addr, 3455 sas_dev->card_port); 3456 3457 dev_info(&adapter->pdev->dev, 3458 "remove dev: hdl=0x%04x, SAS addr=0x%016llx\n", 3459 sas_dev->hdl, (unsigned long long)sas_dev->sas_addr); 3460 } 3461 3462 static struct leapraid_vphy *leapraid_alloc_vphy( 3463 struct leapraid_adapter *adapter, 3464 u8 port_id, u8 phy_num) 3465 { 3466 struct leapraid_card_port *port; 3467 struct leapraid_vphy *vphy; 3468 3469 port = leapraid_get_port_by_id(adapter, port_id, false); 3470 if (!port) 3471 return NULL; 3472 3473 vphy = leapraid_get_vphy_by_phy(port, phy_num); 3474 if (vphy) 3475 return vphy; 3476 vphy = kzalloc_obj(*vphy); 3477 if (!vphy) 3478 return NULL; 3479 3480 if (!port->vphys_mask) 3481 INIT_LIST_HEAD(&port->vphys_list); 3482 3483 port->vphys_mask |= BIT(phy_num); 3484 vphy->phy_mask |= BIT(phy_num); 3485 list_add_tail(&vphy->list, &port->vphys_list); 3486 return vphy; 3487 } 3488 3489 static int leapraid_add_port_to_card_port_list( 3490 struct leapraid_adapter *adapter, 3491 u8 port_id, bool refresh) 3492 { 3493 struct leapraid_card_port *card_port; 3494 3495 card_port = leapraid_get_port_by_id(adapter, port_id, false); 3496 if (card_port) 3497 return 0; 3498 card_port = kzalloc_obj(*card_port); 3499 if (!card_port) 3500 return -ENOMEM; 3501 3502 card_port->port_id = port_id; 3503 dev_dbg(&adapter->pdev->dev, 3504 "port: %d is added to card_port list\n", 3505 card_port->port_id); 3506 3507 if (refresh && adapter->access_ctrl.shost_recovering) 3508 card_port->flg = LEAPRAID_CARD_PORT_FLG_NEW; 3509 list_add_tail(&card_port->list, &adapter->dev_topo.card_port_list); 3510 return 0; 3511 } 3512 3513 static int leapraid_add_card_phy(struct leapraid_adapter *adapter, 3514 struct leapraid_sas_io_unit_p0 *iou, 3515 int i) 3516 { 3517 struct leapraid_sas_phy_p0 phy_pg0; 3518 union cfg_param_1 cfgp1 = {0}; 3519 union cfg_param_2 cfgp2 = {0}; 3520 struct leapraid_topo_node *card = &adapter->dev_topo.card; 3521 u8 port_id; 3522 3523 cfgp1.phy_number = i; 3524 3525 if (leapraid_op_config_page(adapter, &phy_pg0, 3526 cfgp1, cfgp2, GET_PHY_PG0)) 3527 return -EINVAL; 3528 3529 port_id = iou->phy_info[i].port; 3530 3531 if (leapraid_add_port_to_card_port_list(adapter, port_id, false)) 3532 return -EINVAL; 3533 3534 if ((le32_to_cpu(phy_pg0.phy_info) & 3535 LEAPRAID_SAS_PHYINFO_VPHY) && 3536 ((phy_pg0.neg_link_rate >> 3537 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT) >= 3538 LEAPRAID_SAS_NEG_LINK_RATE_1_5)) { 3539 if (!leapraid_alloc_vphy(adapter, port_id, i)) 3540 return -ENOMEM; 3541 3542 card->card_phy[i].vphy = 1; 3543 } 3544 3545 card->card_phy[i].hdl = card->hdl; 3546 card->card_phy[i].phy_id = i; 3547 card->card_phy[i].card_port = 3548 leapraid_get_port_by_id(adapter, port_id, false); 3549 3550 leapraid_transport_add_card_phy(adapter, 3551 &card->card_phy[i], 3552 &phy_pg0, 3553 card->parent_dev); 3554 3555 return 0; 3556 } 3557 3558 static int leapraid_refresh_card_phy(struct leapraid_adapter *adapter, 3559 struct leapraid_sas_io_unit_p0 *iou, 3560 int i) 3561 { 3562 struct leapraid_topo_node *card = &adapter->dev_topo.card; 3563 struct leapraid_sas_phy_p0 phy_pg0; 3564 union cfg_param_1 cfgp1 = {0}; 3565 union cfg_param_2 cfgp2 = {0}; 3566 u16 attached_hdl; 3567 u32 dev_info; 3568 u8 link_rate; 3569 u8 port_id; 3570 3571 link_rate = iou->phy_info[i].neg_link_rate >> 3572 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT; 3573 port_id = iou->phy_info[i].port; 3574 if (leapraid_add_port_to_card_port_list(adapter, port_id, true)) 3575 return -EINVAL; 3576 3577 dev_info = le32_to_cpu(iou->phy_info[i].controller_phy_dev_info); 3578 if (dev_info & LEAPRAID_DEVTYP_SEP && 3579 link_rate >= LEAPRAID_SAS_NEG_LINK_RATE_1_5) { 3580 cfgp1.phy_number = i; 3581 3582 if (leapraid_op_config_page(adapter, &phy_pg0, 3583 cfgp1, cfgp2, GET_PHY_PG0)) 3584 return 0; 3585 3586 if (le32_to_cpu(phy_pg0.phy_info) & 3587 LEAPRAID_SAS_PHYINFO_VPHY) { 3588 if (!leapraid_alloc_vphy(adapter, port_id, i)) 3589 return -ENOMEM; 3590 card->card_phy[i].vphy = 1; 3591 } 3592 } 3593 3594 card->card_phy[i].hdl = card->hdl; 3595 3596 attached_hdl = le16_to_cpu(iou->phy_info[i].attached_dev_hdl); 3597 if (attached_hdl && link_rate < LEAPRAID_SAS_NEG_LINK_RATE_1_5) 3598 link_rate = LEAPRAID_SAS_NEG_LINK_RATE_1_5; 3599 3600 card->card_phy[i].card_port = 3601 leapraid_get_port_by_id(adapter, port_id, false); 3602 3603 if (!card->card_phy[i].phy) { 3604 cfgp1.phy_number = i; 3605 if (leapraid_op_config_page(adapter, &phy_pg0, 3606 cfgp1, cfgp2, GET_PHY_PG0)) 3607 return 0; 3608 3609 card->card_phy[i].phy_id = i; 3610 3611 leapraid_transport_add_card_phy(adapter, 3612 &card->card_phy[i], 3613 &phy_pg0, 3614 card->parent_dev); 3615 return 0; 3616 } 3617 3618 leapraid_transport_update_links(adapter, 3619 card->sas_address, 3620 attached_hdl, 3621 i, 3622 link_rate, 3623 card->card_phy[i].card_port); 3624 3625 return 0; 3626 } 3627 3628 static void leapraid_sas_host_add(struct leapraid_adapter *adapter, 3629 bool refresh) 3630 { 3631 union cfg_param_1 cfgp1 = {0}; 3632 union cfg_param_2 cfgp2 = {0}; 3633 struct leapraid_sas_dev_p0 sas_dev_pg0; 3634 struct leapraid_enc_p0 enc_pg0; 3635 struct leapraid_sas_io_unit_p0 *sas_iou_pg0; 3636 u16 sas_iou_pg0_sz; 3637 u8 phys_num; 3638 int i; 3639 int rc; 3640 3641 if (!refresh) { 3642 if (leapraid_get_adapter_phys(adapter, &phys_num) || !phys_num) 3643 return; 3644 3645 adapter->dev_topo.card.card_phy = 3646 kzalloc_objs(struct leapraid_card_phy, phys_num); 3647 if (!adapter->dev_topo.card.card_phy) 3648 return; 3649 3650 adapter->dev_topo.card.phys_num = phys_num; 3651 } 3652 3653 sas_iou_pg0_sz = 3654 offsetof(struct leapraid_sas_io_unit_p0, phy_info) + 3655 (adapter->dev_topo.card.phys_num * 3656 sizeof(struct leapraid_sas_io_unit0_phy_info)); 3657 sas_iou_pg0 = kzalloc(sas_iou_pg0_sz, GFP_KERNEL); 3658 if (!sas_iou_pg0) 3659 return; 3660 3661 if (leapraid_get_sas_io_unit_page0(adapter, 3662 sas_iou_pg0, 3663 sas_iou_pg0_sz)) 3664 goto out_free; 3665 3666 adapter->dev_topo.card.parent_dev = &adapter->shost->shost_gendev; 3667 adapter->dev_topo.card.hdl = 3668 le16_to_cpu(sas_iou_pg0->phy_info[0].controller_dev_hdl); 3669 for (i = 0; i < adapter->dev_topo.card.phys_num; i++) { 3670 if (!refresh) /* add */ 3671 rc = leapraid_add_card_phy(adapter, sas_iou_pg0, i); 3672 else /* refresh */ 3673 rc = leapraid_refresh_card_phy(adapter, 3674 sas_iou_pg0, 3675 i); 3676 if (rc) 3677 goto out_free; 3678 } 3679 3680 if (!refresh) { 3681 cfgp1.form = LEAPRAID_SAS_DEV_CFG_PGAD_HDL; 3682 cfgp2.handle = adapter->dev_topo.card.hdl; 3683 if (leapraid_op_config_page(adapter, &sas_dev_pg0, cfgp1, 3684 cfgp2, GET_SAS_DEVICE_PG0)) 3685 goto out_free; 3686 3687 adapter->dev_topo.card.enc_hdl = 3688 le16_to_cpu(sas_dev_pg0.enc_hdl); 3689 adapter->dev_topo.card.sas_address = 3690 le64_to_cpu(sas_dev_pg0.sas_address); 3691 dev_info(&adapter->pdev->dev, 3692 "add host: hdl=0x%04x, SAS addr=0x%016llx, phy=%d\n", 3693 adapter->dev_topo.card.hdl, 3694 (unsigned long long)adapter->dev_topo.card.sas_address, 3695 adapter->dev_topo.card.phys_num); 3696 3697 if (adapter->dev_topo.card.enc_hdl) { 3698 cfgp1.form = LEAPRAID_SAS_ENC_CFG_PGAD_HDL; 3699 cfgp2.handle = adapter->dev_topo.card.enc_hdl; 3700 if (!(leapraid_op_config_page(adapter, &enc_pg0, 3701 cfgp1, cfgp2, 3702 GET_SAS_ENCLOSURE_PG0))) 3703 adapter->dev_topo.card.enc_lid = 3704 le64_to_cpu(enc_pg0.enc_lid); 3705 } 3706 } 3707 out_free: 3708 kfree(sas_iou_pg0); 3709 } 3710 3711 static int leapraid_internal_exp_add(struct leapraid_adapter *adapter, 3712 struct leapraid_exp_p0 *exp_pg0, 3713 union cfg_param_1 *cfgp1, 3714 union cfg_param_2 *cfgp2, 3715 u16 hdl) 3716 { 3717 struct leapraid_topo_node *topo_node_exp; 3718 struct leapraid_sas_port *sas_port = NULL; 3719 struct leapraid_enc_node *enc_dev; 3720 struct leapraid_exp_p1 exp_pg1; 3721 int ret; 3722 int rc; 3723 unsigned long flags; 3724 u8 port_id; 3725 u16 parent_handle; 3726 u64 sas_addr_parent; 3727 int i; 3728 3729 port_id = exp_pg0->physical_port; 3730 parent_handle = le16_to_cpu(exp_pg0->parent_dev_hdl); 3731 3732 rc = leapraid_get_sas_address(adapter, 3733 parent_handle, &sas_addr_parent); 3734 if (rc) 3735 return rc; 3736 topo_node_exp = kzalloc_obj(*topo_node_exp); 3737 if (!topo_node_exp) 3738 return -ENOMEM; 3739 3740 topo_node_exp->hdl = hdl; 3741 topo_node_exp->phys_num = exp_pg0->phy_num; 3742 topo_node_exp->sas_address_parent = sas_addr_parent; 3743 topo_node_exp->sas_address = le64_to_cpu(exp_pg0->sas_address); 3744 topo_node_exp->card_port = 3745 leapraid_get_port_by_id(adapter, port_id, false); 3746 if (!topo_node_exp->card_port) { 3747 rc = -EPERM; 3748 goto out_fail; 3749 } 3750 3751 dev_info(&adapter->pdev->dev, 3752 "add exp: saddr=0x%016llx, hdl=0x%04x, phdl=0x%04x, phy=%d\n", 3753 (unsigned long long)topo_node_exp->sas_address, 3754 hdl, parent_handle, 3755 topo_node_exp->phys_num); 3756 if (!topo_node_exp->phys_num) { 3757 dev_err(&adapter->pdev->dev, 3758 "%s: Invalid PHY num from exp_pg0\n", __func__); 3759 rc = -EPERM; 3760 goto out_fail; 3761 } 3762 3763 topo_node_exp->card_phy = 3764 kzalloc_objs(struct leapraid_card_phy, topo_node_exp->phys_num); 3765 if (!topo_node_exp->card_phy) { 3766 dev_err(&adapter->pdev->dev, 3767 "%s: Failed to alloc expander phy array, count=%u\n", 3768 __func__, topo_node_exp->phys_num); 3769 rc = -EPERM; 3770 goto out_fail; 3771 } 3772 3773 INIT_LIST_HEAD(&topo_node_exp->sas_port_list); 3774 sas_port = leapraid_transport_port_add(adapter, hdl, sas_addr_parent, 3775 topo_node_exp->card_port); 3776 if (!sas_port) { 3777 rc = -EPERM; 3778 goto out_fail; 3779 } 3780 3781 topo_node_exp->parent_dev = &sas_port->rphy->dev; 3782 topo_node_exp->rphy = sas_port->rphy; 3783 for (i = 0; i < topo_node_exp->phys_num; i++) { 3784 cfgp1->phy_number = i; 3785 cfgp2->handle = hdl; 3786 if (leapraid_op_config_page(adapter, &exp_pg1, *cfgp1, *cfgp2, 3787 GET_SAS_EXPANDER_PG1)) { 3788 dev_err(&adapter->pdev->dev, 3789 "%s: Failed to get exp_pg1, phy=%d\n", 3790 __func__, i); 3791 rc = -EPERM; 3792 goto out_fail; 3793 } 3794 3795 topo_node_exp->card_phy[i].hdl = hdl; 3796 topo_node_exp->card_phy[i].phy_id = i; 3797 topo_node_exp->card_phy[i].card_port = 3798 leapraid_get_port_by_id(adapter, port_id, false); 3799 ret = leapraid_transport_add_exp_phy( 3800 adapter, 3801 &topo_node_exp->card_phy[i], 3802 &exp_pg1, 3803 topo_node_exp->parent_dev); 3804 if (ret) { 3805 rc = -EPERM; 3806 goto out_fail; 3807 } 3808 } 3809 3810 if (topo_node_exp->enc_hdl) { 3811 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags); 3812 enc_dev = leapraid_enc_find_by_hdl(adapter, 3813 topo_node_exp->enc_hdl); 3814 if (enc_dev) 3815 topo_node_exp->enc_lid = 3816 le64_to_cpu(enc_dev->pg0.enc_lid); 3817 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags); 3818 } 3819 3820 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags); 3821 list_add_tail(&topo_node_exp->list, &adapter->dev_topo.exp_list); 3822 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags); 3823 return 0; 3824 3825 out_fail: 3826 if (sas_port) 3827 leapraid_transport_port_remove(adapter, 3828 topo_node_exp->sas_address, 3829 sas_addr_parent, 3830 topo_node_exp->card_port); 3831 kfree(topo_node_exp->card_phy); 3832 kfree(topo_node_exp); 3833 return rc; 3834 } 3835 3836 static int leapraid_exp_add(struct leapraid_adapter *adapter, u16 hdl) 3837 { 3838 union cfg_param_1 cfgp1 = {0}; 3839 union cfg_param_2 cfgp2 = {0}; 3840 struct leapraid_topo_node *topo_node_exp; 3841 struct leapraid_exp_p0 exp_pg0; 3842 u16 parent_handle; 3843 u64 sas_addr, sas_addr_parent; 3844 unsigned long flags; 3845 u8 port_id; 3846 int rc; 3847 3848 if (!hdl) { 3849 dev_warn(&adapter->pdev->dev, "%s: Invalid hdl\n", __func__); 3850 return -EPERM; 3851 } 3852 3853 if (adapter->access_ctrl.shost_recovering || 3854 adapter->access_ctrl.pcie_recovering) { 3855 dev_warn(&adapter->pdev->dev, 3856 "%s: Failed, shost_recovering=%d pcie_recovering=%d\n", 3857 __func__, adapter->access_ctrl.shost_recovering, 3858 adapter->access_ctrl.pcie_recovering); 3859 return -EPERM; 3860 } 3861 3862 cfgp1.form = LEAPRAID_SAS_EXP_CFD_PGAD_HDL; 3863 cfgp2.handle = hdl; 3864 if (leapraid_op_config_page(adapter, &exp_pg0, cfgp1, cfgp2, 3865 GET_SAS_EXPANDER_PG0)) 3866 return -EPERM; 3867 3868 parent_handle = le16_to_cpu(exp_pg0.parent_dev_hdl); 3869 if (leapraid_get_sas_address(adapter, parent_handle, &sas_addr_parent)) 3870 return -EPERM; 3871 3872 port_id = exp_pg0.physical_port; 3873 if (sas_addr_parent != adapter->dev_topo.card.sas_address) { 3874 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags); 3875 topo_node_exp = 3876 leapraid_exp_find_by_sas_address( 3877 adapter, 3878 sas_addr_parent, 3879 leapraid_get_port_by_id(adapter, 3880 port_id, 3881 false)); 3882 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, 3883 flags); 3884 if (!topo_node_exp) { 3885 rc = leapraid_exp_add(adapter, parent_handle); 3886 if (rc != 0) 3887 return rc; 3888 } 3889 } 3890 3891 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags); 3892 sas_addr = le64_to_cpu(exp_pg0.sas_address); 3893 topo_node_exp = 3894 leapraid_exp_find_by_sas_address( 3895 adapter, 3896 sas_addr, 3897 leapraid_get_port_by_id(adapter, port_id, false)); 3898 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags); 3899 3900 if (topo_node_exp) 3901 return 0; 3902 3903 return leapraid_internal_exp_add(adapter, &exp_pg0, &cfgp1, 3904 &cfgp2, hdl); 3905 } 3906 3907 static void leapraid_exp_node_rm(struct leapraid_adapter *adapter, 3908 struct leapraid_topo_node *topo_node_exp) 3909 { 3910 struct leapraid_sas_port *sas_port, *sas_port_next; 3911 unsigned long flags; 3912 int port_id; 3913 3914 list_for_each_entry_safe(sas_port, sas_port_next, 3915 &topo_node_exp->sas_port_list, 3916 port_list) { 3917 if (adapter->access_ctrl.shost_recovering) 3918 return; 3919 3920 switch (sas_port->remote_identify.device_type) { 3921 case SAS_END_DEVICE: 3922 leapraid_sas_dev_remove_by_sas_address( 3923 adapter, 3924 sas_port->remote_identify.sas_address, 3925 sas_port->card_port); 3926 break; 3927 case SAS_EDGE_EXPANDER_DEVICE: 3928 case SAS_FANOUT_EXPANDER_DEVICE: 3929 leapraid_exp_rm( 3930 adapter, 3931 sas_port->remote_identify.sas_address, 3932 sas_port->card_port); 3933 break; 3934 default: 3935 break; 3936 } 3937 } 3938 3939 port_id = topo_node_exp->card_port->port_id; 3940 leapraid_transport_port_remove(adapter, topo_node_exp->sas_address, 3941 topo_node_exp->sas_address_parent, 3942 topo_node_exp->card_port); 3943 dev_info(&adapter->pdev->dev, 3944 "removing exp: port=%d, SAS addr=0x%016llx, hdl=0x%04x\n", 3945 port_id, (unsigned long long)topo_node_exp->sas_address, 3946 topo_node_exp->hdl); 3947 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags); 3948 list_del(&topo_node_exp->list); 3949 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags); 3950 kfree(topo_node_exp->card_phy); 3951 kfree(topo_node_exp); 3952 } 3953 3954 void leapraid_exp_rm(struct leapraid_adapter *adapter, u64 sas_addr, 3955 struct leapraid_card_port *port) 3956 { 3957 struct leapraid_topo_node *topo_node_exp; 3958 unsigned long flags; 3959 3960 if (adapter->access_ctrl.shost_recovering) 3961 return; 3962 3963 if (!port) 3964 return; 3965 3966 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags); 3967 topo_node_exp = leapraid_exp_find_by_sas_address(adapter, 3968 sas_addr, 3969 port); 3970 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags); 3971 3972 if (topo_node_exp) 3973 leapraid_exp_node_rm(adapter, topo_node_exp); 3974 } 3975 3976 static void leapraid_internal_sas_topo_chg_evt( 3977 struct leapraid_adapter *adapter, 3978 struct leapraid_card_port *card_port, 3979 struct leapraid_topo_node *topo_node_exp, 3980 struct leapraid_fw_evt_work *fw_evt, 3981 u64 sas_addr, u8 max_phys) 3982 { 3983 struct leapraid_evt_data_sas_topo_change_list *evt_data; 3984 u8 phy_number; 3985 u8 link_rate; 3986 u16 reason_code; 3987 u16 hdl; 3988 int i; 3989 3990 evt_data = fw_evt->evt_data; 3991 for (i = 0; i < evt_data->entry_num; i++) { 3992 if (fw_evt->ignore) 3993 return; 3994 3995 if (adapter->access_ctrl.host_removing || 3996 adapter->access_ctrl.pcie_recovering) 3997 return; 3998 3999 phy_number = evt_data->start_phy_num + i; 4000 if (phy_number >= max_phys) 4001 continue; 4002 4003 reason_code = evt_data->phy[i].phy_status & 4004 LEAPRAID_EVT_SAS_TOPO_RC_MASK; 4005 4006 hdl = le16_to_cpu(evt_data->phy[i].attached_dev_hdl); 4007 if (!hdl || 4008 hdl > adapter->adapter_attr.features.max_dev_handle) { 4009 dev_warn(&adapter->pdev->dev, 4010 "%s: Invalid device handle\n", __func__); 4011 continue; 4012 } 4013 link_rate = evt_data->phy[i].link_rate >> 4014 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT; 4015 switch (reason_code) { 4016 case LEAPRAID_EVT_SAS_TOPO_RC_TARG_ADDED: 4017 if (adapter->access_ctrl.shost_recovering) 4018 break; 4019 leapraid_transport_update_links(adapter, sas_addr, 4020 hdl, phy_number, 4021 link_rate, card_port); 4022 if (link_rate < LEAPRAID_SAS_NEG_LINK_RATE_1_5) 4023 break; 4024 leapraid_add_dev(adapter, hdl); 4025 break; 4026 case LEAPRAID_EVT_SAS_TOPO_RC_TARG_NOT_RESPONDING: 4027 leapraid_sas_dev_remove_by_hdl(adapter, hdl); 4028 break; 4029 } 4030 } 4031 4032 if (evt_data->exp_status == LEAPRAID_EVT_SAS_TOPO_ES_NOT_RESPONDING && 4033 topo_node_exp) 4034 leapraid_exp_rm(adapter, sas_addr, card_port); 4035 } 4036 4037 static void leapraid_sas_topo_chg_evt(struct leapraid_adapter *adapter, 4038 struct leapraid_fw_evt_work *fw_evt) 4039 { 4040 struct leapraid_topo_node *topo_node_exp; 4041 struct leapraid_card_port *card_port; 4042 struct leapraid_evt_data_sas_topo_change_list *evt_data; 4043 u16 phdl; 4044 u8 max_phys; 4045 u64 sas_addr; 4046 unsigned long flags; 4047 4048 if (adapter->access_ctrl.shost_recovering || 4049 adapter->access_ctrl.host_removing || 4050 adapter->access_ctrl.pcie_recovering) 4051 return; 4052 4053 evt_data = fw_evt->evt_data; 4054 leapraid_sas_host_add(adapter, adapter->dev_topo.card.phys_num > 0); 4055 4056 if (fw_evt->ignore) 4057 return; 4058 4059 phdl = le16_to_cpu(evt_data->exp_dev_hdl); 4060 card_port = leapraid_get_port_by_id(adapter, 4061 evt_data->physical_port, 4062 false); 4063 if (evt_data->exp_status == LEAPRAID_EVT_SAS_TOPO_ES_ADDED && 4064 leapraid_exp_add(adapter, phdl) != 0) 4065 return; 4066 4067 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags); 4068 topo_node_exp = leapraid_exp_find_by_hdl(adapter, phdl); 4069 if (topo_node_exp) { 4070 sas_addr = topo_node_exp->sas_address; 4071 max_phys = topo_node_exp->phys_num; 4072 card_port = topo_node_exp->card_port; 4073 } else if (phdl < adapter->dev_topo.card.phys_num) { 4074 sas_addr = adapter->dev_topo.card.sas_address; 4075 max_phys = adapter->dev_topo.card.phys_num; 4076 } else { 4077 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, 4078 flags); 4079 return; 4080 } 4081 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags); 4082 4083 leapraid_internal_sas_topo_chg_evt(adapter, card_port, 4084 topo_node_exp, fw_evt, 4085 sas_addr, max_phys); 4086 } 4087 4088 static void leapraid_reprobe_lun(struct scsi_device *sdev, void *no_uld_attach) 4089 { 4090 sdev->no_uld_attach = no_uld_attach ? 1 : 0; 4091 sdev_printk(KERN_INFO, sdev, 4092 "%s RAID component to upper layer\n", 4093 sdev->no_uld_attach ? "hide" : "expose"); 4094 WARN_ON(scsi_device_reprobe(sdev)); 4095 } 4096 4097 static void leapraid_sas_pd_add( 4098 struct leapraid_adapter *adapter, 4099 struct leapraid_evt_data_ir_change *evt_data) 4100 { 4101 union cfg_param_1 cfgp1 = {0}; 4102 union cfg_param_2 cfgp2 = {0}; 4103 struct leapraid_sas_dev_p0 sas_dev_p0; 4104 struct leapraid_sas_dev *sas_dev; 4105 u64 sas_address; 4106 u16 parent_hdl; 4107 u16 hdl; 4108 4109 hdl = le16_to_cpu(evt_data->phys_disk_dev_hdl); 4110 if (!hdl || hdl > adapter->adapter_attr.features.max_dev_handle) { 4111 dev_warn(&adapter->pdev->dev, 4112 "%s: Invalid device handle\n", __func__); 4113 return; 4114 } 4115 4116 set_bit(hdl, adapter->dev_topo.pd_hdls); 4117 sas_dev = leapraid_get_sas_dev_by_hdl(adapter, hdl); 4118 if (sas_dev) { 4119 leapraid_sdev_put(sas_dev); 4120 dev_warn(&adapter->pdev->dev, 4121 "Dev handle 0x%x already exists\n", hdl); 4122 return; 4123 } 4124 4125 cfgp1.form = LEAPRAID_SAS_DEV_CFG_PGAD_HDL; 4126 cfgp2.handle = hdl; 4127 if (leapraid_op_config_page(adapter, &sas_dev_p0, cfgp1, cfgp2, 4128 GET_SAS_DEVICE_PG0)) { 4129 dev_warn(&adapter->pdev->dev, "Failed to read dev page0\n"); 4130 return; 4131 } 4132 4133 parent_hdl = le16_to_cpu(sas_dev_p0.parent_dev_hdl); 4134 if (!leapraid_get_sas_address(adapter, parent_hdl, &sas_address)) 4135 leapraid_transport_update_links(adapter, sas_address, hdl, 4136 sas_dev_p0.phy_num, 4137 LEAPRAID_SAS_NEG_LINK_RATE_1_5, 4138 leapraid_get_port_by_id(adapter, 4139 sas_dev_p0.physical_port, 4140 false)); 4141 leapraid_add_dev(adapter, hdl); 4142 } 4143 4144 static void leapraid_sas_pd_delete( 4145 struct leapraid_adapter *adapter, 4146 struct leapraid_evt_data_ir_change *evt_data) 4147 { 4148 u16 hdl; 4149 4150 hdl = le16_to_cpu(evt_data->phys_disk_dev_hdl); 4151 leapraid_sas_dev_remove_by_hdl(adapter, hdl); 4152 } 4153 4154 static void leapraid_sas_pd_hide( 4155 struct leapraid_adapter *adapter, 4156 struct leapraid_evt_data_ir_change *evt_data) 4157 { 4158 struct leapraid_starget_priv *starget_priv; 4159 struct scsi_target *starget = NULL; 4160 struct leapraid_sas_dev *sas_dev; 4161 unsigned long flags; 4162 u64 volume_wwid = 0; 4163 u16 volume_hdl; 4164 u16 hdl; 4165 4166 hdl = le16_to_cpu(evt_data->phys_disk_dev_hdl); 4167 if (!hdl || hdl > adapter->adapter_attr.features.max_dev_handle) { 4168 dev_warn(&adapter->pdev->dev, 4169 "%s: Invalid device handle\n", __func__); 4170 return; 4171 } 4172 leapraid_cfg_get_volume_hdl(adapter, hdl, &volume_hdl); 4173 if (volume_hdl) 4174 leapraid_cfg_get_volume_wwid(adapter, 4175 volume_hdl, 4176 &volume_wwid); 4177 4178 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 4179 sas_dev = leapraid_hold_lock_get_sas_dev_by_hdl(adapter, hdl); 4180 if (!sas_dev) { 4181 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 4182 return; 4183 } 4184 4185 set_bit(hdl, adapter->dev_topo.pd_hdls); 4186 if (sas_dev->starget && sas_dev->starget->hostdata) { 4187 starget = sas_dev->starget; 4188 starget_priv = starget->hostdata; 4189 starget_priv->flg |= LEAPRAID_TGT_FLG_RAID_MEMBER; 4190 sas_dev->volume_hdl = volume_hdl; 4191 sas_dev->volume_wwid = volume_wwid; 4192 } 4193 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 4194 if (starget) { 4195 starget_for_each_device(starget, 4196 (void *)LEAPRAID_NO_ULD_ATTACH_FLAG, 4197 leapraid_reprobe_lun); 4198 } 4199 4200 leapraid_sdev_put(sas_dev); 4201 } 4202 4203 static void leapraid_sas_pd_expose( 4204 struct leapraid_adapter *adapter, 4205 struct leapraid_evt_data_ir_change *evt_data) 4206 { 4207 struct leapraid_starget_priv *starget_priv; 4208 struct scsi_target *starget = NULL; 4209 struct leapraid_sas_dev *sas_dev; 4210 unsigned long flags; 4211 u16 hdl; 4212 4213 hdl = le16_to_cpu(evt_data->phys_disk_dev_hdl); 4214 if (!hdl || hdl > adapter->adapter_attr.features.max_dev_handle) { 4215 dev_warn(&adapter->pdev->dev, 4216 "%s: Invalid device handle\n", __func__); 4217 return; 4218 } 4219 4220 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 4221 sas_dev = leapraid_hold_lock_get_sas_dev_by_hdl(adapter, hdl); 4222 if (!sas_dev) { 4223 dev_warn(&adapter->pdev->dev, 4224 "%s:%d: sas_dev not found, hdl=0x%x\n", 4225 __func__, __LINE__, hdl); 4226 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 4227 return; 4228 } 4229 4230 sas_dev->volume_hdl = 0; 4231 sas_dev->volume_wwid = 0; 4232 clear_bit(hdl, adapter->dev_topo.pd_hdls); 4233 if (sas_dev->starget && sas_dev->starget->hostdata) { 4234 starget = sas_dev->starget; 4235 starget_priv = starget->hostdata; 4236 starget_priv->flg &= ~LEAPRAID_TGT_FLG_RAID_MEMBER; 4237 sas_dev->led_on = 0; 4238 } 4239 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 4240 4241 if (starget) { 4242 starget_for_each_device(starget, 4243 NULL, 4244 leapraid_reprobe_lun); 4245 } 4246 4247 leapraid_sdev_put(sas_dev); 4248 } 4249 4250 static void leapraid_sas_vol_visibility( 4251 struct leapraid_adapter *adapter, 4252 struct leapraid_evt_data_ir_change *evt_data) 4253 { 4254 struct leapraid_raid_volume *raid_volume; 4255 struct scsi_device *sdev; 4256 bool reprobe_flg = false; 4257 bool sdev_held = false; 4258 unsigned long flags; 4259 u16 hdl; 4260 u8 rc; 4261 4262 hdl = le16_to_cpu(evt_data->vol_dev_hdl); 4263 rc = evt_data->reason_code; 4264 raid_volume = leapraid_raid_volume_find_by_hdl(adapter, hdl); 4265 if (!raid_volume) { 4266 dev_warn(&adapter->pdev->dev, 4267 "%s:%d: Volume handle 0x%x not found\n", 4268 __func__, __LINE__, hdl); 4269 return; 4270 } 4271 4272 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags); 4273 sdev = raid_volume->sdev; 4274 if (!sdev) { 4275 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, 4276 flags); 4277 leapraid_raid_volume_put(raid_volume); 4278 dev_warn(&adapter->pdev->dev, 4279 "%s:%d: Volume handle 0x%x has no sdev\n", 4280 __func__, __LINE__, hdl); 4281 return; 4282 } 4283 4284 if (sdev->no_uld_attach && 4285 rc == LEAPRAID_EVT_IR_RC_VOLUME_UNHIDE) { 4286 sdev->no_uld_attach = 0; 4287 reprobe_flg = true; 4288 } else if (!sdev->no_uld_attach && 4289 rc == LEAPRAID_EVT_IR_RC_VOLUME_HIDE) { 4290 sdev->no_uld_attach = 1; 4291 reprobe_flg = true; 4292 } 4293 4294 if (reprobe_flg && !scsi_device_get(sdev)) 4295 sdev_held = true; 4296 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags); 4297 leapraid_raid_volume_put(raid_volume); 4298 4299 if (!reprobe_flg) { 4300 dev_warn(&adapter->pdev->dev, 4301 "%s:rc(0x%x): Request matches, skipping\n", 4302 __func__, rc); 4303 return; 4304 } 4305 4306 if (!sdev_held) { 4307 dev_warn(&adapter->pdev->dev, 4308 "%s: Failed to hold sdev for reprobe, hdl=0x%x\n", 4309 __func__, hdl); 4310 return; 4311 } 4312 4313 if (sdev->no_uld_attach) 4314 sdev_printk(KERN_INFO, sdev, "hide vol\n"); 4315 else 4316 sdev_printk(KERN_INFO, sdev, "unhide vol\n"); 4317 4318 WARN_ON(scsi_device_reprobe(sdev)); 4319 scsi_device_put(sdev); 4320 } 4321 4322 static void leapraid_sas_volume_add( 4323 struct leapraid_adapter *adapter, 4324 struct leapraid_evt_data_ir_change *evt_data) 4325 { 4326 struct leapraid_raid_volume *raid_volume; 4327 unsigned long flags; 4328 u64 wwid; 4329 u16 hdl; 4330 4331 hdl = le16_to_cpu(evt_data->vol_dev_hdl); 4332 4333 if (leapraid_cfg_get_volume_wwid(adapter, hdl, &wwid)) { 4334 dev_warn(&adapter->pdev->dev, "Failed to read volume page1\n"); 4335 return; 4336 } 4337 4338 if (!wwid) { 4339 dev_warn(&adapter->pdev->dev, "Invalid WWID(handle=0x%x)\n", 4340 hdl); 4341 return; 4342 } 4343 4344 raid_volume = leapraid_raid_volume_find_by_wwid(adapter, wwid); 4345 if (raid_volume) { 4346 dev_warn(&adapter->pdev->dev, 4347 "Volume handle 0x%x already exists\n", hdl); 4348 leapraid_raid_volume_put(raid_volume); 4349 return; 4350 } 4351 4352 raid_volume = kzalloc_obj(*raid_volume); 4353 if (!raid_volume) 4354 return; 4355 4356 INIT_LIST_HEAD(&raid_volume->list); 4357 kref_init(&raid_volume->refcnt); 4358 raid_volume->id = adapter->dev_topo.sas_id++; 4359 raid_volume->channel = RAID_CHANNEL; 4360 raid_volume->hdl = hdl; 4361 raid_volume->wwid = wwid; 4362 leapraid_raid_volume_add(adapter, raid_volume); 4363 if (!adapter->scan_dev_desc.wait_scan_dev_done) { 4364 if (scsi_add_device(adapter->shost, RAID_CHANNEL, 4365 raid_volume->id, 0)) 4366 leapraid_raid_volume_remove(adapter, raid_volume); 4367 dev_info(&adapter->pdev->dev, 4368 "add RAID volume: hdl=0x%x, wwid=0x%llx\n", hdl, wwid); 4369 } else { 4370 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags); 4371 leapraid_check_boot_dev(adapter, raid_volume, RAID_CHANNEL); 4372 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, 4373 flags); 4374 } 4375 leapraid_raid_volume_put(raid_volume); 4376 } 4377 4378 static void leapraid_sas_volume_delete_by_ptr( 4379 struct leapraid_adapter *adapter, 4380 struct leapraid_raid_volume *raid_volume) 4381 { 4382 struct leapraid_starget_priv *starget_priv; 4383 struct scsi_target *starget = NULL; 4384 unsigned long flags; 4385 bool in_list; 4386 4387 if (!raid_volume) 4388 return; 4389 4390 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags); 4391 in_list = !list_empty(&raid_volume->list); 4392 if (in_list && raid_volume->starget) { 4393 starget = raid_volume->starget; 4394 starget_priv = starget->hostdata; 4395 if (starget_priv) 4396 starget_priv->deleted = 1; 4397 } 4398 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags); 4399 4400 if (!in_list) 4401 return; 4402 4403 dev_info(&adapter->pdev->dev, 4404 "delete RAID volume: hdl=0x%x, wwid=0x%llx\n", 4405 raid_volume->hdl, raid_volume->wwid); 4406 leapraid_raid_volume_remove(adapter, raid_volume); 4407 4408 if (starget) 4409 scsi_remove_target(&starget->dev); 4410 } 4411 4412 static void leapraid_sas_volume_delete(struct leapraid_adapter *adapter, 4413 u16 hdl) 4414 { 4415 struct leapraid_raid_volume *raid_volume; 4416 4417 raid_volume = leapraid_raid_volume_find_by_hdl(adapter, hdl); 4418 if (!raid_volume) { 4419 dev_warn(&adapter->pdev->dev, 4420 "%s:%d: Volume handle 0x%x not found\n", 4421 __func__, __LINE__, hdl); 4422 return; 4423 } 4424 4425 leapraid_sas_volume_delete_by_ptr(adapter, raid_volume); 4426 leapraid_raid_volume_put(raid_volume); 4427 } 4428 4429 static void leapraid_sas_ir_chg_evt(struct leapraid_adapter *adapter, 4430 struct leapraid_fw_evt_work *fw_evt) 4431 { 4432 struct leapraid_evt_data_ir_change *evt_data; 4433 4434 evt_data = fw_evt->evt_data; 4435 4436 switch (evt_data->reason_code) { 4437 case LEAPRAID_EVT_IR_RC_VOLUME_ADD: 4438 leapraid_sas_volume_add(adapter, evt_data); 4439 break; 4440 case LEAPRAID_EVT_IR_RC_VOLUME_DELETE: 4441 leapraid_sas_volume_delete(adapter, 4442 le16_to_cpu(evt_data->vol_dev_hdl)); 4443 break; 4444 case LEAPRAID_EVT_IR_RC_PD_HIDDEN_TO_ADD: 4445 leapraid_sas_pd_add(adapter, evt_data); 4446 break; 4447 case LEAPRAID_EVT_IR_RC_PD_UNHIDDEN_TO_DELETE: 4448 leapraid_sas_pd_delete(adapter, evt_data); 4449 break; 4450 case LEAPRAID_EVT_IR_RC_PD_CREATED_TO_HIDE: 4451 leapraid_sas_pd_hide(adapter, evt_data); 4452 break; 4453 case LEAPRAID_EVT_IR_RC_PD_DELETED_TO_EXPOSE: 4454 leapraid_sas_pd_expose(adapter, evt_data); 4455 break; 4456 case LEAPRAID_EVT_IR_RC_VOLUME_HIDE: 4457 case LEAPRAID_EVT_IR_RC_VOLUME_UNHIDE: 4458 leapraid_sas_vol_visibility(adapter, evt_data); 4459 break; 4460 default: 4461 break; 4462 } 4463 } 4464 4465 static void leapraid_sas_enc_dev_stat_add_node( 4466 struct leapraid_adapter *adapter, u16 hdl) 4467 { 4468 union cfg_param_1 cfgp1 = {0}; 4469 union cfg_param_2 cfgp2 = {0}; 4470 struct leapraid_enc_node *enc_node; 4471 struct leapraid_enc_node *enc_exist; 4472 unsigned long flags; 4473 int rc; 4474 4475 enc_node = kzalloc_obj(*enc_node); 4476 if (!enc_node) 4477 return; 4478 4479 cfgp1.form = LEAPRAID_SAS_ENC_CFG_PGAD_HDL; 4480 cfgp2.handle = hdl; 4481 rc = leapraid_op_config_page(adapter, &enc_node->pg0, cfgp1, cfgp2, 4482 GET_SAS_ENCLOSURE_PG0); 4483 if (rc) { 4484 kfree(enc_node); 4485 return; 4486 } 4487 4488 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags); 4489 enc_exist = leapraid_enc_find_by_hdl(adapter, hdl); 4490 if (enc_exist) { 4491 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags); 4492 kfree(enc_node); 4493 return; 4494 } 4495 list_add_tail(&enc_node->list, &adapter->dev_topo.enc_list); 4496 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags); 4497 } 4498 4499 static void leapraid_sas_enc_dev_stat_del_node( 4500 struct leapraid_adapter *adapter, u16 hdl) 4501 { 4502 struct leapraid_enc_node *enc_node; 4503 unsigned long flags; 4504 4505 if (!hdl) 4506 return; 4507 4508 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags); 4509 enc_node = leapraid_enc_find_by_hdl(adapter, hdl); 4510 if (enc_node) 4511 list_del(&enc_node->list); 4512 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags); 4513 4514 kfree(enc_node); 4515 } 4516 4517 static void leapraid_sas_enc_dev_stat_chg_evt( 4518 struct leapraid_adapter *adapter, 4519 struct leapraid_fw_evt_work *fw_evt) 4520 { 4521 struct leapraid_evt_data_sas_enc_dev_status_change *evt_data; 4522 u16 enc_hdl; 4523 4524 if (adapter->access_ctrl.shost_recovering) 4525 return; 4526 4527 evt_data = fw_evt->evt_data; 4528 enc_hdl = le16_to_cpu(evt_data->enc_hdl); 4529 switch (evt_data->reason_code) { 4530 case LEAPRAID_EVT_SAS_ENCL_RC_ADDED: 4531 if (enc_hdl) 4532 leapraid_sas_enc_dev_stat_add_node(adapter, enc_hdl); 4533 break; 4534 case LEAPRAID_EVT_SAS_ENCL_RC_NOT_RESPONDING: 4535 leapraid_sas_enc_dev_stat_del_node(adapter, enc_hdl); 4536 break; 4537 default: 4538 break; 4539 } 4540 } 4541 4542 static void leapraid_remove_unresp_sas_end_dev( 4543 struct leapraid_adapter *adapter) 4544 { 4545 struct leapraid_sas_dev *sas_dev, *sas_dev_next; 4546 unsigned long flags; 4547 LIST_HEAD(head); 4548 4549 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 4550 list_for_each_entry_safe(sas_dev, sas_dev_next, 4551 &adapter->dev_topo.sas_dev_init_list, list) { 4552 if (sas_dev->rphy || sas_dev->pend_sas_rphy_add) 4553 continue; 4554 4555 list_del_init(&sas_dev->list); 4556 leapraid_clear_cached_boot_dev(adapter, sas_dev, 0); 4557 leapraid_sdev_put(sas_dev); 4558 } 4559 list_for_each_entry_safe(sas_dev, sas_dev_next, 4560 &adapter->dev_topo.sas_dev_list, list) { 4561 if (!sas_dev->resp) 4562 list_move_tail(&sas_dev->list, &head); 4563 else 4564 sas_dev->resp = 0; 4565 } 4566 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 4567 4568 list_for_each_entry_safe(sas_dev, sas_dev_next, &head, list) { 4569 leapraid_remove_device(adapter, sas_dev); 4570 list_del_init(&sas_dev->list); 4571 leapraid_sdev_put(sas_dev); 4572 } 4573 4574 dev_warn(&adapter->pdev->dev, 4575 "Unresponsive SAS end devices removed\n"); 4576 } 4577 4578 static void leapraid_remove_unresp_raid_volumes( 4579 struct leapraid_adapter *adapter) 4580 { 4581 unsigned long flags; 4582 struct leapraid_raid_volume *raid_volume, *raid_volume_next; 4583 LIST_HEAD(head); 4584 4585 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags); 4586 list_for_each_entry_safe(raid_volume, raid_volume_next, 4587 &adapter->dev_topo.raid_volume_list, list) { 4588 if (!raid_volume->resp) 4589 list_move_tail(&raid_volume->list, &head); 4590 else 4591 raid_volume->resp = 0; 4592 } 4593 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags); 4594 4595 list_for_each_entry_safe(raid_volume, raid_volume_next, &head, list) { 4596 leapraid_sas_volume_delete_by_ptr(adapter, raid_volume); 4597 } 4598 4599 dev_warn(&adapter->pdev->dev, 4600 "Unresponsive RAID volumes removed\n"); 4601 } 4602 4603 static void leapraid_remove_unresp_sas_exp(struct leapraid_adapter *adapter) 4604 { 4605 struct leapraid_topo_node *topo_node_exp, *topo_node_exp_next; 4606 unsigned long flags; 4607 LIST_HEAD(head); 4608 4609 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags); 4610 list_for_each_entry_safe(topo_node_exp, topo_node_exp_next, 4611 &adapter->dev_topo.exp_list, list) { 4612 if (!topo_node_exp->resp) 4613 list_move_tail(&topo_node_exp->list, &head); 4614 else 4615 topo_node_exp->resp = 0; 4616 } 4617 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags); 4618 4619 list_for_each_entry_safe(topo_node_exp, topo_node_exp_next, 4620 &head, list) 4621 leapraid_exp_node_rm(adapter, topo_node_exp); 4622 4623 dev_warn(&adapter->pdev->dev, 4624 "Unresponsive SAS expanders removed\n"); 4625 } 4626 4627 static void leapraid_remove_unresp_dev(struct leapraid_adapter *adapter) 4628 { 4629 leapraid_remove_unresp_sas_end_dev(adapter); 4630 if (adapter->adapter_attr.raid_support) 4631 leapraid_remove_unresp_raid_volumes(adapter); 4632 leapraid_remove_unresp_sas_exp(adapter); 4633 leapraid_ublk_io_all_dev(adapter); 4634 } 4635 4636 static void leapraid_del_dirty_vphy(struct leapraid_adapter *adapter) 4637 { 4638 struct leapraid_card_port *card_port, *card_port_next; 4639 struct leapraid_vphy *vphy, *vphy_next; 4640 4641 list_for_each_entry_safe(card_port, card_port_next, 4642 &adapter->dev_topo.card_port_list, list) { 4643 if (!card_port->vphys_mask) 4644 continue; 4645 4646 list_for_each_entry_safe(vphy, vphy_next, 4647 &card_port->vphys_list, list) { 4648 if (!(vphy->flg & LEAPRAID_VPHY_FLG_DIRTY)) 4649 continue; 4650 4651 card_port->vphys_mask &= ~vphy->phy_mask; 4652 list_del(&vphy->list); 4653 kfree(vphy); 4654 } 4655 4656 if (!card_port->vphys_mask && !card_port->sas_address) 4657 card_port->flg |= LEAPRAID_CARD_PORT_FLG_DIRTY; 4658 } 4659 } 4660 4661 static void leapraid_del_dirty_card_port(struct leapraid_adapter *adapter) 4662 { 4663 struct leapraid_card_port *card_port, *card_port_next; 4664 4665 list_for_each_entry_safe(card_port, card_port_next, 4666 &adapter->dev_topo.card_port_list, list) { 4667 if (!(card_port->flg & LEAPRAID_CARD_PORT_FLG_DIRTY) || 4668 card_port->flg & LEAPRAID_CARD_PORT_FLG_NEW) 4669 continue; 4670 4671 list_del(&card_port->list); 4672 kfree(card_port); 4673 } 4674 } 4675 4676 static void leapraid_update_dev_qdepth(struct leapraid_adapter *adapter) 4677 { 4678 struct leapraid_sdev_priv *sdev_priv; 4679 struct leapraid_sas_dev *sas_dev; 4680 struct leapraid_adapter_attr *attr; 4681 struct scsi_device *sdev; 4682 u16 qdepth; 4683 4684 attr = &adapter->adapter_attr; 4685 shost_for_each_device(sdev, adapter->shost) { 4686 sdev_priv = sdev->hostdata; 4687 if (!sdev_priv || !sdev_priv->starget_priv) 4688 continue; 4689 sas_dev = sdev_priv->starget_priv->sas_dev; 4690 if (sas_dev && sas_dev->dev_info & LEAPRAID_DEVTYP_SSP_TGT) 4691 qdepth = (sas_dev->port_connection > 1) ? 4692 attr->wideport_max_queue_depth : 4693 attr->narrowport_max_queue_depth; 4694 else if (sas_dev && sas_dev->dev_info & 4695 LEAPRAID_DEVTYP_SATA_DEV) 4696 qdepth = attr->sata_max_queue_depth; 4697 else 4698 continue; 4699 4700 leapraid_change_queue_depth(sdev, qdepth); 4701 } 4702 } 4703 4704 static void leapraid_update_exp_links(struct leapraid_adapter *adapter, 4705 struct leapraid_topo_node *topo_node_exp, 4706 u16 hdl) 4707 { 4708 union cfg_param_1 cfgp1 = {0}; 4709 union cfg_param_2 cfgp2 = {0}; 4710 struct leapraid_exp_p1 exp_p1; 4711 int i; 4712 4713 cfgp2.handle = hdl; 4714 for (i = 0; i < topo_node_exp->phys_num; i++) { 4715 cfgp1.phy_number = i; 4716 if (leapraid_op_config_page(adapter, &exp_p1, cfgp1, cfgp2, 4717 GET_SAS_EXPANDER_PG1)) 4718 return; 4719 4720 leapraid_transport_update_links( 4721 adapter, 4722 topo_node_exp->sas_address, 4723 le16_to_cpu(exp_p1.attached_dev_hdl), 4724 i, 4725 exp_p1.neg_link_rate >> 4726 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT, 4727 topo_node_exp->card_port); 4728 } 4729 } 4730 4731 static void leapraid_scan_exp_after_reset(struct leapraid_adapter *adapter) 4732 { 4733 union cfg_param_1 cfgp1 = {0}; 4734 union cfg_param_2 cfgp2 = {0}; 4735 struct leapraid_topo_node *topo_node_exp; 4736 struct leapraid_exp_p0 exp_p0; 4737 unsigned long flags; 4738 u16 hdl; 4739 u8 port_id; 4740 4741 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP; 4742 for (hdl = 0xFFFF, cfgp2.handle = hdl; 4743 !leapraid_op_config_page(adapter, &exp_p0, cfgp1, cfgp2, 4744 GET_SAS_EXPANDER_PG0); 4745 cfgp2.handle = hdl) { 4746 hdl = le16_to_cpu(exp_p0.dev_hdl); 4747 port_id = exp_p0.physical_port; 4748 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags); 4749 topo_node_exp = 4750 leapraid_exp_find_by_sas_address( 4751 adapter, 4752 le64_to_cpu(exp_p0.sas_address), 4753 leapraid_get_port_by_id(adapter, 4754 port_id, 4755 false)); 4756 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, 4757 flags); 4758 4759 if (topo_node_exp) { 4760 leapraid_update_exp_links(adapter, topo_node_exp, hdl); 4761 } else { 4762 leapraid_exp_add(adapter, hdl); 4763 4764 dev_info(&adapter->pdev->dev, 4765 "add exp: hdl=0x%04x, SAS addr=0x%016llx\n", 4766 hdl, 4767 (unsigned long long)le64_to_cpu( 4768 exp_p0.sas_address)); 4769 } 4770 } 4771 } 4772 4773 static void leapraid_scan_phy_disks_after_reset( 4774 struct leapraid_adapter *adapter) 4775 { 4776 union cfg_param_1 cfgp1 = {0}; 4777 union cfg_param_2 cfgp2 = {0}; 4778 union cfg_param_1 cfgp1_extra = {0}; 4779 union cfg_param_2 cfgp2_extra = {0}; 4780 struct leapraid_sas_dev_p0 sas_dev_p0; 4781 struct leapraid_raidpd_p0 raidpd_p0; 4782 struct leapraid_sas_dev *sas_dev; 4783 u8 phys_disk_num, port_id; 4784 u16 hdl, parent_hdl; 4785 u64 sas_addr; 4786 4787 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP; 4788 for (phys_disk_num = 0xFF, cfgp2.form_specific = phys_disk_num; 4789 !leapraid_op_config_page(adapter, &raidpd_p0, 4790 cfgp1, cfgp2, GET_PHY_DISK_PG0); 4791 cfgp2.form_specific = phys_disk_num) { 4792 phys_disk_num = raidpd_p0.phys_disk_num; 4793 hdl = le16_to_cpu(raidpd_p0.dev_hdl); 4794 sas_dev = leapraid_get_sas_dev_by_hdl(adapter, hdl); 4795 if (sas_dev) { 4796 leapraid_sdev_put(sas_dev); 4797 continue; 4798 } 4799 4800 cfgp1_extra.form = LEAPRAID_SAS_DEV_CFG_PGAD_HDL; 4801 cfgp2_extra.handle = hdl; 4802 if (leapraid_op_config_page(adapter, &sas_dev_p0, cfgp1_extra, 4803 cfgp2_extra, GET_SAS_DEVICE_PG0) != 4804 0) 4805 continue; 4806 4807 parent_hdl = le16_to_cpu(sas_dev_p0.parent_dev_hdl); 4808 if (!leapraid_get_sas_address(adapter, 4809 parent_hdl, 4810 &sas_addr)) { 4811 port_id = sas_dev_p0.physical_port; 4812 leapraid_transport_update_links( 4813 adapter, sas_addr, hdl, 4814 sas_dev_p0.phy_num, 4815 LEAPRAID_SAS_NEG_LINK_RATE_1_5, 4816 leapraid_get_port_by_id( 4817 adapter, port_id, false)); 4818 if (!hdl || hdl > 4819 adapter->adapter_attr.features.max_dev_handle) { 4820 dev_warn(&adapter->pdev->dev, 4821 "%s: Invalid device handle\n", 4822 __func__); 4823 } else { 4824 set_bit(hdl, adapter->dev_topo.pd_hdls); 4825 leapraid_add_dev(adapter, hdl); 4826 4827 dev_info(&adapter->pdev->dev, 4828 "add pd hdl=0x%04x saddr=0x%016llx\n", 4829 hdl, 4830 (unsigned long long)le64_to_cpu( 4831 sas_dev_p0.sas_address)); 4832 } 4833 } 4834 } 4835 } 4836 4837 static void leapraid_scan_vol_after_reset(struct leapraid_adapter *adapter) 4838 { 4839 union cfg_param_1 cfgp1 = {0}; 4840 union cfg_param_2 cfgp2 = {0}; 4841 union cfg_param_1 cfgp1_extra = {0}; 4842 union cfg_param_2 cfgp2_extra = {0}; 4843 struct leapraid_evt_data_ir_change evt_data; 4844 struct leapraid_raid_volume *raid_volume; 4845 struct leapraid_raidvol_p1 *vol_p1; 4846 struct leapraid_raidvol_p0 *vol_p0; 4847 u16 hdl; 4848 4849 vol_p0 = kzalloc_obj(*vol_p0); 4850 if (!vol_p0) 4851 return; 4852 4853 vol_p1 = kzalloc_obj(*vol_p1); 4854 if (!vol_p1) { 4855 kfree(vol_p0); 4856 return; 4857 } 4858 4859 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP; 4860 for (hdl = 0xFFFF, cfgp2.handle = hdl; 4861 !leapraid_op_config_page(adapter, vol_p1, cfgp1, 4862 cfgp2, GET_RAID_VOLUME_PG1); 4863 cfgp2.handle = hdl) { 4864 hdl = le16_to_cpu(vol_p1->dev_hdl); 4865 raid_volume = leapraid_raid_volume_find_by_wwid( 4866 adapter, 4867 le64_to_cpu(vol_p1->wwid)); 4868 if (raid_volume) { 4869 leapraid_raid_volume_put(raid_volume); 4870 continue; 4871 } 4872 4873 cfgp1_extra.size = sizeof(struct leapraid_raidvol_p0); 4874 cfgp2_extra.handle = hdl; 4875 if (leapraid_op_config_page(adapter, vol_p0, cfgp1_extra, 4876 cfgp2_extra, GET_RAID_VOLUME_PG0)) 4877 continue; 4878 4879 if (vol_p0->volume_state == LEAPRAID_VOL_STATE_OPTIMAL || 4880 vol_p0->volume_state == LEAPRAID_VOL_STATE_ONLINE || 4881 vol_p0->volume_state == LEAPRAID_VOL_STATE_DEGRADED) { 4882 memset(&evt_data, 0, 4883 sizeof(struct leapraid_evt_data_ir_change)); 4884 evt_data.reason_code = LEAPRAID_EVT_IR_RC_VOLUME_ADD; 4885 evt_data.vol_dev_hdl = vol_p1->dev_hdl; 4886 leapraid_sas_volume_add(adapter, &evt_data); 4887 dev_info(&adapter->pdev->dev, 4888 "add volume: hdl=0x%04x\n", 4889 vol_p1->dev_hdl); 4890 } 4891 } 4892 4893 kfree(vol_p0); 4894 kfree(vol_p1); 4895 } 4896 4897 static void leapraid_scan_sas_dev_after_reset(struct leapraid_adapter *adapter) 4898 { 4899 union cfg_param_1 cfgp1 = {0}; 4900 union cfg_param_2 cfgp2 = {0}; 4901 struct leapraid_sas_dev_p0 sas_dev_p0; 4902 struct leapraid_sas_dev *sas_dev; 4903 u16 hdl, parent_hdl; 4904 u64 sas_address; 4905 u8 port_id; 4906 4907 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP; 4908 for (hdl = 0xFFFF, cfgp2.handle = hdl; 4909 !leapraid_op_config_page(adapter, &sas_dev_p0, cfgp1, cfgp2, 4910 GET_SAS_DEVICE_PG0); 4911 cfgp2.handle = hdl) { 4912 hdl = le16_to_cpu(sas_dev_p0.dev_hdl); 4913 if (!hdl || 4914 hdl > adapter->adapter_attr.features.max_dev_handle) { 4915 dev_warn(&adapter->pdev->dev, 4916 "%s: Invalid device handle\n", __func__); 4917 continue; 4918 } 4919 4920 if (!(leapraid_is_end_dev(le32_to_cpu(sas_dev_p0.dev_info)))) 4921 continue; 4922 4923 port_id = sas_dev_p0.physical_port; 4924 sas_dev = leapraid_get_sas_dev_by_addr( 4925 adapter, 4926 le64_to_cpu(sas_dev_p0.sas_address), 4927 leapraid_get_port_by_id( 4928 adapter, 4929 port_id, 4930 false)); 4931 if (sas_dev) { 4932 leapraid_sdev_put(sas_dev); 4933 continue; 4934 } 4935 4936 parent_hdl = le16_to_cpu(sas_dev_p0.parent_dev_hdl); 4937 if (!leapraid_get_sas_address(adapter, parent_hdl, 4938 &sas_address)) { 4939 leapraid_transport_update_links( 4940 adapter, 4941 sas_address, 4942 hdl, 4943 sas_dev_p0.phy_num, 4944 LEAPRAID_SAS_NEG_LINK_RATE_1_5, 4945 leapraid_get_port_by_id(adapter, 4946 port_id, 4947 false)); 4948 leapraid_add_dev(adapter, hdl); 4949 dev_info(&adapter->pdev->dev, 4950 "Add SAS dev: hdl=0x%04x, saddr=0x%016llx\n", 4951 hdl, 4952 (unsigned long long)le64_to_cpu( 4953 sas_dev_p0.sas_address)); 4954 } 4955 } 4956 } 4957 4958 static void leapraid_scan_all_dev_after_reset(struct leapraid_adapter *adapter) 4959 { 4960 leapraid_sas_host_add(adapter, adapter->dev_topo.card.phys_num > 0); 4961 leapraid_scan_exp_after_reset(adapter); 4962 if (adapter->adapter_attr.raid_support) { 4963 leapraid_scan_phy_disks_after_reset(adapter); 4964 leapraid_scan_vol_after_reset(adapter); 4965 } 4966 leapraid_scan_sas_dev_after_reset(adapter); 4967 } 4968 4969 static void leapraid_hardreset_async_logic(struct leapraid_adapter *adapter) 4970 { 4971 unsigned long flags; 4972 4973 leapraid_remove_unresp_dev(adapter); 4974 leapraid_del_dirty_vphy(adapter); 4975 leapraid_del_dirty_card_port(adapter); 4976 leapraid_update_dev_qdepth(adapter); 4977 leapraid_scan_all_dev_after_reset(adapter); 4978 4979 if (adapter->scan_dev_desc.driver_loading) 4980 leapraid_scan_dev_done(adapter); 4981 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags); 4982 adapter->access_ctrl.shost_recover_async = 0; 4983 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags); 4984 wake_up(&adapter->access_ctrl.shost_recover_wq); 4985 } 4986 4987 static int leapraid_send_enc_cmd(struct leapraid_adapter *adapter, 4988 struct leapraid_sep_rep *sep_rep, 4989 struct leapraid_sep_req *sep_req) 4990 { 4991 void *req; 4992 bool reset_flg = false; 4993 int rc; 4994 u16 smid; 4995 4996 mutex_lock(&adapter->driver_cmds.enc_cmd.mutex); 4997 rc = leapraid_check_adapter_is_op(adapter, LEAPRAID_DB_WAIT_OP_SHORT, 4998 __func__); 4999 if (rc) 5000 goto unlock; 5001 5002 adapter->driver_cmds.enc_cmd.status = LEAPRAID_CMD_PENDING; 5003 smid = adapter->driver_cmds.enc_cmd.inter_taskid; 5004 req = leapraid_get_task_desc(adapter, smid); 5005 memset(req, 0, LEAPRAID_REQUEST_SIZE); 5006 memcpy(req, sep_req, sizeof(struct leapraid_sep_req)); 5007 init_completion(&adapter->driver_cmds.enc_cmd.done); 5008 leapraid_fire_task(adapter, smid); 5009 wait_for_completion_timeout(&adapter->driver_cmds.enc_cmd.done, 5010 LEAPRAID_ENC_CMD_TIMEOUT * HZ); 5011 if (!(adapter->driver_cmds.enc_cmd.status & LEAPRAID_CMD_DONE)) { 5012 dev_err(&adapter->pdev->dev, 5013 "%s: SEP command timeout, status=0x%x\n", 5014 __func__, adapter->driver_cmds.enc_cmd.status); 5015 leapraid_log_req_context(adapter, smid, sep_req); 5016 reset_flg = 5017 leapraid_check_reset( 5018 adapter->driver_cmds.enc_cmd.status); 5019 rc = -EFAULT; 5020 goto do_hard_reset; 5021 } 5022 5023 if (adapter->driver_cmds.enc_cmd.status & LEAPRAID_CMD_REPLY_VALID) 5024 memcpy(sep_rep, &adapter->driver_cmds.enc_cmd.reply, 5025 sizeof(struct leapraid_sep_rep)); 5026 do_hard_reset: 5027 if (reset_flg) { 5028 dev_info(&adapter->pdev->dev, "%s:%d: call hard_reset\n", 5029 __func__, __LINE__); 5030 leapraid_hard_reset_handler(adapter, FULL_RESET); 5031 } 5032 5033 adapter->driver_cmds.enc_cmd.status = LEAPRAID_CMD_NOT_USED; 5034 unlock: 5035 mutex_unlock(&adapter->driver_cmds.enc_cmd.mutex); 5036 return rc; 5037 } 5038 5039 static void leapraid_set_led(struct leapraid_adapter *adapter, 5040 struct leapraid_sas_dev *sas_dev, bool on) 5041 { 5042 struct leapraid_sep_rep sep_rep; 5043 struct leapraid_sep_req sep_req; 5044 5045 if (!sas_dev) 5046 return; 5047 5048 memset(&sep_req, 0, sizeof(struct leapraid_sep_req)); 5049 memset(&sep_rep, 0, sizeof(struct leapraid_sep_rep)); 5050 sep_req.func = LEAPRAID_FUNC_SCSI_ENC_PROCESSOR; 5051 sep_req.act = LEAPRAID_SEP_REQ_ACT_WRITE_STATUS; 5052 if (on) { 5053 u32 status = LEAPRAID_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT; 5054 5055 sep_req.slot_status = cpu_to_le32(status); 5056 sep_req.dev_hdl = cpu_to_le16(sas_dev->hdl); 5057 sep_req.flg = LEAPRAID_SEP_REQ_FLG_DEVHDL_ADDRESS; 5058 if (leapraid_send_enc_cmd(adapter, &sep_rep, &sep_req)) { 5059 leapraid_sdev_put(sas_dev); 5060 return; 5061 } 5062 5063 sas_dev->led_on = 1; 5064 leapraid_sdev_put(sas_dev); 5065 } else { 5066 sep_req.slot_status = 0; 5067 sep_req.slot = cpu_to_le16(sas_dev->slot); 5068 sep_req.dev_hdl = 0; 5069 sep_req.enc_hdl = cpu_to_le16(sas_dev->enc_hdl); 5070 sep_req.flg = LEAPRAID_SEP_REQ_FLG_ENCLOSURE_SLOT_ADDRESS; 5071 leapraid_send_enc_cmd(adapter, &sep_rep, &sep_req); 5072 } 5073 } 5074 5075 static int leapraid_wait_adapter_recovery(struct leapraid_adapter *adapter) 5076 { 5077 unsigned long flags; 5078 5079 while (leapraid_shost_in_recovery(adapter->shost) || 5080 READ_ONCE(adapter->access_ctrl.shost_recovering)) { 5081 if (READ_ONCE(adapter->access_ctrl.host_removing) || 5082 READ_ONCE(adapter->fw_evt_s.fw_evt_cleanup)) { 5083 spin_lock_irqsave( 5084 &adapter->reset_desc.adapter_reset_lock, 5085 flags); 5086 adapter->access_ctrl.shost_recover_async = 0; 5087 spin_unlock_irqrestore( 5088 &adapter->reset_desc.adapter_reset_lock, 5089 flags); 5090 5091 wake_up(&adapter->access_ctrl.shost_recover_wq); 5092 5093 dev_warn(&adapter->pdev->dev, 5094 "%s: Failed, shost %d, host %d\n", 5095 __func__, 5096 adapter->access_ctrl.shost_recovering, 5097 adapter->access_ctrl.host_removing); 5098 5099 return -EFAULT; 5100 } 5101 5102 wait_event_timeout( 5103 adapter->access_ctrl.recovery_waitq, 5104 (!leapraid_shost_in_recovery(adapter->shost) && 5105 !READ_ONCE(adapter->access_ctrl.shost_recovering)), 5106 msecs_to_jiffies(1000)); 5107 } 5108 5109 return 0; 5110 } 5111 5112 static void leapraid_fw_work(struct leapraid_adapter *adapter, 5113 struct leapraid_fw_evt_work *fw_evt) 5114 { 5115 struct leapraid_sas_dev *sas_dev; 5116 unsigned long flags; 5117 5118 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags); 5119 adapter->fw_evt_s.cur_evt = fw_evt; 5120 adapter->fw_evt_s.cur_evt_task = current; 5121 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags); 5122 leapraid_del_fw_evt_from_list(adapter, fw_evt); 5123 if (adapter->access_ctrl.host_removing || 5124 adapter->access_ctrl.pcie_recovering) { 5125 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags); 5126 leapraid_fw_evt_put(fw_evt); 5127 adapter->fw_evt_s.cur_evt = NULL; 5128 adapter->fw_evt_s.cur_evt_task = NULL; 5129 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags); 5130 return; 5131 } 5132 switch (fw_evt->evt_type) { 5133 case LEAPRAID_EVT_SAS_TOPO_CHANGE_LIST: 5134 leapraid_sas_topo_chg_evt(adapter, fw_evt); 5135 break; 5136 case LEAPRAID_EVT_IR_CHANGE: 5137 leapraid_sas_ir_chg_evt(adapter, fw_evt); 5138 break; 5139 case LEAPRAID_EVT_SAS_ENCL_DEV_STATUS_CHANGE: 5140 leapraid_sas_enc_dev_stat_chg_evt(adapter, fw_evt); 5141 break; 5142 case LEAPRAID_EVT_REMOVE_DEAD_DEV: 5143 if (leapraid_wait_adapter_recovery(adapter)) 5144 goto out_cleanup; 5145 5146 leapraid_hardreset_async_logic(adapter); 5147 break; 5148 case LEAPRAID_EVT_TURN_ON_PFA_LED: 5149 sas_dev = leapraid_get_sas_dev_by_hdl(adapter, 5150 fw_evt->dev_handle); 5151 leapraid_set_led(adapter, sas_dev, true); 5152 break; 5153 case LEAPRAID_EVT_SCAN_DEV_DONE: 5154 adapter->scan_dev_desc.scan_start = 0; 5155 break; 5156 default: 5157 break; 5158 } 5159 out_cleanup: 5160 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags); 5161 leapraid_fw_evt_put(fw_evt); 5162 adapter->fw_evt_s.cur_evt = NULL; 5163 adapter->fw_evt_s.cur_evt_task = NULL; 5164 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags); 5165 } 5166 5167 static void leapraid_sas_dev_stat_chg_evt( 5168 struct leapraid_adapter *adapter, 5169 struct leapraid_evt_data_sas_dev_status_change *event_data) 5170 { 5171 struct leapraid_starget_priv *starget_priv; 5172 struct leapraid_sas_dev *sas_dev; 5173 u64 sas_address; 5174 unsigned long flags; 5175 5176 switch (event_data->reason_code) { 5177 case LEAPRAID_EVT_SAS_DEV_STAT_RC_INTERNAL_DEV_RESET: 5178 case LEAPRAID_EVT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET: 5179 break; 5180 default: 5181 return; 5182 } 5183 5184 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 5185 5186 sas_address = le64_to_cpu(event_data->sas_address); 5187 sas_dev = leapraid_hold_lock_get_sas_dev_by_addr( 5188 adapter, 5189 sas_address, 5190 leapraid_get_port_by_id(adapter, 5191 event_data->physical_port, 5192 false)); 5193 if (!sas_dev || !sas_dev->starget) 5194 goto out_unlock; 5195 5196 starget_priv = sas_dev->starget->hostdata; 5197 if (starget_priv) { 5198 switch (event_data->reason_code) { 5199 case LEAPRAID_EVT_SAS_DEV_STAT_RC_INTERNAL_DEV_RESET: 5200 starget_priv->tm_busy = 1; 5201 break; 5202 case LEAPRAID_EVT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET: 5203 starget_priv->tm_busy = 0; 5204 break; 5205 } 5206 } 5207 5208 out_unlock: 5209 if (sas_dev) 5210 leapraid_sdev_put(sas_dev); 5211 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 5212 } 5213 5214 static void leapraid_set_volume_delete_flag(struct leapraid_adapter *adapter, 5215 u16 handle) 5216 { 5217 struct leapraid_raid_volume *raid_volume; 5218 struct leapraid_starget_priv *sas_target_priv_data; 5219 unsigned long flags; 5220 5221 raid_volume = leapraid_raid_volume_find_by_hdl(adapter, handle); 5222 if (raid_volume) { 5223 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags); 5224 if (raid_volume->starget && 5225 raid_volume->starget->hostdata) { 5226 sas_target_priv_data = raid_volume->starget->hostdata; 5227 sas_target_priv_data->deleted = 1; 5228 } 5229 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, 5230 flags); 5231 leapraid_raid_volume_put(raid_volume); 5232 } 5233 } 5234 5235 static void leapraid_check_ir_change_evt( 5236 struct leapraid_adapter *adapter, 5237 struct leapraid_evt_data_ir_change *evt_data) 5238 { 5239 u16 phys_disk_dev_hdl; 5240 5241 switch (evt_data->reason_code) { 5242 case LEAPRAID_EVT_IR_RC_VOLUME_DELETE: 5243 leapraid_set_volume_delete_flag( 5244 adapter, 5245 le16_to_cpu(evt_data->vol_dev_hdl)); 5246 break; 5247 case LEAPRAID_EVT_IR_RC_PD_UNHIDDEN_TO_DELETE: 5248 phys_disk_dev_hdl = 5249 le16_to_cpu(evt_data->phys_disk_dev_hdl); 5250 if (!phys_disk_dev_hdl || 5251 phys_disk_dev_hdl > 5252 adapter->adapter_attr.features.max_dev_handle) { 5253 dev_warn(&adapter->pdev->dev, 5254 "%s: Invalid device handle\n", __func__); 5255 } else { 5256 clear_bit(phys_disk_dev_hdl, 5257 adapter->dev_topo.pd_hdls); 5258 leapraid_tgt_rst_send(adapter, phys_disk_dev_hdl); 5259 } 5260 break; 5261 } 5262 } 5263 5264 static void leapraid_topo_del_evts_process_exp_status( 5265 struct leapraid_adapter *adapter, 5266 struct leapraid_evt_data_sas_topo_change_list *evt_data) 5267 { 5268 struct leapraid_fw_evt_work *fw_evt = NULL; 5269 struct leapraid_evt_data_sas_topo_change_list *loc_evt_data; 5270 unsigned long flags; 5271 u16 exp_hdl; 5272 5273 exp_hdl = le16_to_cpu(evt_data->exp_dev_hdl); 5274 5275 switch (evt_data->exp_status) { 5276 case LEAPRAID_EVT_SAS_TOPO_ES_NOT_RESPONDING: 5277 spin_lock_irqsave(&adapter->fw_evt_s.fw_evt_lock, flags); 5278 list_for_each_entry(fw_evt, 5279 &adapter->fw_evt_s.fw_evt_list, list) { 5280 if (fw_evt->evt_type != 5281 LEAPRAID_EVT_SAS_TOPO_CHANGE_LIST || 5282 fw_evt->ignore) 5283 continue; 5284 5285 loc_evt_data = fw_evt->evt_data; 5286 if ((loc_evt_data->exp_status == 5287 LEAPRAID_EVT_SAS_TOPO_ES_ADDED || 5288 loc_evt_data->exp_status == 5289 LEAPRAID_EVT_SAS_TOPO_ES_RESPONDING) && 5290 le16_to_cpu(loc_evt_data->exp_dev_hdl) == exp_hdl) 5291 fw_evt->ignore = 1; 5292 } 5293 spin_unlock_irqrestore(&adapter->fw_evt_s.fw_evt_lock, flags); 5294 break; 5295 default: 5296 break; 5297 } 5298 } 5299 5300 static void leapraid_check_topo_del_evts( 5301 struct leapraid_adapter *adapter, 5302 struct leapraid_evt_data_sas_topo_change_list *evt_data) 5303 { 5304 int reason_code; 5305 u16 hdl; 5306 int i; 5307 5308 for (i = 0; i < evt_data->entry_num; i++) { 5309 hdl = le16_to_cpu(evt_data->phy[i].attached_dev_hdl); 5310 if (!hdl) 5311 continue; 5312 5313 reason_code = evt_data->phy[i].phy_status & 5314 LEAPRAID_EVT_SAS_TOPO_RC_MASK; 5315 if (reason_code == 5316 LEAPRAID_EVT_SAS_TOPO_RC_TARG_NOT_RESPONDING) 5317 leapraid_tgt_not_responding(adapter, hdl); 5318 } 5319 leapraid_topo_del_evts_process_exp_status(adapter, evt_data); 5320 } 5321 5322 static bool leapraid_async_evt_validate( 5323 struct leapraid_adapter *adapter, 5324 struct leapraid_evt_notify_rep *event_notify_rep) 5325 { 5326 size_t msg_len; 5327 size_t evt_sz; 5328 size_t evt_avail; 5329 u16 evt; 5330 5331 msg_len = event_notify_rep->msg_len * sizeof(u32); 5332 if (msg_len > LEAPRAID_REPLY_SIZE || 5333 msg_len < offsetof(struct leapraid_evt_notify_rep, evt_data)) { 5334 dev_warn(&adapter->pdev->dev, 5335 "%s: Invalid async event msg_len=%zu\n", 5336 __func__, msg_len); 5337 return false; 5338 } 5339 5340 evt_sz = le16_to_cpu(event_notify_rep->evt_data_len) * sizeof(u32); 5341 evt_avail = msg_len - 5342 offsetof(struct leapraid_evt_notify_rep, evt_data); 5343 if (evt_sz > evt_avail) { 5344 dev_warn(&adapter->pdev->dev, 5345 "%s: Invalid async event evt_data_len=%zu\n", 5346 __func__, evt_sz); 5347 return false; 5348 } 5349 5350 evt = le16_to_cpu(event_notify_rep->evt); 5351 switch (evt) { 5352 case LEAPRAID_EVT_SAS_DEV_STATUS_CHANGE: 5353 if (evt_sz < 5354 sizeof(struct leapraid_evt_data_sas_dev_status_change)) 5355 goto invalid_evt_sz; 5356 break; 5357 case LEAPRAID_EVT_IR_CHANGE: 5358 if (evt_sz < sizeof(struct leapraid_evt_data_ir_change)) 5359 goto invalid_evt_sz; 5360 break; 5361 case LEAPRAID_EVT_SAS_TOPO_CHANGE_LIST: 5362 { 5363 struct leapraid_evt_data_sas_topo_change_list *evt_data = 5364 (void *)event_notify_rep->evt_data; 5365 size_t hdr_sz; 5366 5367 hdr_sz = 5368 offsetof(struct leapraid_evt_data_sas_topo_change_list, 5369 phy); 5370 if (evt_sz < hdr_sz) 5371 goto invalid_evt_sz; 5372 5373 if (evt_data->entry_num > 5374 (evt_sz - hdr_sz) / sizeof(evt_data->phy[0])) 5375 goto invalid_evt_sz; 5376 break; 5377 } 5378 case LEAPRAID_EVT_SAS_ENCL_DEV_STATUS_CHANGE: 5379 if (evt_sz < 5380 sizeof(struct leapraid_evt_data_sas_enc_dev_status_change)) 5381 goto invalid_evt_sz; 5382 break; 5383 default: 5384 break; 5385 } 5386 5387 return true; 5388 5389 invalid_evt_sz: 5390 dev_warn(&adapter->pdev->dev, 5391 "%s: Invalid async event size=%zu for evt=0x%x\n", 5392 __func__, evt_sz, evt); 5393 return false; 5394 } 5395 5396 static bool leapraid_async_process_evt( 5397 struct leapraid_adapter *adapter, 5398 struct leapraid_evt_notify_rep *event_notify_rep) 5399 { 5400 u16 evt = le16_to_cpu(event_notify_rep->evt); 5401 bool exit_flag = false; 5402 5403 if (adapter->access_ctrl.host_removing || 5404 adapter->access_ctrl.pcie_recovering) 5405 return true; 5406 5407 switch (evt) { 5408 case LEAPRAID_EVT_SAS_DEV_STATUS_CHANGE: 5409 leapraid_sas_dev_stat_chg_evt( 5410 adapter, 5411 (struct leapraid_evt_data_sas_dev_status_change 5412 *)event_notify_rep->evt_data); 5413 break; 5414 case LEAPRAID_EVT_IR_CHANGE: 5415 leapraid_check_ir_change_evt( 5416 adapter, 5417 (struct leapraid_evt_data_ir_change 5418 *)event_notify_rep->evt_data); 5419 break; 5420 case LEAPRAID_EVT_SAS_TOPO_CHANGE_LIST: 5421 leapraid_check_topo_del_evts( 5422 adapter, 5423 (struct leapraid_evt_data_sas_topo_change_list 5424 *)event_notify_rep->evt_data); 5425 if (adapter->access_ctrl.shost_recovering) { 5426 exit_flag = true; 5427 return exit_flag; 5428 } 5429 break; 5430 case LEAPRAID_EVT_SAS_ENCL_DEV_STATUS_CHANGE: 5431 break; 5432 default: 5433 exit_flag = true; 5434 return exit_flag; 5435 } 5436 5437 return exit_flag; 5438 } 5439 5440 static void leapraid_async_evt_cb_enqueue( 5441 struct leapraid_adapter *adapter, 5442 struct leapraid_evt_notify_rep *evt_notify_rep) 5443 { 5444 struct leapraid_fw_evt_work *fw_evt; 5445 u16 evt_sz; 5446 5447 fw_evt = leapraid_alloc_fw_evt_work(); 5448 if (!fw_evt) 5449 return; 5450 5451 evt_sz = le16_to_cpu(evt_notify_rep->evt_data_len) * sizeof(u32); 5452 fw_evt->evt_data = kmemdup(evt_notify_rep->evt_data, 5453 evt_sz, GFP_ATOMIC); 5454 if (!fw_evt->evt_data) { 5455 leapraid_fw_evt_put(fw_evt); 5456 return; 5457 } 5458 fw_evt->adapter = adapter; 5459 fw_evt->evt_type = le16_to_cpu(evt_notify_rep->evt); 5460 leapraid_fw_evt_add(adapter, fw_evt); 5461 leapraid_fw_evt_put(fw_evt); 5462 } 5463 5464 static void leapraid_async_evt_cb(struct leapraid_adapter *adapter, 5465 u8 msix_index, u32 rep_paddr) 5466 { 5467 struct leapraid_evt_notify_rep *evt_notify_rep; 5468 5469 if (adapter->access_ctrl.host_removing || 5470 adapter->access_ctrl.pcie_recovering) 5471 return; 5472 5473 evt_notify_rep = leapraid_get_reply_vaddr(adapter, rep_paddr); 5474 if (unlikely(!evt_notify_rep)) 5475 return; 5476 5477 if (!leapraid_async_evt_validate(adapter, evt_notify_rep)) 5478 return; 5479 5480 if (leapraid_async_process_evt(adapter, evt_notify_rep)) 5481 return; 5482 5483 leapraid_async_evt_cb_enqueue(adapter, evt_notify_rep); 5484 } 5485 5486 static void leapraid_handle_async_event(struct leapraid_adapter *adapter, 5487 u8 msix_index, u32 reply) 5488 { 5489 struct leapraid_evt_notify_rep *leap_mpi_rep = 5490 leapraid_get_reply_vaddr(adapter, reply); 5491 5492 if (!leap_mpi_rep) 5493 return; 5494 5495 if (leap_mpi_rep->func != LEAPRAID_FUNC_EVENT_NOTIFY) 5496 return; 5497 5498 leapraid_async_evt_cb(adapter, msix_index, reply); 5499 } 5500 5501 void leapraid_async_turn_on_led(struct leapraid_adapter *adapter, u16 handle) 5502 { 5503 struct leapraid_fw_evt_work *fw_event; 5504 5505 fw_event = leapraid_alloc_fw_evt_work(); 5506 if (!fw_event) 5507 return; 5508 5509 fw_event->dev_handle = handle; 5510 fw_event->adapter = adapter; 5511 fw_event->evt_type = LEAPRAID_EVT_TURN_ON_PFA_LED; 5512 leapraid_fw_evt_add(adapter, fw_event); 5513 leapraid_fw_evt_put(fw_event); 5514 } 5515 5516 static void leapraid_hardreset_barrier(struct leapraid_adapter *adapter) 5517 { 5518 struct leapraid_fw_evt_work *fw_event; 5519 5520 fw_event = leapraid_alloc_fw_evt_work(); 5521 if (!fw_event) 5522 return; 5523 5524 fw_event->adapter = adapter; 5525 fw_event->evt_type = LEAPRAID_EVT_REMOVE_DEAD_DEV; 5526 leapraid_fw_evt_add(adapter, fw_event); 5527 leapraid_fw_evt_put(fw_event); 5528 } 5529 5530 static void leapraid_scan_dev_complete(struct leapraid_adapter *adapter) 5531 { 5532 struct leapraid_fw_evt_work *fw_evt; 5533 5534 fw_evt = leapraid_alloc_fw_evt_work(); 5535 if (!fw_evt) 5536 return; 5537 5538 fw_evt->evt_type = LEAPRAID_EVT_SCAN_DEV_DONE; 5539 fw_evt->adapter = adapter; 5540 leapraid_fw_evt_add(adapter, fw_evt); 5541 leapraid_fw_evt_put(fw_evt); 5542 } 5543 5544 static void leapraid_handle_scan_cb(struct leapraid_adapter *adapter, 5545 struct leapraid_driver_cmd *cmd, 5546 struct leapraid_rep *rep) 5547 { 5548 u16 status; 5549 5550 cmd->status &= ~LEAPRAID_CMD_PENDING; 5551 5552 status = le16_to_cpu(rep->adapter_status) & 5553 LEAPRAID_ADAPTER_STATUS_MASK; 5554 if (status != LEAPRAID_ADAPTER_STATUS_SUCCESS) 5555 adapter->scan_dev_desc.scan_dev_failed = 1; 5556 5557 if (!cmd->async_scan_dev) { 5558 complete(&cmd->done); 5559 return; 5560 } 5561 5562 if (status == LEAPRAID_ADAPTER_STATUS_SUCCESS) 5563 leapraid_scan_dev_complete(adapter); 5564 else 5565 adapter->scan_dev_desc.scan_start_failed = status; 5566 } 5567 5568 static void leapraid_handle_ctl_cb(struct leapraid_adapter *adapter, 5569 struct leapraid_rep *rep, 5570 u16 taskid) 5571 { 5572 struct leapraid_scsiio_rep *scsiio_reply; 5573 5574 if (rep->function != LEAPRAID_FUNC_SCSIIO && 5575 rep->function != LEAPRAID_FUNC_SCSIIO_RAID_PASSTHROUGH) 5576 return; 5577 5578 scsiio_reply = (struct leapraid_scsiio_rep *)rep; 5579 if (!(scsiio_reply->scsi_state & 5580 LEAPRAID_SCSI_STATE_AUTOSENSE_VALID)) 5581 return; 5582 5583 memcpy(&adapter->driver_cmds.ctl_cmd.sense, 5584 leapraid_get_sense_buffer(adapter, taskid), 5585 min_t(u32, SCSI_SENSE_BUFFERSIZE, 5586 le32_to_cpu(scsiio_reply->sense_count))); 5587 } 5588 5589 static bool leapraid_driver_cmds_done(struct leapraid_adapter *adapter, 5590 u16 taskid, u8 msix_index, 5591 u32 rep_paddr, u8 cb_idx) 5592 { 5593 struct leapraid_rep *leap_mpi_rep = 5594 leapraid_get_reply_vaddr(adapter, rep_paddr); 5595 struct leapraid_driver_cmd *sp_cmd, *_sp_cmd = NULL; 5596 u8 reply_len; 5597 5598 list_for_each_entry(sp_cmd, &adapter->driver_cmds.special_cmd_list, 5599 list) 5600 if (cb_idx == sp_cmd->cb_idx) { 5601 _sp_cmd = sp_cmd; 5602 break; 5603 } 5604 5605 if (WARN_ON(!_sp_cmd)) 5606 return true; 5607 if (WARN_ON(_sp_cmd->status == LEAPRAID_CMD_NOT_USED)) 5608 return true; 5609 if (WARN_ON(taskid != _sp_cmd->hp_taskid && 5610 taskid != _sp_cmd->taskid && 5611 taskid != _sp_cmd->inter_taskid)) 5612 return true; 5613 _sp_cmd->status |= LEAPRAID_CMD_DONE; 5614 if (leap_mpi_rep) { 5615 reply_len = leap_mpi_rep->msg_len * sizeof(u32); 5616 if (reply_len > LEAPRAID_REPLY_SIZE) 5617 reply_len = LEAPRAID_REPLY_SIZE; 5618 memcpy(&_sp_cmd->reply, leap_mpi_rep, reply_len); 5619 _sp_cmd->status |= LEAPRAID_CMD_REPLY_VALID; 5620 5621 if (_sp_cmd->cb_idx == LEAPRAID_SCAN_DEV_CB_IDX) { 5622 leapraid_handle_scan_cb(adapter, _sp_cmd, 5623 leap_mpi_rep); 5624 return true; 5625 } 5626 5627 if (_sp_cmd->cb_idx == LEAPRAID_CTL_CB_IDX) 5628 leapraid_handle_ctl_cb(adapter, leap_mpi_rep, taskid); 5629 } 5630 5631 _sp_cmd->status &= ~LEAPRAID_CMD_PENDING; 5632 complete(&_sp_cmd->done); 5633 5634 return true; 5635 } 5636 5637 static void leapraid_complete_task(struct leapraid_adapter *adapter, 5638 u16 taskid, u8 msix_idx, u32 rep) 5639 { 5640 bool scsiio_task = taskid <= adapter->shost->can_queue; 5641 5642 if (scsiio_task) { 5643 if (leapraid_scsiio_done(adapter, taskid, msix_idx, rep)) 5644 leapraid_free_taskid(adapter, taskid); 5645 return; 5646 } 5647 5648 if (leapraid_driver_cmds_done(adapter, taskid, msix_idx, rep, 5649 leapraid_get_cb_idx(adapter, taskid))) 5650 leapraid_free_taskid(adapter, taskid); 5651 } 5652 5653 static void leapraid_request_descript_handler( 5654 struct leapraid_adapter *adapter, 5655 union leapraid_rep_desc_union *rpf, 5656 u8 req_desc_type, u8 msix_idx) 5657 { 5658 u32 rep; 5659 u16 taskid; 5660 5661 rep = 0; 5662 taskid = le16_to_cpu(rpf->dflt_rep.taskid); 5663 switch (req_desc_type) { 5664 case LEAPRAID_RPY_DESC_FLG_FP_SCSI_IO_SUCCESS: 5665 case LEAPRAID_RPY_DESC_FLG_SCSI_IO_SUCCESS: 5666 leapraid_complete_task(adapter, taskid, msix_idx, 0); 5667 break; 5668 case LEAPRAID_RPY_DESC_FLG_ADDRESS_REPLY: 5669 rep = le32_to_cpu(rpf->addr_rep.rep_frame_addr); 5670 if (rep > (u32)adapter->mem_desc.rep_msg_dma + 5671 adapter->adapter_attr.rep_msg_qd * 5672 LEAPRAID_REPLY_SIZE || 5673 rep < (u32)adapter->mem_desc.rep_msg_dma) 5674 rep = 0; 5675 5676 if (taskid) 5677 leapraid_complete_task(adapter, taskid, msix_idx, rep); 5678 else 5679 leapraid_handle_async_event(adapter, msix_idx, rep); 5680 5681 if (!rep) 5682 return; 5683 5684 adapter->rep_msg_host_idx = 5685 (adapter->rep_msg_host_idx == 5686 (adapter->adapter_attr.rep_msg_qd - 1)) ? 5687 0 : adapter->rep_msg_host_idx + 1; 5688 adapter->mem_desc.rep_msg_addr[adapter->rep_msg_host_idx] = 5689 cpu_to_le32(rep); 5690 wmb(); /* Make sure that all write ops are in order */ 5691 writel(adapter->rep_msg_host_idx, 5692 &adapter->iomem_base->rep_msg_host_idx); 5693 5694 break; 5695 default: 5696 break; 5697 } 5698 } 5699 5700 int leapraid_rep_queue_handler(struct leapraid_rq *rq) 5701 { 5702 struct leapraid_adapter *adapter = rq->adapter; 5703 union leapraid_rep_desc_union *rep_desc; 5704 u8 req_desc_type; 5705 u64 finish_cmds; 5706 u8 msix_idx; 5707 5708 msix_idx = rq->msix_idx; 5709 finish_cmds = 0; 5710 if (!atomic_add_unless(&rq->busy, LEAPRAID_BUSY_LIMIT, 5711 LEAPRAID_BUSY_LIMIT)) 5712 return finish_cmds; 5713 5714 rep_desc = &rq->rep_desc[rq->rep_post_host_idx]; 5715 req_desc_type = rep_desc->dflt_rep.rep_flg & 5716 LEAPRAID_RPY_DESC_FLG_TYPE_MASK; 5717 if (req_desc_type == LEAPRAID_RPY_DESC_FLG_UNUSED) { 5718 atomic_dec(&rq->busy); 5719 return finish_cmds; 5720 } 5721 5722 for (;;) { 5723 if (rep_desc->u.low == UINT_MAX || 5724 rep_desc->u.high == UINT_MAX) 5725 break; 5726 5727 leapraid_request_descript_handler(adapter, rep_desc, 5728 req_desc_type, msix_idx); 5729 dev_dbg(&adapter->pdev->dev, 5730 "LEAPRAID_SCSIIO: Handled Desc taskid %d, msix %d\n", 5731 rep_desc->dflt_rep.taskid, msix_idx); 5732 rep_desc->words = cpu_to_le64(ULLONG_MAX); 5733 rq->rep_post_host_idx = 5734 (rq->rep_post_host_idx == 5735 (adapter->adapter_attr.rep_desc_qd - 5736 LEAPRAID_BUSY_LIMIT)) ? 5737 0 : rq->rep_post_host_idx + 1; 5738 req_desc_type = 5739 rq->rep_desc[rq->rep_post_host_idx].dflt_rep.rep_flg & 5740 LEAPRAID_RPY_DESC_FLG_TYPE_MASK; 5741 finish_cmds++; 5742 if (req_desc_type == LEAPRAID_RPY_DESC_FLG_UNUSED) 5743 break; 5744 rep_desc = rq->rep_desc + rq->rep_post_host_idx; 5745 } 5746 5747 if (!finish_cmds) { 5748 atomic_dec(&rq->busy); 5749 return finish_cmds; 5750 } 5751 5752 wmb(); /* Make sure that all write ops are in order */ 5753 writel(rq->rep_post_host_idx | ((msix_idx & LEAPRAID_MSIX_GROUP_MASK) << 5754 LEAPRAID_RPHI_MSIX_IDX_SHIFT), 5755 &adapter->iomem_base->rep_post_reg_idx[ 5756 msix_idx / LEAPRAID_MSIX_GROUP_SIZE].idx); 5757 atomic_dec(&rq->busy); 5758 return finish_cmds; 5759 } 5760 5761 static irqreturn_t leapraid_irq_handler(int irq, void *bus_id) 5762 { 5763 struct leapraid_rq *rq = bus_id; 5764 struct leapraid_adapter *adapter = rq->adapter; 5765 5766 dev_dbg(&adapter->pdev->dev, 5767 "LEAPRAID_SCSIIO: Receive a interrupt, irq %d msix %d\n", 5768 irq, rq->msix_idx); 5769 5770 if (adapter->mask_int) 5771 return IRQ_NONE; 5772 5773 return (leapraid_rep_queue_handler(rq) > 0 ? 5774 IRQ_HANDLED : IRQ_NONE); 5775 } 5776 5777 void leapraid_sync_irqs(struct leapraid_adapter *adapter, bool poll) 5778 { 5779 struct leapraid_int_rq *int_rq; 5780 struct leapraid_blk_mq_poll_rq *blk_mq_poll_rq; 5781 unsigned int i; 5782 5783 if (!adapter->notification_desc.msix_enable) 5784 return; 5785 5786 if (adapter->access_ctrl.shost_recovering || 5787 adapter->access_ctrl.host_removing || 5788 adapter->access_ctrl.pcie_recovering) 5789 return; 5790 5791 for (i = 0; i < adapter->notification_desc.iopoll_qdex; i++) { 5792 int_rq = &adapter->notification_desc.int_rqs[i]; 5793 if (adapter->access_ctrl.shost_recovering || 5794 adapter->access_ctrl.host_removing || 5795 adapter->access_ctrl.pcie_recovering) 5796 return; 5797 5798 if (int_rq->rq.msix_idx == 0) 5799 continue; 5800 5801 synchronize_irq(pci_irq_vector(adapter->pdev, 5802 int_rq->rq.msix_idx)); 5803 if (poll) 5804 leapraid_rep_queue_handler(&int_rq->rq); 5805 } 5806 5807 for (i = 0; i < adapter->notification_desc.iopoll_qcnt; i++) { 5808 blk_mq_poll_rq = 5809 &adapter->notification_desc.blk_mq_poll_rqs[i]; 5810 if (adapter->access_ctrl.shost_recovering || 5811 adapter->access_ctrl.host_removing || 5812 adapter->access_ctrl.pcie_recovering) 5813 return; 5814 5815 if (blk_mq_poll_rq->rq.msix_idx == 0) 5816 continue; 5817 5818 leapraid_rep_queue_handler(&blk_mq_poll_rq->rq); 5819 } 5820 } 5821 5822 static void leapraid_sync_irqs_for_cleanup(struct leapraid_adapter *adapter) 5823 { 5824 struct leapraid_notification_desc *desc = &adapter->notification_desc; 5825 struct leapraid_int_rq *int_rq; 5826 unsigned int i; 5827 5828 if (!adapter->mask_int && leapraid_pci_active(adapter)) 5829 leapraid_mask_int(adapter); 5830 5831 for (i = 0; i < desc->int_rqs_allocated; i++) { 5832 int_rq = &desc->int_rqs[i]; 5833 synchronize_irq(pci_irq_vector(adapter->pdev, 5834 int_rq->rq.msix_idx)); 5835 } 5836 } 5837 5838 void leapraid_mq_polling_pause(struct leapraid_adapter *adapter) 5839 { 5840 struct leapraid_notification_desc *desc; 5841 int iopoll_q_count; 5842 int qid; 5843 5844 desc = &adapter->notification_desc; 5845 iopoll_q_count = adapter->adapter_attr.rq_cnt - desc->iopoll_qdex; 5846 5847 for (qid = 0; qid < iopoll_q_count; qid++) 5848 atomic_set(&desc->blk_mq_poll_rqs[qid].pause, 1); 5849 5850 for (qid = 0; qid < iopoll_q_count; qid++) { 5851 while (atomic_read(&desc->blk_mq_poll_rqs[qid].busy)) { 5852 cpu_relax(); 5853 udelay(LEAPRAID_IO_POLL_DELAY_US); 5854 } 5855 } 5856 } 5857 5858 void leapraid_mq_polling_resume(struct leapraid_adapter *adapter) 5859 { 5860 struct leapraid_notification_desc *desc; 5861 int iopoll_q_count; 5862 int qid; 5863 5864 desc = &adapter->notification_desc; 5865 iopoll_q_count = adapter->adapter_attr.rq_cnt - desc->iopoll_qdex; 5866 5867 for (qid = 0; qid < iopoll_q_count; qid++) 5868 atomic_set(&desc->blk_mq_poll_rqs[qid].pause, 0); 5869 } 5870 5871 static int leapraid_unlock_host_diag(struct leapraid_adapter *adapter, 5872 u32 *host_diag) 5873 { 5874 const u32 unlock_seq[] = { 5875 LEAPRAID_WRSEQ_FLUSH_KEY_VALUE, 5876 LEAPRAID_WRSEQ_1ST_KEY_VALUE, 5877 LEAPRAID_WRSEQ_2ND_KEY_VALUE, 5878 LEAPRAID_WRSEQ_3RD_KEY_VALUE, 5879 LEAPRAID_WRSEQ_4TH_KEY_VALUE, 5880 LEAPRAID_WRSEQ_5TH_KEY_VALUE, 5881 LEAPRAID_WRSEQ_6TH_KEY_VALUE 5882 }; 5883 5884 const int max_retries = LEAPRAID_UNLOCK_RETRY_LIMIT; 5885 int retry = 0; 5886 unsigned int i; 5887 5888 *host_diag = 0; 5889 while (retry++ <= max_retries) { 5890 for (i = 0; i < ARRAY_SIZE(unlock_seq); i++) 5891 writel(unlock_seq[i], &adapter->iomem_base->ws); 5892 5893 msleep(LEAPRAID_UNLOCK_SLEEP_MS); 5894 5895 *host_diag = leapraid_readl(&adapter->iomem_base->host_diag); 5896 if (*host_diag & LEAPRAID_DIAG_WRITE_ENABLE) 5897 return 0; 5898 } 5899 5900 dev_err(&adapter->pdev->dev, "Try host reset timeout!\n"); 5901 return -EFAULT; 5902 } 5903 5904 static int leapraid_host_diag_reset(struct leapraid_adapter *adapter) 5905 { 5906 u32 host_diag; 5907 5908 pci_cfg_access_lock(adapter->pdev); 5909 5910 mutex_lock(&adapter->reset_desc.host_diag_mutex); 5911 if (leapraid_unlock_host_diag(adapter, &host_diag)) 5912 goto out_cleanup; 5913 5914 writel(host_diag | LEAPRAID_DIAG_RESET, 5915 &adapter->iomem_base->host_diag); 5916 5917 msleep(LEAPRAID_MSLEEP_EXTRA_LONG_MS); 5918 msleep(LEAPRAID_MSLEEP_NORMAL_MS); 5919 5920 host_diag = leapraid_readl(&adapter->iomem_base->host_diag); 5921 if (host_diag == LEAPRAID_INVALID_HOST_DIAG_VAL || 5922 host_diag & LEAPRAID_DIAG_RESET) 5923 goto out_cleanup; 5924 5925 writel(0x0, &adapter->iomem_base->ws); 5926 mutex_unlock(&adapter->reset_desc.host_diag_mutex); 5927 if (!leapraid_wait_adapter_ready(adapter)) 5928 goto out_failed; 5929 5930 pci_cfg_access_unlock(adapter->pdev); 5931 return 0; 5932 5933 out_cleanup: 5934 mutex_unlock(&adapter->reset_desc.host_diag_mutex); 5935 out_failed: 5936 pci_cfg_access_unlock(adapter->pdev); 5937 dev_err(&adapter->pdev->dev, "Host diag failed\n"); 5938 return -EFAULT; 5939 } 5940 5941 static int leapraid_find_matching_port( 5942 struct leapraid_card_port *card_port_table, 5943 u8 count, u8 port_id, u64 sas_addr) 5944 { 5945 int i; 5946 5947 for (i = 0; i < count; i++) 5948 if (card_port_table[i].port_id == port_id && 5949 card_port_table[i].sas_address == sas_addr) 5950 return i; 5951 5952 return LEAPRAID_INVALID_INDEX; 5953 } 5954 5955 static u8 leapraid_fill_card_port_table( 5956 struct leapraid_adapter *adapter, 5957 struct leapraid_sas_io_unit_p0 *sas_iounit_p0, 5958 struct leapraid_card_port *new_card_port_table) 5959 { 5960 u8 port_entry_num = 0, port_id; 5961 u16 attached_hdl; 5962 u64 attached_sas_addr; 5963 int i, idx; 5964 5965 for (i = 0; i < adapter->dev_topo.card.phys_num; i++) { 5966 if (sas_iounit_p0->phy_info[i].neg_link_rate >> 5967 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT < 5968 LEAPRAID_SAS_NEG_LINK_RATE_1_5) 5969 continue; 5970 5971 attached_hdl = le16_to_cpu(sas_iounit_p0->phy_info[i] 5972 .attached_dev_hdl); 5973 if (leapraid_get_sas_address(adapter, 5974 attached_hdl, 5975 &attached_sas_addr) != 0) 5976 continue; 5977 5978 port_id = sas_iounit_p0->phy_info[i].port; 5979 5980 idx = leapraid_find_matching_port(new_card_port_table, 5981 port_entry_num, 5982 port_id, 5983 attached_sas_addr); 5984 if (idx >= 0) { 5985 new_card_port_table[idx].phy_mask |= BIT(i); 5986 } else { 5987 new_card_port_table[port_entry_num].port_id = port_id; 5988 new_card_port_table[port_entry_num].phy_mask = BIT(i); 5989 new_card_port_table[port_entry_num].sas_address = 5990 attached_sas_addr; 5991 port_entry_num++; 5992 } 5993 } 5994 5995 return port_entry_num; 5996 } 5997 5998 static u8 leapraid_set_new_card_port_table_after_reset( 5999 struct leapraid_adapter *adapter, 6000 struct leapraid_card_port *new_card_port_table) 6001 { 6002 union cfg_param_1 cfgp1 = {0}; 6003 union cfg_param_2 cfgp2 = {0}; 6004 struct leapraid_sas_io_unit_p0 *sas_iounit_p0; 6005 u8 port_entry_num = 0; 6006 u16 sz; 6007 6008 sz = offsetof(struct leapraid_sas_io_unit_p0, phy_info) + 6009 (adapter->dev_topo.card.phys_num * 6010 sizeof(struct leapraid_sas_io_unit0_phy_info)); 6011 sas_iounit_p0 = kzalloc(sz, GFP_KERNEL); 6012 if (!sas_iounit_p0) 6013 return port_entry_num; 6014 6015 cfgp1.size = sz; 6016 if (leapraid_op_config_page(adapter, sas_iounit_p0, cfgp1, cfgp2, 6017 GET_SAS_IOUNIT_PG0) != 0) 6018 goto out_free; 6019 6020 port_entry_num = leapraid_fill_card_port_table(adapter, 6021 sas_iounit_p0, 6022 new_card_port_table); 6023 out_free: 6024 kfree(sas_iounit_p0); 6025 return port_entry_num; 6026 } 6027 6028 static void leapraid_update_existing_port(struct leapraid_adapter *adapter, 6029 struct leapraid_card_port *new_table, 6030 int entry_idx, int port_entry_num) 6031 { 6032 struct leapraid_card_port *matched_card_port; 6033 int matched_code; 6034 int count, lcount = 0; 6035 u64 sas_addr; 6036 int i; 6037 6038 matched_code = leapraid_check_card_port(adapter, 6039 &new_table[entry_idx], 6040 &matched_card_port, 6041 &count); 6042 6043 if (!matched_card_port) 6044 return; 6045 6046 if (matched_code == SAME_PORT_WITH_PARTIALLY_CHANGED_PHYS || 6047 matched_code == SAME_ADDR_WITH_PARTIALLY_CHANGED_PHYS) { 6048 leapraid_add_or_del_phys_from_existing_port(adapter, 6049 matched_card_port, 6050 new_table, 6051 entry_idx, 6052 port_entry_num); 6053 } else if (matched_code == SAME_ADDR_ONLY) { 6054 sas_addr = new_table[entry_idx].sas_address; 6055 for (i = 0; i < port_entry_num; i++) 6056 if (new_table[i].sas_address == sas_addr) 6057 lcount++; 6058 6059 if (count > 1 || lcount > 1) 6060 return; 6061 6062 leapraid_add_or_del_phys_from_existing_port(adapter, 6063 matched_card_port, 6064 new_table, 6065 entry_idx, 6066 port_entry_num); 6067 } 6068 6069 if (matched_card_port->port_id != new_table[entry_idx].port_id) 6070 matched_card_port->port_id = new_table[entry_idx].port_id; 6071 6072 matched_card_port->flg &= ~LEAPRAID_CARD_PORT_FLG_DIRTY; 6073 matched_card_port->phy_mask = new_table[entry_idx].phy_mask; 6074 } 6075 6076 static void leapraid_update_card_port_after_reset( 6077 struct leapraid_adapter *adapter) 6078 { 6079 struct leapraid_card_port *new_card_port_table; 6080 struct leapraid_card_port *matched_card_port; 6081 u8 port_entry_num; 6082 u8 nr_phys; 6083 int i; 6084 6085 if (leapraid_get_adapter_phys(adapter, &nr_phys) || !nr_phys) 6086 return; 6087 6088 if (!adapter->dev_topo.card.card_phy) { 6089 adapter->dev_topo.card.card_phy = 6090 kzalloc_objs(struct leapraid_card_phy, nr_phys); 6091 if (!adapter->dev_topo.card.card_phy) 6092 return; 6093 } 6094 6095 adapter->dev_topo.card.phys_num = nr_phys; 6096 6097 new_card_port_table = kzalloc_objs(struct leapraid_card_port, 6098 adapter->dev_topo.card.phys_num); 6099 if (!new_card_port_table) 6100 return; 6101 6102 port_entry_num = 6103 leapraid_set_new_card_port_table_after_reset( 6104 adapter, 6105 new_card_port_table); 6106 if (!port_entry_num) 6107 goto out_free_port_table; 6108 6109 list_for_each_entry(matched_card_port, 6110 &adapter->dev_topo.card_port_list, list) 6111 matched_card_port->flg |= LEAPRAID_CARD_PORT_FLG_DIRTY; 6112 6113 matched_card_port = NULL; 6114 for (i = 0; i < port_entry_num; i++) 6115 leapraid_update_existing_port(adapter, 6116 new_card_port_table, 6117 i, port_entry_num); 6118 out_free_port_table: 6119 kfree(new_card_port_table); 6120 } 6121 6122 static bool leapraid_is_valid_vphy( 6123 struct leapraid_adapter *adapter, 6124 struct leapraid_sas_io_unit_p0 *sas_io_unit_p0, 6125 int phy_index) 6126 { 6127 union cfg_param_1 cfgp1 = {0}; 6128 union cfg_param_2 cfgp2 = {0}; 6129 struct leapraid_sas_phy_p0 phy_p0; 6130 u32 dev_info; 6131 6132 if (sas_io_unit_p0->phy_info[phy_index].neg_link_rate >> 6133 LEAPRAID_SAS_NEG_LINK_RATE_SHIFT < 6134 LEAPRAID_SAS_NEG_LINK_RATE_1_5) 6135 return false; 6136 6137 dev_info = le32_to_cpu(sas_io_unit_p0->phy_info[phy_index] 6138 .controller_phy_dev_info); 6139 if (!(dev_info & LEAPRAID_DEVTYP_SEP)) 6140 return false; 6141 6142 cfgp1.phy_number = phy_index; 6143 if (leapraid_op_config_page(adapter, &phy_p0, cfgp1, cfgp2, 6144 GET_PHY_PG0)) 6145 return false; 6146 6147 if (!(le32_to_cpu(phy_p0.phy_info) & LEAPRAID_SAS_PHYINFO_VPHY)) 6148 return false; 6149 6150 return true; 6151 } 6152 6153 static void leapraid_update_vphy_binding(struct leapraid_adapter *adapter, 6154 struct leapraid_card_port *card_port, 6155 struct leapraid_vphy *vphy, 6156 int phy_index, u8 may_new_port_id, 6157 u64 attached_sas_addr) 6158 { 6159 struct leapraid_card_port *may_new_card_port; 6160 struct leapraid_sas_dev *sas_dev; 6161 6162 may_new_card_port = leapraid_get_port_by_id(adapter, 6163 may_new_port_id, 6164 true); 6165 if (!may_new_card_port) { 6166 may_new_card_port = kzalloc_obj(*may_new_card_port); 6167 if (!may_new_card_port) 6168 return; 6169 may_new_card_port->port_id = may_new_port_id; 6170 dev_err(&adapter->pdev->dev, 6171 "%s: New card port %p added, port=%d\n", 6172 __func__, may_new_card_port, may_new_port_id); 6173 list_add_tail(&may_new_card_port->list, 6174 &adapter->dev_topo.card_port_list); 6175 } 6176 6177 if (card_port != may_new_card_port) { 6178 if (!may_new_card_port->vphys_mask) 6179 INIT_LIST_HEAD(&may_new_card_port->vphys_list); 6180 may_new_card_port->vphys_mask |= BIT(phy_index); 6181 card_port->vphys_mask &= ~BIT(phy_index); 6182 list_move(&vphy->list, &may_new_card_port->vphys_list); 6183 6184 sas_dev = leapraid_get_sas_dev_by_addr(adapter, 6185 attached_sas_addr, 6186 card_port); 6187 if (sas_dev) { 6188 sas_dev->card_port = may_new_card_port; 6189 leapraid_sdev_put(sas_dev); 6190 } 6191 } 6192 6193 if (may_new_card_port->flg & LEAPRAID_CARD_PORT_FLG_DIRTY) { 6194 may_new_card_port->sas_address = 0; 6195 may_new_card_port->phy_mask = 0; 6196 may_new_card_port->flg &= ~LEAPRAID_CARD_PORT_FLG_DIRTY; 6197 } 6198 vphy->flg &= ~LEAPRAID_VPHY_FLG_DIRTY; 6199 } 6200 6201 static void leapraid_update_vphys_after_reset(struct leapraid_adapter *adapter) 6202 { 6203 union cfg_param_1 cfgp1 = {0}; 6204 union cfg_param_2 cfgp2 = {0}; 6205 struct leapraid_sas_io_unit_p0 *sas_iounit_p0; 6206 struct leapraid_card_port *card_port, *card_port_next; 6207 struct leapraid_vphy *vphy, *vphy_next; 6208 u64 attached_sas_addr; 6209 u16 sz; 6210 u16 attached_hdl; 6211 bool found = false; 6212 u8 port_id; 6213 int i; 6214 6215 list_for_each_entry_safe(card_port, card_port_next, 6216 &adapter->dev_topo.card_port_list, list) { 6217 if (!card_port->vphys_mask) 6218 continue; 6219 6220 list_for_each_entry_safe(vphy, vphy_next, 6221 &card_port->vphys_list, list) 6222 vphy->flg |= LEAPRAID_VPHY_FLG_DIRTY; 6223 } 6224 6225 sz = offsetof(struct leapraid_sas_io_unit_p0, phy_info) + 6226 (adapter->dev_topo.card.phys_num * 6227 sizeof(struct leapraid_sas_io_unit0_phy_info)); 6228 sas_iounit_p0 = kzalloc(sz, GFP_KERNEL); 6229 if (!sas_iounit_p0) 6230 return; 6231 6232 cfgp1.size = sz; 6233 if (leapraid_op_config_page(adapter, sas_iounit_p0, cfgp1, cfgp2, 6234 GET_SAS_IOUNIT_PG0) != 0) 6235 goto out_free; 6236 6237 for (i = 0; i < adapter->dev_topo.card.phys_num; i++) { 6238 if (!leapraid_is_valid_vphy(adapter, sas_iounit_p0, i)) 6239 continue; 6240 6241 attached_hdl = 6242 le16_to_cpu(sas_iounit_p0->phy_info[i] 6243 .attached_dev_hdl); 6244 if (leapraid_get_sas_address(adapter, attached_hdl, 6245 &attached_sas_addr) != 0) 6246 continue; 6247 6248 found = false; 6249 card_port = NULL; 6250 card_port_next = NULL; 6251 list_for_each_entry_safe(card_port, card_port_next, 6252 &adapter->dev_topo.card_port_list, 6253 list) { 6254 if (!card_port->vphys_mask) 6255 continue; 6256 6257 list_for_each_entry_safe(vphy, vphy_next, 6258 &card_port->vphys_list, 6259 list) { 6260 if (!(vphy->flg & LEAPRAID_VPHY_FLG_DIRTY)) 6261 continue; 6262 6263 if (vphy->sas_address != attached_sas_addr) 6264 continue; 6265 6266 if (!(vphy->phy_mask & BIT(i))) 6267 vphy->phy_mask = BIT(i); 6268 6269 port_id = sas_iounit_p0->phy_info[i].port; 6270 6271 leapraid_update_vphy_binding(adapter, 6272 card_port, 6273 vphy, 6274 i, 6275 port_id, 6276 attached_sas_addr); 6277 6278 found = true; 6279 break; 6280 } 6281 if (found) 6282 break; 6283 } 6284 } 6285 out_free: 6286 kfree(sas_iounit_p0); 6287 } 6288 6289 static void leapraid_mark_all_dev_deleted(struct leapraid_adapter *adapter) 6290 { 6291 struct leapraid_sdev_priv *sdev_priv; 6292 struct scsi_device *sdev; 6293 6294 shost_for_each_device(sdev, adapter->shost) { 6295 sdev_priv = sdev->hostdata; 6296 if (sdev_priv && sdev_priv->starget_priv) 6297 sdev_priv->starget_priv->deleted = 1; 6298 } 6299 } 6300 6301 static void leapraid_free_enc_list(struct leapraid_adapter *adapter) 6302 { 6303 struct leapraid_enc_node *enc_dev, *enc_dev_next; 6304 LIST_HEAD(free_list); 6305 unsigned long flags; 6306 6307 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags); 6308 list_splice_init(&adapter->dev_topo.enc_list, &free_list); 6309 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags); 6310 6311 list_for_each_entry_safe(enc_dev, enc_dev_next, &free_list, list) { 6312 list_del(&enc_dev->list); 6313 kfree(enc_dev); 6314 } 6315 } 6316 6317 static void leapraid_rebuild_enc_list_after_reset( 6318 struct leapraid_adapter *adapter) 6319 { 6320 union cfg_param_1 cfgp1 = {0}; 6321 union cfg_param_2 cfgp2 = {0}; 6322 struct leapraid_enc_node *enc_node; 6323 u16 enc_hdl; 6324 unsigned long flags; 6325 int rc; 6326 6327 leapraid_free_enc_list(adapter); 6328 6329 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP; 6330 for (enc_hdl = 0xFFFF; ; enc_hdl = le16_to_cpu(enc_node->pg0.enc_hdl)) { 6331 enc_node = kzalloc_obj(*enc_node); 6332 if (!enc_node) 6333 return; 6334 6335 cfgp2.handle = enc_hdl; 6336 rc = leapraid_op_config_page(adapter, &enc_node->pg0, cfgp1, 6337 cfgp2, GET_SAS_ENCLOSURE_PG0); 6338 if (rc) { 6339 kfree(enc_node); 6340 return; 6341 } 6342 6343 spin_lock_irqsave(&adapter->dev_topo.enc_lock, flags); 6344 list_add_tail(&enc_node->list, &adapter->dev_topo.enc_list); 6345 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, flags); 6346 } 6347 } 6348 6349 static void leapraid_mark_resp_sas_dev(struct leapraid_adapter *adapter, 6350 struct leapraid_sas_dev_p0 *sas_dev_p0) 6351 { 6352 struct leapraid_starget_priv *starget_priv; 6353 struct leapraid_enc_node *enc_node = NULL; 6354 struct leapraid_card_port *card_port; 6355 struct leapraid_sas_dev *sas_dev; 6356 struct scsi_target *starget; 6357 unsigned long flags; 6358 unsigned long enc_flags = 0; 6359 u16 enc_hdl; 6360 u64 enc_lid = 0; 6361 6362 card_port = leapraid_get_port_by_id(adapter, sas_dev_p0->physical_port, 6363 false); 6364 enc_hdl = le16_to_cpu(sas_dev_p0->enc_hdl); 6365 if (enc_hdl) { 6366 spin_lock_irqsave(&adapter->dev_topo.enc_lock, enc_flags); 6367 enc_node = leapraid_enc_find_by_hdl(adapter, enc_hdl); 6368 if (enc_node) 6369 enc_lid = le64_to_cpu(enc_node->pg0.enc_lid); 6370 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, enc_flags); 6371 if (!enc_node) 6372 dev_info(&adapter->pdev->dev, 6373 "enc hdl 0x%04x has no matched enc dev\n", 6374 enc_hdl); 6375 } 6376 6377 spin_lock_irqsave(&adapter->dev_topo.sas_dev_lock, flags); 6378 list_for_each_entry(sas_dev, &adapter->dev_topo.sas_dev_list, list) { 6379 if (sas_dev->sas_addr != le64_to_cpu(sas_dev_p0->sas_address) || 6380 sas_dev->slot != le16_to_cpu(sas_dev_p0->slot) || 6381 sas_dev->card_port != card_port) 6382 continue; 6383 6384 sas_dev->resp = 1; 6385 starget = sas_dev->starget; 6386 if (starget && starget->hostdata) { 6387 starget_priv = starget->hostdata; 6388 starget_priv->tm_busy = 0; 6389 starget_priv->deleted = 0; 6390 } else { 6391 starget_priv = NULL; 6392 } 6393 6394 if (starget) { 6395 starget_printk( 6396 KERN_INFO, starget, 6397 "dev: hdl=0x%04x saddr=0x%016llx port_id=%d\n", 6398 sas_dev->hdl, 6399 (unsigned long long)sas_dev->sas_addr, 6400 sas_dev->card_port->port_id); 6401 if (sas_dev->enc_hdl != 0) 6402 starget_printk( 6403 KERN_INFO, 6404 starget, 6405 "enc info: enc_lid=0x%016llx slot=%d\n", 6406 (unsigned long long)sas_dev->enc_lid, 6407 sas_dev->slot); 6408 } 6409 6410 if (le16_to_cpu(sas_dev_p0->flg) & 6411 LEAPRAID_SAS_DEV_P0_FLG_ENC_LEVEL_VALID) { 6412 sas_dev->enc_level = sas_dev_p0->enc_level; 6413 memcpy(sas_dev->connector_name, 6414 sas_dev_p0->connector_name, 6415 LEAPRAID_SAS_DEV_P0_CON_NAME_LEN); 6416 sas_dev->connector_name[ 6417 LEAPRAID_SAS_DEV_P0_CON_NAME_LEN] = '\0'; 6418 } else { 6419 sas_dev->enc_level = 0; 6420 sas_dev->connector_name[0] = '\0'; 6421 } 6422 6423 sas_dev->enc_hdl = enc_hdl; 6424 sas_dev->enc_lid = enc_lid; 6425 6426 if (sas_dev->hdl == le16_to_cpu(sas_dev_p0->dev_hdl)) 6427 goto unlock; 6428 6429 dev_info(&adapter->pdev->dev, 6430 "hdl changed: 0x%04x -> 0x%04x\n", 6431 sas_dev->hdl, sas_dev_p0->dev_hdl); 6432 sas_dev->hdl = le16_to_cpu(sas_dev_p0->dev_hdl); 6433 if (starget_priv) 6434 starget_priv->hdl = le16_to_cpu(sas_dev_p0->dev_hdl); 6435 6436 goto unlock; 6437 } 6438 unlock: 6439 spin_unlock_irqrestore(&adapter->dev_topo.sas_dev_lock, flags); 6440 } 6441 6442 static void leapraid_search_resp_sas_dev(struct leapraid_adapter *adapter) 6443 { 6444 union cfg_param_1 cfgp1 = {0}; 6445 union cfg_param_2 cfgp2 = {0}; 6446 struct leapraid_sas_dev_p0 sas_dev_p0; 6447 u32 device_info; 6448 6449 if (list_empty(&adapter->dev_topo.sas_dev_list)) 6450 return; 6451 6452 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP; 6453 for (cfgp2.handle = 0xFFFF; 6454 !leapraid_op_config_page(adapter, &sas_dev_p0, 6455 cfgp1, cfgp2, GET_SAS_DEVICE_PG0); 6456 cfgp2.handle = le16_to_cpu(sas_dev_p0.dev_hdl)) { 6457 device_info = le32_to_cpu(sas_dev_p0.dev_info); 6458 if (!(leapraid_is_end_dev(device_info))) 6459 continue; 6460 6461 leapraid_mark_resp_sas_dev(adapter, &sas_dev_p0); 6462 } 6463 } 6464 6465 static void leapraid_mark_resp_raid_volume(struct leapraid_adapter *adapter, 6466 u64 wwid, u16 hdl) 6467 { 6468 struct leapraid_raid_volume *raid_volume; 6469 struct leapraid_starget_priv *starget_priv = NULL; 6470 struct scsi_target *starget; 6471 unsigned long flags; 6472 u64 volume_wwid; 6473 u16 old_hdl; 6474 6475 raid_volume = leapraid_raid_volume_find_by_wwid(adapter, wwid); 6476 if (!raid_volume) 6477 return; 6478 6479 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags); 6480 if (!raid_volume->starget) { 6481 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, 6482 flags); 6483 leapraid_raid_volume_put(raid_volume); 6484 return; 6485 } 6486 6487 starget = raid_volume->starget; 6488 if (starget->hostdata) { 6489 starget_priv = starget->hostdata; 6490 starget_priv->deleted = 0; 6491 } 6492 6493 raid_volume->resp = 1; 6494 volume_wwid = raid_volume->wwid; 6495 old_hdl = raid_volume->hdl; 6496 if (old_hdl != hdl) { 6497 raid_volume->hdl = hdl; 6498 if (starget_priv) 6499 starget_priv->hdl = hdl; 6500 } 6501 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags); 6502 6503 starget_printk(KERN_INFO, starget, 6504 "raid volume: hdl=0x%04x, wwid=0x%016llx\n", 6505 hdl, (unsigned long long)volume_wwid); 6506 if (old_hdl != hdl) 6507 dev_info(&adapter->pdev->dev, 6508 "hdl changed: 0x%04x -> 0x%04x\n", 6509 old_hdl, hdl); 6510 6511 leapraid_raid_volume_put(raid_volume); 6512 } 6513 6514 static void leapraid_search_resp_raid_volume(struct leapraid_adapter *adapter) 6515 { 6516 union cfg_param_1 cfgp1 = {0}; 6517 union cfg_param_1 cfgp1_extra = {0}; 6518 union cfg_param_2 cfgp2 = {0}; 6519 union cfg_param_2 cfgp2_extra = {0}; 6520 struct leapraid_raidvol_p1 raidvol_p1; 6521 struct leapraid_raidvol_p0 raidvol_p0; 6522 struct leapraid_raidpd_p0 raidpd_p0; 6523 unsigned long flags; 6524 u16 hdl; 6525 u8 phys_disk_num; 6526 bool is_empty; 6527 6528 if (!adapter->adapter_attr.raid_support) 6529 return; 6530 6531 spin_lock_irqsave(&adapter->dev_topo.raid_volume_lock, flags); 6532 is_empty = list_empty(&adapter->dev_topo.raid_volume_list); 6533 spin_unlock_irqrestore(&adapter->dev_topo.raid_volume_lock, flags); 6534 if (is_empty) 6535 return; 6536 6537 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP; 6538 for (hdl = 0xFFFF, cfgp2.handle = hdl; 6539 !leapraid_op_config_page(adapter, &raidvol_p1, cfgp1, cfgp2, 6540 GET_RAID_VOLUME_PG1); 6541 cfgp2.handle = hdl) { 6542 hdl = le16_to_cpu(raidvol_p1.dev_hdl); 6543 cfgp1_extra.size = sizeof(struct leapraid_raidvol_p0); 6544 cfgp2_extra.handle = hdl; 6545 if (leapraid_op_config_page(adapter, &raidvol_p0, cfgp1_extra, 6546 cfgp2_extra, GET_RAID_VOLUME_PG0)) 6547 continue; 6548 6549 if (raidvol_p0.volume_state == LEAPRAID_VOL_STATE_OPTIMAL || 6550 raidvol_p0.volume_state == LEAPRAID_VOL_STATE_ONLINE || 6551 raidvol_p0.volume_state == LEAPRAID_VOL_STATE_DEGRADED) 6552 leapraid_mark_resp_raid_volume( 6553 adapter, 6554 le64_to_cpu(raidvol_p1.wwid), 6555 hdl); 6556 } 6557 6558 memset(adapter->dev_topo.pd_hdls, 0, adapter->dev_topo.pd_hdls_sz); 6559 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP; 6560 for (phys_disk_num = 0xFF, cfgp2.form_specific = phys_disk_num; 6561 !leapraid_op_config_page(adapter, &raidpd_p0, cfgp1, cfgp2, 6562 GET_PHY_DISK_PG0); 6563 cfgp2.form_specific = phys_disk_num) { 6564 phys_disk_num = raidpd_p0.phys_disk_num; 6565 hdl = le16_to_cpu(raidpd_p0.dev_hdl); 6566 if (!hdl || 6567 hdl > adapter->adapter_attr.features.max_dev_handle) 6568 dev_warn(&adapter->pdev->dev, 6569 "%s: Invalid device handle\n", __func__); 6570 else 6571 set_bit(hdl, adapter->dev_topo.pd_hdls); 6572 } 6573 } 6574 6575 static void leapraid_mark_resp_exp(struct leapraid_adapter *adapter, 6576 struct leapraid_exp_p0 *exp_pg0) 6577 { 6578 struct leapraid_enc_node *enc_node = NULL; 6579 struct leapraid_topo_node *topo_node_exp; 6580 u16 enc_hdl = le16_to_cpu(exp_pg0->enc_hdl); 6581 u64 sas_address = le64_to_cpu(exp_pg0->sas_address); 6582 u16 hdl = le16_to_cpu(exp_pg0->dev_hdl); 6583 u8 port_id = exp_pg0->physical_port; 6584 struct leapraid_card_port *card_port = leapraid_get_port_by_id(adapter, 6585 port_id, 6586 false); 6587 unsigned long flags; 6588 unsigned long enc_flags = 0; 6589 u64 enc_lid = 0; 6590 int i; 6591 6592 if (enc_hdl) { 6593 spin_lock_irqsave(&adapter->dev_topo.enc_lock, enc_flags); 6594 enc_node = leapraid_enc_find_by_hdl(adapter, enc_hdl); 6595 if (enc_node) 6596 enc_lid = le64_to_cpu(enc_node->pg0.enc_lid); 6597 spin_unlock_irqrestore(&adapter->dev_topo.enc_lock, enc_flags); 6598 } 6599 6600 spin_lock_irqsave(&adapter->dev_topo.topo_node_lock, flags); 6601 list_for_each_entry(topo_node_exp, &adapter->dev_topo.exp_list, list) { 6602 if (topo_node_exp->sas_address != sas_address || 6603 topo_node_exp->card_port != card_port) 6604 continue; 6605 6606 topo_node_exp->resp = 1; 6607 topo_node_exp->enc_hdl = enc_hdl; 6608 topo_node_exp->enc_lid = enc_lid; 6609 if (topo_node_exp->hdl == hdl) 6610 goto unlock; 6611 6612 dev_info(&adapter->pdev->dev, 6613 "hdl changed: 0x%04x -> 0x%04x\n", 6614 topo_node_exp->hdl, hdl); 6615 topo_node_exp->hdl = hdl; 6616 for (i = 0; i < topo_node_exp->phys_num; i++) 6617 topo_node_exp->card_phy[i].hdl = hdl; 6618 goto unlock; 6619 } 6620 unlock: 6621 spin_unlock_irqrestore(&adapter->dev_topo.topo_node_lock, flags); 6622 } 6623 6624 static void leapraid_search_resp_exp(struct leapraid_adapter *adapter) 6625 { 6626 union cfg_param_1 cfgp1 = {0}; 6627 union cfg_param_2 cfgp2 = {0}; 6628 struct leapraid_exp_p0 exp_p0; 6629 u64 sas_address; 6630 u16 hdl; 6631 u8 port; 6632 6633 if (list_empty(&adapter->dev_topo.exp_list)) 6634 return; 6635 6636 cfgp1.form = LEAPRAID_SAS_CFG_PGAD_GET_NEXT_LOOP; 6637 for (hdl = 0xFFFF, cfgp2.handle = hdl; 6638 !leapraid_op_config_page(adapter, &exp_p0, cfgp1, cfgp2, 6639 GET_SAS_EXPANDER_PG0); 6640 cfgp2.handle = hdl) { 6641 hdl = le16_to_cpu(exp_p0.dev_hdl); 6642 sas_address = le64_to_cpu(exp_p0.sas_address); 6643 port = exp_p0.physical_port; 6644 6645 dev_dbg(&adapter->pdev->dev, 6646 "exp detected: hdl=0x%04x, sas=0x%016llx, port=%u", 6647 hdl, (unsigned long long)sas_address, 6648 adapter->adapter_attr.enable_mp ? port : 6649 LEAPRAID_DISABLE_MP_PORT_ID); 6650 leapraid_mark_resp_exp(adapter, &exp_p0); 6651 } 6652 } 6653 6654 void leapraid_wait_cmds_done(struct leapraid_adapter *adapter) 6655 { 6656 struct leapraid_io_req_tracker *io_req_tracker; 6657 unsigned long flags; 6658 u16 i; 6659 6660 adapter->reset_desc.pending_io_cnt = 0; 6661 if (!leapraid_pci_active(adapter)) { 6662 dev_err(&adapter->pdev->dev, 6663 "%s %s: PCI error, device reset or unplugged!\n", 6664 adapter->adapter_attr.name, __func__); 6665 return; 6666 } 6667 6668 if (leapraid_get_adapter_state(adapter) != LEAPRAID_DB_OPERATIONAL) 6669 return; 6670 6671 spin_lock_irqsave(&adapter->dynamic_task_desc.task_lock, flags); 6672 for (i = 1; i <= adapter->shost->can_queue; i++) { 6673 io_req_tracker = leapraid_get_io_tracker_from_taskid(adapter, 6674 i); 6675 if (io_req_tracker && io_req_tracker->taskid != 0 && 6676 io_req_tracker->scmd) 6677 adapter->reset_desc.pending_io_cnt++; 6678 } 6679 spin_unlock_irqrestore(&adapter->dynamic_task_desc.task_lock, flags); 6680 6681 if (!adapter->reset_desc.pending_io_cnt) 6682 return; 6683 6684 wait_event_timeout(adapter->reset_desc.reset_wait_queue, 6685 adapter->reset_desc.pending_io_cnt == 0, 6686 LEAPRAID_IO_CMD_TIMEOUT * HZ); 6687 } 6688 6689 int leapraid_hard_reset_handler(struct leapraid_adapter *adapter, 6690 enum reset_type type) 6691 { 6692 unsigned long flags; 6693 bool wake = false; 6694 int rc; 6695 6696 mutex_lock(&adapter->reset_desc.adapter_reset_mutex); 6697 6698 if (adapter->access_ctrl.shost_recover_async) { 6699 rc = adapter->reset_desc.adapter_reset_results; 6700 dev_info(&adapter->pdev->dev, 6701 "Skip nested hard reset, async evt running, rc=%d\n", 6702 rc); 6703 mutex_unlock(&adapter->reset_desc.adapter_reset_mutex); 6704 return rc; 6705 } 6706 6707 if (!leapraid_pci_active(adapter)) { 6708 if (leapraid_pci_removed(adapter)) { 6709 dev_info(&adapter->pdev->dev, 6710 "pci_dev removed, pause poll, clean cmds\n"); 6711 leapraid_mq_polling_pause(adapter); 6712 leapraid_clean_active_scsi_cmds(adapter); 6713 leapraid_mq_polling_resume(adapter); 6714 } 6715 dev_err(&adapter->pdev->dev, "PCIe unavailable!\n"); 6716 mutex_unlock(&adapter->reset_desc.adapter_reset_mutex); 6717 return -ENXIO; 6718 } 6719 6720 dev_info(&adapter->pdev->dev, "Starting hard reset\n"); 6721 6722 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags); 6723 adapter->access_ctrl.shost_recovering = 1; 6724 adapter->access_ctrl.shost_recover_async = 1; 6725 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags); 6726 6727 leapraid_wait_cmds_done(adapter); 6728 leapraid_mask_int(adapter); 6729 leapraid_mq_polling_pause(adapter); 6730 rc = leapraid_make_adapter_ready(adapter, type); 6731 if (rc) { 6732 dev_err(&adapter->pdev->dev, 6733 "Failed to make adapter ready, rc=%d\n", rc); 6734 goto out_cleanup; 6735 } 6736 6737 rc = leapraid_fw_log_init(adapter); 6738 if (rc) { 6739 dev_err(&adapter->pdev->dev, "Firmware log init failed\n"); 6740 goto out_cleanup; 6741 } 6742 6743 leapraid_clean_active_cmds(adapter); 6744 if (adapter->scan_dev_desc.driver_loading && 6745 adapter->scan_dev_desc.scan_dev_failed) { 6746 dev_err(&adapter->pdev->dev, 6747 "Previous device scan failed or driver loading\n"); 6748 adapter->access_ctrl.host_removing = 1; 6749 rc = -EFAULT; 6750 goto out_cleanup; 6751 } 6752 6753 rc = leapraid_make_adapter_available(adapter); 6754 if (!rc) { 6755 dev_info(&adapter->pdev->dev, 6756 "Adapter is now available, rebuilding topology\n"); 6757 if (adapter->adapter_attr.enable_mp) { 6758 leapraid_update_card_port_after_reset(adapter); 6759 leapraid_update_vphys_after_reset(adapter); 6760 } 6761 leapraid_mark_all_dev_deleted(adapter); 6762 leapraid_rebuild_enc_list_after_reset(adapter); 6763 leapraid_search_resp_sas_dev(adapter); 6764 leapraid_search_resp_raid_volume(adapter); 6765 leapraid_search_resp_exp(adapter); 6766 leapraid_hardreset_barrier(adapter); 6767 } 6768 out_cleanup: 6769 if (rc) 6770 dev_err(&adapter->pdev->dev, "Hard reset failed\n"); 6771 6772 spin_lock_irqsave(&adapter->reset_desc.adapter_reset_lock, flags); 6773 adapter->reset_desc.adapter_reset_results = rc; 6774 adapter->access_ctrl.shost_recovering = 0; 6775 wake_up(&adapter->access_ctrl.recovery_waitq); 6776 if (rc) { 6777 adapter->access_ctrl.shost_recover_async = 0; 6778 wake = true; 6779 } 6780 spin_unlock_irqrestore(&adapter->reset_desc.adapter_reset_lock, flags); 6781 if (wake) 6782 wake_up(&adapter->access_ctrl.shost_recover_wq); 6783 6784 adapter->reset_desc.reset_cnt++; 6785 mutex_unlock(&adapter->reset_desc.adapter_reset_mutex); 6786 6787 if (rc) 6788 leapraid_clean_active_scsi_cmds(adapter); 6789 leapraid_mq_polling_resume(adapter); 6790 6791 return rc; 6792 } 6793 6794 static int leapraid_get_adapter_features(struct leapraid_adapter *adapter) 6795 { 6796 struct leapraid_adapter_features_req leap_mpi_req; 6797 struct leapraid_adapter_features_rep leap_mpi_rep; 6798 u8 fw_major, fw_minor, fw_build, fw_release; 6799 u32 req_sz; 6800 u32 rep_sz; 6801 u32 db; 6802 int r; 6803 6804 db = leapraid_readl(&adapter->iomem_base->db); 6805 if (db & LEAPRAID_DB_USED || 6806 (db & LEAPRAID_DB_MASK) == LEAPRAID_DB_FAULT) { 6807 dev_err(&adapter->pdev->dev, 6808 "%s: Doorbell used or fault\n", __func__); 6809 return -EFAULT; 6810 } 6811 6812 if ((db & LEAPRAID_DB_MASK) != LEAPRAID_DB_READY && 6813 (db & LEAPRAID_DB_MASK) != LEAPRAID_DB_OPERATIONAL && 6814 !leapraid_wait_adapter_ready(adapter)) { 6815 dev_err(&adapter->pdev->dev, 6816 "%s: adapter not ready\n", __func__); 6817 return -EFAULT; 6818 } 6819 6820 req_sz = sizeof(struct leapraid_adapter_features_req); 6821 rep_sz = sizeof(struct leapraid_adapter_features_rep); 6822 memset(&leap_mpi_req, 0, req_sz); 6823 memset(&leap_mpi_rep, 0, rep_sz); 6824 leap_mpi_req.func = LEAPRAID_FUNC_GET_ADAPTER_FEATURES; 6825 r = leapraid_handshake_func(adapter, 6826 req_sz, 6827 (u32 *)&leap_mpi_req, 6828 rep_sz, 6829 (u16 *)&leap_mpi_rep); 6830 if (r) { 6831 dev_err(&adapter->pdev->dev, 6832 "%s %s: Handshake failed, r=%d\n", 6833 adapter->adapter_attr.name, __func__, r); 6834 return r; 6835 } 6836 6837 memset(&adapter->adapter_attr.features, 0, 6838 sizeof(struct leapraid_adapter_features)); 6839 adapter->adapter_attr.features.req_slot = 6840 le16_to_cpu(leap_mpi_rep.req_slot); 6841 adapter->adapter_attr.features.hp_slot = 6842 le16_to_cpu(leap_mpi_rep.hp_slot); 6843 adapter->adapter_attr.features.adapter_caps = 6844 le32_to_cpu(leap_mpi_rep.adapter_caps); 6845 adapter->adapter_attr.features.max_msix_vectors = 6846 leap_mpi_rep.max_msix_vectors; 6847 adapter->adapter_attr.features.max_volumes = 6848 leap_mpi_rep.max_volumes; 6849 if (!adapter->adapter_attr.features.max_volumes) 6850 adapter->adapter_attr.features.max_volumes = 6851 LEAPRAID_MAX_VOLUMES_DEFAULT; 6852 adapter->adapter_attr.features.max_dev_handle = 6853 le16_to_cpu(leap_mpi_rep.max_dev_hdl); 6854 if (!adapter->adapter_attr.features.max_dev_handle) 6855 adapter->adapter_attr.features.max_dev_handle = 6856 LEAPRAID_MAX_DEV_HANDLE_DEFAULT; 6857 adapter->adapter_attr.features.min_dev_handle = 6858 le16_to_cpu(leap_mpi_rep.min_dev_hdl); 6859 if (adapter->adapter_attr.features.adapter_caps & 6860 LEAPRAID_ADAPTER_FEATURES_CAP_INTEGRATED_RAID) 6861 adapter->adapter_attr.raid_support = 1; 6862 adapter->adapter_attr.wideport_max_queue_depth = 6863 le16_to_cpu(leap_mpi_rep.sas_wide_max_qdepth) ? 6864 le16_to_cpu(leap_mpi_rep.sas_wide_max_qdepth) : 6865 LEAPRAID_SAS_QUEUE_DEPTH; 6866 adapter->adapter_attr.narrowport_max_queue_depth = 6867 le16_to_cpu(leap_mpi_rep.sas_narrow_max_qdepth) ? 6868 le16_to_cpu(leap_mpi_rep.sas_narrow_max_qdepth) : 6869 LEAPRAID_SAS_QUEUE_DEPTH; 6870 adapter->adapter_attr.sata_max_queue_depth = 6871 leap_mpi_rep.sata_max_qdepth ? 6872 leap_mpi_rep.sata_max_qdepth : 6873 LEAPRAID_SATA_QUEUE_DEPTH; 6874 adapter->adapter_attr.raid_volume_max_queue_depth = 6875 LEAPRAID_RAID_QUEUE_DEPTH; 6876 dev_info(&adapter->pdev->dev, 6877 "max: wp qd=%d, np qd=%d, SATA qd=%d, raid qd=%d\n", 6878 adapter->adapter_attr.wideport_max_queue_depth, 6879 adapter->adapter_attr.narrowport_max_queue_depth, 6880 adapter->adapter_attr.sata_max_queue_depth, 6881 adapter->adapter_attr.raid_volume_max_queue_depth); 6882 if (WARN_ON(!(adapter->adapter_attr.features.adapter_caps & 6883 LEAPRAID_ADAPTER_FEATURES_CAP_ATOMIC_REQ))) 6884 return -EFAULT; 6885 adapter->adapter_attr.features.fw_version = 6886 le32_to_cpu(leap_mpi_rep.fw_version); 6887 6888 fw_major = (adapter->adapter_attr.features.fw_version >> 6889 LEAPRAID_VER_MAJOR_SHIFT) & LEAPRAID_VER_MASK; 6890 fw_minor = (adapter->adapter_attr.features.fw_version >> 6891 LEAPRAID_VER_MINOR_SHIFT) & LEAPRAID_VER_MASK; 6892 fw_build = (adapter->adapter_attr.features.fw_version >> 6893 LEAPRAID_VER_BUILD_SHIFT) & LEAPRAID_VER_MASK; 6894 fw_release = 6895 adapter->adapter_attr.features.fw_version & LEAPRAID_VER_MASK; 6896 6897 dev_info(&adapter->pdev->dev, 6898 "Firmware version: %u.%u.%u.%u (0x%08x)\n", 6899 fw_major, fw_minor, fw_build, fw_release, 6900 adapter->adapter_attr.features.fw_version); 6901 6902 adapter->adapter_attr.features.msg_ver = 6903 le16_to_cpu(leap_mpi_rep.msg_ver); 6904 adapter->adapter_attr.features.product_id = 6905 le16_to_cpu(leap_mpi_rep.product_id); 6906 dev_info(&adapter->pdev->dev, 6907 "message version: 0x%x, product id 0x%x\n", 6908 adapter->adapter_attr.features.msg_ver, 6909 adapter->adapter_attr.features.product_id); 6910 6911 if (adapter->adapter_attr.features.msg_ver < 0x1000) { 6912 dev_err(&adapter->pdev->dev, "Device not supported\n"); 6913 return -EFAULT; 6914 } 6915 adapter->shost->max_id = LEAPRAID_INVALID_INITIAL_VALUE; 6916 6917 return 0; 6918 } 6919 6920 static inline void leapraid_disable_pcie(struct leapraid_adapter *adapter) 6921 { 6922 mutex_lock(&adapter->access_ctrl.pci_access_lock); 6923 if (adapter->iomem_base) { 6924 iounmap(adapter->iomem_base); 6925 adapter->iomem_base = NULL; 6926 } 6927 if (pci_is_enabled(adapter->pdev)) { 6928 pci_release_regions(adapter->pdev); 6929 pci_disable_device(adapter->pdev); 6930 } 6931 mutex_unlock(&adapter->access_ctrl.pci_access_lock); 6932 } 6933 6934 static int leapraid_enable_pcie(struct leapraid_adapter *adapter) 6935 { 6936 u64 dma_mask; 6937 int rc; 6938 6939 rc = pci_enable_device(adapter->pdev); 6940 if (rc) { 6941 dev_err(&adapter->pdev->dev, "Failed to enable PCI device\n"); 6942 return rc; 6943 } 6944 6945 rc = pci_request_regions(adapter->pdev, LEAPRAID_DRIVER_NAME); 6946 if (rc) { 6947 dev_err(&adapter->pdev->dev, 6948 "Failed to obtain PCI resources\n"); 6949 return rc; 6950 } 6951 6952 if (sizeof(dma_addr_t) > 4) { 6953 dma_mask = DMA_BIT_MASK(DMA_64_BITS); 6954 adapter->adapter_attr.use_32_dma_mask = 0; 6955 } else { 6956 dma_mask = DMA_BIT_MASK(DMA_32_BITS); 6957 adapter->adapter_attr.use_32_dma_mask = 1; 6958 } 6959 6960 rc = dma_set_mask_and_coherent(&adapter->pdev->dev, dma_mask); 6961 if (rc) { 6962 dev_err(&adapter->pdev->dev, 6963 "Failed to set %lld DMA mask\n", dma_mask); 6964 return rc; 6965 } 6966 adapter->iomem_base = ioremap(pci_resource_start(adapter->pdev, 0), 6967 sizeof(struct leapraid_reg_base)); 6968 if (!adapter->iomem_base) { 6969 dev_err(&adapter->pdev->dev, 6970 "Failed to map memory for controller registers\n"); 6971 return -ENOMEM; 6972 } 6973 6974 pci_set_master(adapter->pdev); 6975 6976 return 0; 6977 } 6978 6979 static void leapraid_cpus_on_irq(struct leapraid_adapter *adapter) 6980 { 6981 struct leapraid_int_rq *int_rq; 6982 unsigned int i, base_group, this_group; 6983 unsigned int cpu, nr_cpus, total_msix, index; 6984 6985 total_msix = adapter->notification_desc.iopoll_qdex; 6986 nr_cpus = num_online_cpus(); 6987 6988 if (!nr_cpus || !total_msix) 6989 return; 6990 base_group = nr_cpus / total_msix; 6991 6992 cpu = cpumask_first(cpu_online_mask); 6993 for (index = 0; index < adapter->notification_desc.iopoll_qdex; 6994 index++) { 6995 int_rq = &adapter->notification_desc.int_rqs[index]; 6996 6997 if (cpu >= adapter->notification_desc.msix_cpu_map_sz) 6998 break; 6999 7000 this_group = base_group + 7001 (index < (nr_cpus % total_msix) ? 1 : 0); 7002 7003 for (i = 0 ; i < this_group ; i++) { 7004 if (cpu >= adapter->notification_desc.msix_cpu_map_sz) 7005 break; 7006 7007 adapter->notification_desc.msix_cpu_map[cpu] = 7008 int_rq->rq.msix_idx; 7009 cpu = cpumask_next(cpu, cpu_online_mask); 7010 } 7011 } 7012 } 7013 7014 static void leapraid_map_msix_to_cpu(struct leapraid_adapter *adapter) 7015 { 7016 struct leapraid_int_rq *int_rq; 7017 const cpumask_t *affinity_mask; 7018 int cpu; 7019 u32 i; 7020 7021 if (!adapter->adapter_attr.rq_cnt) 7022 return; 7023 7024 for (i = 0; i < adapter->notification_desc.iopoll_qdex; i++) { 7025 int_rq = &adapter->notification_desc.int_rqs[i]; 7026 affinity_mask = pci_irq_get_affinity(adapter->pdev, 7027 int_rq->rq.msix_idx); 7028 if (!affinity_mask) { 7029 dev_warn(&adapter->pdev->dev, 7030 "%s: IRQ affinity NULL, msix_idx=%d\n", 7031 __func__, int_rq->rq.msix_idx); 7032 goto out_apply_irq_affinity; 7033 } 7034 7035 for_each_cpu_and(cpu, affinity_mask, cpu_online_mask) { 7036 if (cpu >= adapter->notification_desc.msix_cpu_map_sz) 7037 continue; 7038 7039 adapter->notification_desc.msix_cpu_map[cpu] = 7040 int_rq->rq.msix_idx; 7041 } 7042 } 7043 return; 7044 out_apply_irq_affinity: 7045 leapraid_cpus_on_irq(adapter); 7046 } 7047 7048 static int leapraid_alloc_msix_cpu_map(struct leapraid_adapter *adapter) 7049 { 7050 adapter->notification_desc.msix_cpu_map_sz = nr_cpu_ids; 7051 adapter->notification_desc.msix_cpu_map = 7052 kzalloc(adapter->notification_desc.msix_cpu_map_sz, 7053 GFP_KERNEL); 7054 if (!adapter->notification_desc.msix_cpu_map) 7055 return -ENOMEM; 7056 7057 return 0; 7058 } 7059 7060 static void leapraid_configure_reply_queue_affinity( 7061 struct leapraid_adapter *adapter) 7062 { 7063 if (!adapter || !adapter->notification_desc.msix_enable) 7064 return; 7065 7066 leapraid_map_msix_to_cpu(adapter); 7067 } 7068 7069 static void leapraid_free_irq(struct leapraid_adapter *adapter) 7070 { 7071 struct leapraid_int_rq *int_rq; 7072 unsigned int i; 7073 int irq; 7074 7075 for (i = 0; adapter->notification_desc.int_rqs && 7076 i < adapter->notification_desc.int_rqs_allocated; i++) { 7077 int_rq = &adapter->notification_desc.int_rqs[i]; 7078 if (!int_rq) 7079 continue; 7080 7081 irq = pci_irq_vector(adapter->pdev, int_rq->rq.msix_idx); 7082 irq_set_affinity_hint(irq, NULL); 7083 free_irq(irq, &int_rq->rq); 7084 } 7085 adapter->notification_desc.int_rqs_allocated = 0; 7086 7087 if (adapter->notification_desc.irq_vectors_allocated) { 7088 pci_free_irq_vectors(adapter->pdev); 7089 adapter->notification_desc.irq_vectors_allocated = 0; 7090 } 7091 7092 adapter->notification_desc.msix_enable = 0; 7093 7094 kfree(adapter->notification_desc.blk_mq_poll_rqs); 7095 adapter->notification_desc.blk_mq_poll_rqs = NULL; 7096 7097 kfree(adapter->notification_desc.int_rqs); 7098 adapter->notification_desc.int_rqs = NULL; 7099 7100 kfree(adapter->notification_desc.msix_cpu_map); 7101 adapter->notification_desc.msix_cpu_map = NULL; 7102 adapter->notification_desc.msix_cpu_map_sz = 0; 7103 adapter->notification_desc.iopoll_qdex = 0; 7104 adapter->notification_desc.iopoll_qcnt = 0; 7105 } 7106 7107 static int leapraid_setup_irqs(struct leapraid_adapter *adapter) 7108 { 7109 int irq_mode = adapter->notification_desc.irq_mode; 7110 unsigned int i; 7111 int rc = 0; 7112 7113 if (irq_mode == LEAPRAID_INTERRUPT_MODE_MSIX) { 7114 rc = pci_alloc_irq_vectors_affinity( 7115 adapter->pdev, 7116 adapter->notification_desc.iopoll_qdex, 7117 adapter->notification_desc.iopoll_qdex, 7118 PCI_IRQ_MSIX | PCI_IRQ_AFFINITY, NULL); 7119 if (rc < 0) { 7120 dev_err(&adapter->pdev->dev, 7121 "%d MSI/MSIX vectors allocated failed!\n", 7122 adapter->notification_desc.iopoll_qdex); 7123 return rc; 7124 } 7125 7126 adapter->notification_desc.irq_vectors_allocated = 1; 7127 } 7128 7129 for (i = 0; i < adapter->notification_desc.iopoll_qdex; i++) { 7130 adapter->notification_desc.int_rqs[i].rq.adapter = adapter; 7131 adapter->notification_desc.int_rqs[i].rq.msix_idx = i; 7132 atomic_set(&adapter->notification_desc.int_rqs[i].rq.busy, 0); 7133 if (irq_mode == LEAPRAID_INTERRUPT_MODE_MSIX) 7134 snprintf(adapter->notification_desc.int_rqs[i].rq.name, 7135 LEAPRAID_NAME_LENGTH, "%s%u-MSIx%u", 7136 LEAPRAID_DRIVER_NAME, 7137 adapter->adapter_attr.id, i); 7138 else if (irq_mode == LEAPRAID_INTERRUPT_MODE_MSI) 7139 snprintf(adapter->notification_desc.int_rqs[i].rq.name, 7140 LEAPRAID_NAME_LENGTH, "%s%u-MSI%u", 7141 LEAPRAID_DRIVER_NAME, 7142 adapter->adapter_attr.id, i); 7143 7144 rc = request_irq(pci_irq_vector(adapter->pdev, i), 7145 leapraid_irq_handler, 7146 IRQF_SHARED, 7147 adapter->notification_desc.int_rqs[i].rq.name, 7148 &adapter->notification_desc.int_rqs[i].rq); 7149 if (rc) { 7150 dev_err(&adapter->pdev->dev, 7151 "MSI/MSIx: request_irq %s failed!\n", 7152 adapter->notification_desc.int_rqs[i].rq.name); 7153 return rc; 7154 } 7155 adapter->notification_desc.int_rqs_allocated++; 7156 } 7157 7158 return 0; 7159 } 7160 7161 static int leapraid_setup_legacy_int(struct leapraid_adapter *adapter) 7162 { 7163 int rc; 7164 7165 adapter->notification_desc.int_rqs[0].rq.adapter = adapter; 7166 adapter->notification_desc.int_rqs[0].rq.msix_idx = 0; 7167 atomic_set(&adapter->notification_desc.int_rqs[0].rq.busy, 0); 7168 snprintf(adapter->notification_desc.int_rqs[0].rq.name, 7169 LEAPRAID_NAME_LENGTH, "%s%d-LegacyInt", 7170 LEAPRAID_DRIVER_NAME, adapter->adapter_attr.id); 7171 7172 rc = pci_alloc_irq_vectors_affinity( 7173 adapter->pdev, 7174 adapter->notification_desc.iopoll_qdex, 7175 adapter->notification_desc.iopoll_qdex, 7176 PCI_IRQ_INTX | PCI_IRQ_AFFINITY, 7177 NULL); 7178 if (rc < 0) { 7179 dev_err(&adapter->pdev->dev, 7180 "Legacy irq allocated failed!\n"); 7181 return rc; 7182 } 7183 7184 adapter->notification_desc.irq_vectors_allocated = 1; 7185 adapter->notification_desc.irq_mode = LEAPRAID_INTERRUPT_MODE_LEGACY; 7186 rc = request_irq(pci_irq_vector(adapter->pdev, 0), 7187 leapraid_irq_handler, 7188 IRQF_SHARED, 7189 adapter->notification_desc.int_rqs[0].rq.name, 7190 &adapter->notification_desc.int_rqs[0].rq); 7191 if (rc) { 7192 irq_set_affinity_hint(pci_irq_vector(adapter->pdev, 0), NULL); 7193 pci_free_irq_vectors(adapter->pdev); 7194 adapter->notification_desc.irq_vectors_allocated = 0; 7195 dev_err(&adapter->pdev->dev, 7196 "Legacy Int: request_irq %s failed!\n", 7197 adapter->notification_desc.int_rqs[0].rq.name); 7198 return -EBUSY; 7199 } 7200 adapter->notification_desc.int_rqs_allocated = 1; 7201 return rc; 7202 } 7203 7204 static int leapraid_set_legacy_int(struct leapraid_adapter *adapter) 7205 { 7206 int rc; 7207 7208 rc = leapraid_alloc_msix_cpu_map(adapter); 7209 if (rc) 7210 return rc; 7211 7212 adapter->adapter_attr.rq_cnt = 1; 7213 adapter->notification_desc.iopoll_qdex = 7214 adapter->adapter_attr.rq_cnt; 7215 adapter->notification_desc.iopoll_qcnt = 0; 7216 dev_info(&adapter->pdev->dev, 7217 "Legacy Intr: req queue cnt=%d intr=%d/poll=%d rep queues!\n", 7218 adapter->adapter_attr.rq_cnt, 7219 adapter->notification_desc.iopoll_qdex, 7220 adapter->notification_desc.iopoll_qcnt); 7221 adapter->notification_desc.int_rqs = 7222 kzalloc_objs(struct leapraid_int_rq, 7223 adapter->notification_desc.iopoll_qdex); 7224 if (!adapter->notification_desc.int_rqs) 7225 return -ENOMEM; 7226 7227 return leapraid_setup_legacy_int(adapter); 7228 } 7229 7230 static int leapraid_set_msix(struct leapraid_adapter *adapter) 7231 { 7232 int iopoll_qcnt = 0; 7233 unsigned int i; 7234 int rc, msix_cnt; 7235 7236 msix_cnt = pci_msix_vec_count(adapter->pdev); 7237 if (msix_cnt <= 0 || 7238 adapter->adapter_attr.features.max_msix_vectors == 0) { 7239 dev_info(&adapter->pdev->dev, "MSIX unsupported!\n"); 7240 return -EOPNOTSUPP; 7241 } 7242 7243 msix_cnt = min_t(int, msix_cnt, 7244 adapter->adapter_attr.features.max_msix_vectors); 7245 7246 if (reset_devices) 7247 adapter->adapter_attr.rq_cnt = 1; 7248 else 7249 adapter->adapter_attr.rq_cnt = min_t(int, 7250 num_online_cpus(), 7251 msix_cnt); 7252 7253 if (max_msix_vectors > 0) 7254 adapter->adapter_attr.rq_cnt = min_t( 7255 int, max_msix_vectors, adapter->adapter_attr.rq_cnt); 7256 7257 if (adapter->adapter_attr.rq_cnt <= 1) 7258 adapter->shost->host_tagset = 0; 7259 if (adapter->shost->host_tagset) { 7260 iopoll_qcnt = poll_queues; 7261 if (iopoll_qcnt >= adapter->adapter_attr.rq_cnt) 7262 iopoll_qcnt = 0; 7263 } 7264 if (iopoll_qcnt) { 7265 adapter->notification_desc.blk_mq_poll_rqs = 7266 kzalloc_objs(struct leapraid_blk_mq_poll_rq, 7267 iopoll_qcnt); 7268 if (!adapter->notification_desc.blk_mq_poll_rqs) 7269 return -ENOMEM; 7270 adapter->adapter_attr.rq_cnt = 7271 min(adapter->adapter_attr.rq_cnt + iopoll_qcnt, 7272 msix_cnt); 7273 } 7274 7275 adapter->notification_desc.iopoll_qdex = 7276 adapter->adapter_attr.rq_cnt - iopoll_qcnt; 7277 7278 adapter->notification_desc.iopoll_qcnt = iopoll_qcnt; 7279 dev_info(&adapter->pdev->dev, 7280 "MSIx: req queue cnt=%d, intr=%d/poll=%d rep queues!\n", 7281 adapter->adapter_attr.rq_cnt, 7282 adapter->notification_desc.iopoll_qdex, 7283 adapter->notification_desc.iopoll_qcnt); 7284 7285 adapter->notification_desc.int_rqs = 7286 kzalloc_objs(struct leapraid_int_rq, 7287 adapter->notification_desc.iopoll_qdex); 7288 if (!adapter->notification_desc.int_rqs) 7289 return -ENOMEM; 7290 7291 for (i = 0; i < adapter->notification_desc.iopoll_qcnt; i++) { 7292 adapter->notification_desc.blk_mq_poll_rqs[i].rq.adapter = 7293 adapter; 7294 adapter->notification_desc.blk_mq_poll_rqs[i].rq.msix_idx = 7295 i + adapter->notification_desc.iopoll_qdex; 7296 atomic_set( 7297 &adapter->notification_desc.blk_mq_poll_rqs[i].rq.busy, 7298 0); 7299 snprintf(adapter->notification_desc.blk_mq_poll_rqs[i].rq.name, 7300 LEAPRAID_NAME_LENGTH, 7301 "%s%u-MQ-Poll%u", LEAPRAID_DRIVER_NAME, 7302 adapter->adapter_attr.id, i); 7303 atomic_set(&adapter->notification_desc.blk_mq_poll_rqs[i].busy, 7304 0); 7305 atomic_set(&adapter->notification_desc.blk_mq_poll_rqs[i].pause, 7306 0); 7307 } 7308 7309 rc = leapraid_alloc_msix_cpu_map(adapter); 7310 if (rc) 7311 return rc; 7312 7313 adapter->notification_desc.irq_mode = LEAPRAID_INTERRUPT_MODE_MSIX; 7314 adapter->notification_desc.msix_enable = 1; 7315 rc = leapraid_setup_irqs(adapter); 7316 if (rc) { 7317 leapraid_free_irq(adapter); 7318 adapter->notification_desc.msix_enable = 0; 7319 return rc; 7320 } 7321 7322 return 0; 7323 } 7324 7325 static int leapraid_set_msi(struct leapraid_adapter *adapter) 7326 { 7327 int iopoll_qcnt = 0; 7328 unsigned int i; 7329 int rc, msi_cnt; 7330 7331 msi_cnt = pci_msi_vec_count(adapter->pdev); 7332 if (msi_cnt <= 0 || 7333 adapter->adapter_attr.features.max_msix_vectors == 0) { 7334 dev_info(&adapter->pdev->dev, "MSI unsupported!\n"); 7335 return -EOPNOTSUPP; 7336 } 7337 7338 msi_cnt = min_t(int, msi_cnt, 7339 adapter->adapter_attr.features.max_msix_vectors); 7340 7341 if (reset_devices) 7342 adapter->adapter_attr.rq_cnt = 1; 7343 else 7344 adapter->adapter_attr.rq_cnt = min_t(int, 7345 num_online_cpus(), 7346 msi_cnt); 7347 7348 if (max_msix_vectors > 0) 7349 adapter->adapter_attr.rq_cnt = min_t( 7350 int, max_msix_vectors, adapter->adapter_attr.rq_cnt); 7351 7352 if (adapter->adapter_attr.rq_cnt <= 1) 7353 adapter->shost->host_tagset = 0; 7354 if (adapter->shost->host_tagset) { 7355 iopoll_qcnt = poll_queues; 7356 if (iopoll_qcnt >= adapter->adapter_attr.rq_cnt) 7357 iopoll_qcnt = 0; 7358 } 7359 7360 if (iopoll_qcnt) { 7361 adapter->notification_desc.blk_mq_poll_rqs = 7362 kzalloc_objs(struct leapraid_blk_mq_poll_rq, 7363 iopoll_qcnt); 7364 if (!adapter->notification_desc.blk_mq_poll_rqs) 7365 return -ENOMEM; 7366 7367 adapter->adapter_attr.rq_cnt = 7368 min(adapter->adapter_attr.rq_cnt + iopoll_qcnt, 7369 msi_cnt); 7370 } 7371 7372 adapter->notification_desc.iopoll_qdex = 7373 adapter->adapter_attr.rq_cnt - iopoll_qcnt; 7374 rc = pci_alloc_irq_vectors_affinity( 7375 adapter->pdev, 7376 1, 7377 adapter->notification_desc.iopoll_qdex, 7378 PCI_IRQ_MSI | PCI_IRQ_AFFINITY, NULL); 7379 if (rc < 0) { 7380 dev_err(&adapter->pdev->dev, 7381 "%d MSI vectors allocated failed!\n", 7382 adapter->notification_desc.iopoll_qdex); 7383 leapraid_free_irq(adapter); 7384 return rc; 7385 } 7386 adapter->notification_desc.irq_vectors_allocated = 1; 7387 if (rc != adapter->notification_desc.iopoll_qdex) { 7388 adapter->notification_desc.iopoll_qdex = rc; 7389 adapter->adapter_attr.rq_cnt = 7390 adapter->notification_desc.iopoll_qdex + iopoll_qcnt; 7391 } 7392 adapter->notification_desc.iopoll_qcnt = iopoll_qcnt; 7393 dev_info(&adapter->pdev->dev, 7394 "MSI: req queue cnt=%d, intr=%d/poll=%d rep queues!\n", 7395 adapter->adapter_attr.rq_cnt, 7396 adapter->notification_desc.iopoll_qdex, 7397 adapter->notification_desc.iopoll_qcnt); 7398 7399 adapter->notification_desc.int_rqs = 7400 kzalloc_objs(struct leapraid_int_rq, 7401 adapter->notification_desc.iopoll_qdex); 7402 if (!adapter->notification_desc.int_rqs) 7403 return -ENOMEM; 7404 7405 for (i = 0; i < adapter->notification_desc.iopoll_qcnt; i++) { 7406 adapter->notification_desc.blk_mq_poll_rqs[i].rq.adapter = 7407 adapter; 7408 adapter->notification_desc.blk_mq_poll_rqs[i].rq.msix_idx = 7409 i + adapter->notification_desc.iopoll_qdex; 7410 atomic_set( 7411 &adapter->notification_desc.blk_mq_poll_rqs[i].rq.busy, 7412 0); 7413 snprintf(adapter->notification_desc.blk_mq_poll_rqs[i].rq.name, 7414 LEAPRAID_NAME_LENGTH, 7415 "%s%u-MQ-Poll%u", LEAPRAID_DRIVER_NAME, 7416 adapter->adapter_attr.id, i); 7417 atomic_set( 7418 &adapter->notification_desc.blk_mq_poll_rqs[i].busy, 7419 0); 7420 atomic_set( 7421 &adapter->notification_desc.blk_mq_poll_rqs[i].pause, 7422 0); 7423 } 7424 7425 rc = leapraid_alloc_msix_cpu_map(adapter); 7426 if (rc) 7427 return rc; 7428 7429 adapter->notification_desc.irq_mode = LEAPRAID_INTERRUPT_MODE_MSI; 7430 adapter->notification_desc.msix_enable = 1; 7431 rc = leapraid_setup_irqs(adapter); 7432 if (rc) { 7433 leapraid_free_irq(adapter); 7434 adapter->notification_desc.msix_enable = 0; 7435 return rc; 7436 } 7437 7438 return 0; 7439 } 7440 7441 static int leapraid_set_notification_auto(struct leapraid_adapter *adapter) 7442 { 7443 int rc; 7444 7445 rc = leapraid_set_msix(adapter); 7446 if (!rc) 7447 return 0; 7448 7449 leapraid_free_irq(adapter); 7450 dev_info(&adapter->pdev->dev, 7451 "MSI-X setup failed (%d), trying MSI\n", rc); 7452 7453 rc = leapraid_set_msi(adapter); 7454 if (!rc) 7455 return 0; 7456 7457 leapraid_free_irq(adapter); 7458 dev_info(&adapter->pdev->dev, 7459 "MSI setup failed (%d), back to legacy INTx\n", rc); 7460 7461 rc = leapraid_set_legacy_int(adapter); 7462 if (rc) 7463 dev_err(&adapter->pdev->dev, 7464 "%s: Enable legacy irq failed!\n", __func__); 7465 7466 return rc; 7467 } 7468 7469 int leapraid_set_pcie_and_notification(struct leapraid_adapter *adapter) 7470 { 7471 int rc; 7472 7473 rc = leapraid_enable_pcie(adapter); 7474 if (rc) 7475 goto out_fail; 7476 7477 leapraid_mask_int(adapter); 7478 7479 rc = leapraid_make_adapter_ready(adapter, PART_RESET); 7480 if (rc) { 7481 dev_err(&adapter->pdev->dev, "Make adapter ready failure\n"); 7482 goto out_fail; 7483 } 7484 7485 rc = leapraid_get_adapter_features(adapter); 7486 if (rc) { 7487 dev_err(&adapter->pdev->dev, "Get adapter feature failure\n"); 7488 goto out_fail; 7489 } 7490 7491 rc = leapraid_set_notification_auto(adapter); 7492 if (rc) 7493 goto out_fail; 7494 7495 pci_save_state(adapter->pdev); 7496 7497 return 0; 7498 7499 out_fail: 7500 leapraid_free_irq(adapter); 7501 leapraid_disable_pcie(adapter); 7502 return rc; 7503 } 7504 7505 void leapraid_disable_controller(struct leapraid_adapter *adapter) 7506 { 7507 if (!adapter->iomem_base) 7508 return; 7509 7510 leapraid_mask_int(adapter); 7511 7512 adapter->access_ctrl.shost_recovering = 1; 7513 leapraid_make_adapter_ready(adapter, PART_RESET); 7514 adapter->access_ctrl.shost_recovering = 0; 7515 wake_up(&adapter->access_ctrl.recovery_waitq); 7516 7517 leapraid_free_irq(adapter); 7518 leapraid_disable_pcie(adapter); 7519 } 7520 7521 static int leapraid_adapter_unit_reset(struct leapraid_adapter *adapter) 7522 { 7523 int rc = 0; 7524 7525 writel(LEAPRAID_FUNC_ADAPTER_UNIT_RESET << LEAPRAID_DB_FUNC_SHIFT, 7526 &adapter->iomem_base->db); 7527 if (leapraid_db_wait_ack_and_clear_int(adapter)) 7528 rc = -EFAULT; 7529 7530 if (!leapraid_wait_adapter_ready(adapter)) { 7531 dev_err(&adapter->pdev->dev, "unit reset failed\n"); 7532 return -EFAULT; 7533 } 7534 7535 return rc; 7536 } 7537 7538 static int leapraid_make_adapter_ready(struct leapraid_adapter *adapter, 7539 enum reset_type type) 7540 { 7541 u32 db; 7542 int count; 7543 7544 if (!leapraid_pci_active(adapter)) 7545 return 0; 7546 7547 count = 0; 7548 db = leapraid_readl(&adapter->iomem_base->db); 7549 if ((db & LEAPRAID_DB_MASK) == LEAPRAID_DB_RESET) { 7550 while ((db & LEAPRAID_DB_MASK) != LEAPRAID_DB_READY) { 7551 if (count++ == LEAPRAID_DB_RETRY_COUNT_MAX) { 7552 dev_err(&adapter->pdev->dev, 7553 "Wait adapter ready timeout\n"); 7554 return -EFAULT; 7555 } 7556 ssleep(1); 7557 db = leapraid_readl(&adapter->iomem_base->db); 7558 dev_info(&adapter->pdev->dev, 7559 "Wait adapter ready, count=%d, db=0x%x\n", 7560 count, db); 7561 } 7562 } 7563 if ((db & LEAPRAID_DB_MASK) == LEAPRAID_DB_READY) 7564 return 0; 7565 7566 if (db & LEAPRAID_DB_USED) 7567 goto full_reset; 7568 7569 if ((db & LEAPRAID_DB_MASK) == LEAPRAID_DB_FAULT) 7570 goto full_reset; 7571 7572 if (type == FULL_RESET) 7573 goto full_reset; 7574 7575 if ((db & LEAPRAID_DB_MASK) == LEAPRAID_DB_OPERATIONAL && 7576 !leapraid_adapter_unit_reset(adapter)) 7577 return 0; 7578 7579 full_reset: 7580 return leapraid_host_diag_reset(adapter); 7581 } 7582 7583 static void leapraid_fw_log_exit(struct leapraid_adapter *adapter) 7584 { 7585 if (!adapter->fw_log_desc.open_pcie_trace) 7586 return; 7587 7588 if (adapter->fw_log_desc.fw_log_buffer) { 7589 wait_event(adapter->fw_log_desc.mmap_waitq, 7590 !atomic_read(&adapter->fw_log_desc.mmap_refcnt)); 7591 dma_free_coherent(&adapter->pdev->dev, 7592 (LEAPRAID_SYS_LOG_BUF_SIZE + 7593 LEAPRAID_SYS_LOG_BUF_RESERVE), 7594 adapter->fw_log_desc.fw_log_buffer, 7595 adapter->fw_log_desc.fw_log_buffer_dma); 7596 adapter->fw_log_desc.fw_log_buffer = NULL; 7597 } 7598 } 7599 7600 static int leapraid_fw_log_init(struct leapraid_adapter *adapter) 7601 { 7602 struct leapraid_adapter_log_req adapter_log_req; 7603 struct leapraid_adapter_log_rep adapter_log_rep; 7604 u16 adapter_status; 7605 u64 buf_addr; 7606 u32 rc; 7607 7608 if (!adapter->fw_log_desc.open_pcie_trace) 7609 return 0; 7610 7611 if (!adapter->fw_log_desc.fw_log_buffer) { 7612 adapter->fw_log_desc.fw_log_buffer = 7613 dma_alloc_coherent( 7614 &adapter->pdev->dev, 7615 (LEAPRAID_SYS_LOG_BUF_SIZE + 7616 LEAPRAID_SYS_LOG_BUF_RESERVE), 7617 &adapter->fw_log_desc.fw_log_buffer_dma, 7618 GFP_KERNEL); 7619 if (!adapter->fw_log_desc.fw_log_buffer) 7620 return -ENOMEM; 7621 } 7622 7623 memset(&adapter_log_req, 0, sizeof(struct leapraid_adapter_log_req)); 7624 adapter_log_req.func = LEAPRAID_FUNC_LOGBUF_INIT; 7625 buf_addr = adapter->fw_log_desc.fw_log_buffer_dma; 7626 7627 adapter_log_req.mbox.w[0] = 7628 cpu_to_le32((u32)(buf_addr & 0xFFFFFFFF)); 7629 adapter_log_req.mbox.w[1] = 7630 cpu_to_le32((u32)((buf_addr >> 32) & 0xFFFFFFFF)); 7631 adapter_log_req.mbox.w[2] = 7632 cpu_to_le32(LEAPRAID_SYS_LOG_BUF_SIZE); 7633 rc = leapraid_handshake_func(adapter, 7634 sizeof(struct leapraid_adapter_log_req), 7635 (u32 *)&adapter_log_req, 7636 sizeof(struct leapraid_adapter_log_rep), 7637 (u16 *)&adapter_log_rep); 7638 if (rc != 0) { 7639 dev_err(&adapter->pdev->dev, "%s: Handshake failed, rc=%d\n", 7640 __func__, rc); 7641 return rc; 7642 } 7643 7644 adapter_status = le16_to_cpu(adapter_log_rep.adapter_status) & 7645 LEAPRAID_ADAPTER_STATUS_MASK; 7646 if (adapter_status != LEAPRAID_ADAPTER_STATUS_SUCCESS) { 7647 dev_err(&adapter->pdev->dev, "%s: failed!\n", __func__); 7648 rc = -EIO; 7649 } 7650 7651 return rc; 7652 } 7653 7654 static void leapraid_free_host_memory(struct leapraid_adapter *adapter) 7655 { 7656 unsigned int i; 7657 7658 if (adapter->mem_desc.task_desc) { 7659 dma_free_coherent(&adapter->pdev->dev, 7660 adapter->adapter_attr.task_desc_dma_size, 7661 adapter->mem_desc.task_desc, 7662 adapter->mem_desc.task_desc_dma); 7663 adapter->mem_desc.task_desc = NULL; 7664 } 7665 7666 if (adapter->mem_desc.sense_data) { 7667 dma_free_coherent( 7668 &adapter->pdev->dev, 7669 adapter->adapter_attr.io_qd * SCSI_SENSE_BUFFERSIZE, 7670 adapter->mem_desc.sense_data, 7671 adapter->mem_desc.sense_data_dma); 7672 adapter->mem_desc.sense_data = NULL; 7673 } 7674 7675 if (adapter->mem_desc.rep_msg) { 7676 dma_free_coherent( 7677 &adapter->pdev->dev, 7678 adapter->adapter_attr.rep_msg_qd * LEAPRAID_REPLY_SIZE, 7679 adapter->mem_desc.rep_msg, 7680 adapter->mem_desc.rep_msg_dma); 7681 adapter->mem_desc.rep_msg = NULL; 7682 } 7683 7684 if (adapter->mem_desc.rep_msg_addr) { 7685 dma_free_coherent(&adapter->pdev->dev, 7686 adapter->adapter_attr.rep_msg_qd * 7687 LEAPRAID_REP_MSG_ADDR_SIZE, 7688 adapter->mem_desc.rep_msg_addr, 7689 adapter->mem_desc.rep_msg_addr_dma); 7690 adapter->mem_desc.rep_msg_addr = NULL; 7691 } 7692 7693 if (adapter->mem_desc.rep_desc_seg_maint) { 7694 for (i = 0; i < adapter->adapter_attr.rep_desc_q_seg_cnt; 7695 i++) { 7696 if (adapter->mem_desc.rep_desc_seg_maint[i] 7697 .rep_desc_seg) { 7698 dma_free_coherent( 7699 &adapter->pdev->dev, 7700 (adapter->adapter_attr.rep_desc_qd * 7701 LEAPRAID_REP_DESC_ENTRY_SIZE) * 7702 LEAPRAID_REP_DESC_CHUNK_SIZE, 7703 adapter->mem_desc.rep_desc_seg_maint[i] 7704 .rep_desc_seg, 7705 adapter->mem_desc.rep_desc_seg_maint[i] 7706 .rep_desc_seg_dma); 7707 adapter->mem_desc.rep_desc_seg_maint[i] 7708 .rep_desc_seg = NULL; 7709 } 7710 } 7711 7712 if (adapter->mem_desc.rep_desc_q_arr) { 7713 dma_free_coherent( 7714 &adapter->pdev->dev, 7715 adapter->adapter_attr.rq_cnt * 7716 LEAPRAID_REP_RQ_CNT_SIZE, 7717 adapter->mem_desc.rep_desc_q_arr, 7718 adapter->mem_desc.rep_desc_q_arr_dma); 7719 adapter->mem_desc.rep_desc_q_arr = NULL; 7720 } 7721 7722 for (i = 0; i < adapter->adapter_attr.rep_desc_q_seg_cnt; i++) { 7723 struct leapraid_mem_desc *mem_desc = 7724 &adapter->mem_desc; 7725 kfree(adapter->mem_desc.rep_desc_seg_maint[i] 7726 .rep_desc_maint); 7727 mem_desc->rep_desc_seg_maint[i].rep_desc_maint = NULL; 7728 } 7729 kfree(adapter->mem_desc.rep_desc_seg_maint); 7730 adapter->mem_desc.rep_desc_seg_maint = NULL; 7731 } 7732 7733 kfree(adapter->mem_desc.taskid_to_uniq_tag); 7734 adapter->mem_desc.taskid_to_uniq_tag = NULL; 7735 7736 dma_pool_destroy(adapter->mem_desc.sg_chain_pool); 7737 adapter->mem_desc.sg_chain_pool = NULL; 7738 } 7739 7740 static inline bool leapraid_is_in_same_4g_seg(dma_addr_t start, u32 size) 7741 { 7742 return upper_32_bits(start) == upper_32_bits(start + size - 1); 7743 } 7744 7745 int leapraid_internal_init_cmd_priv(struct leapraid_adapter *adapter, 7746 struct leapraid_io_req_tracker *io_tracker) 7747 { 7748 io_tracker->chain = 7749 dma_pool_alloc(adapter->mem_desc.sg_chain_pool, 7750 GFP_KERNEL, 7751 &io_tracker->chain_dma); 7752 7753 if (!io_tracker->chain) 7754 return -ENOMEM; 7755 7756 return 0; 7757 } 7758 7759 void leapraid_internal_exit_cmd_priv(struct leapraid_adapter *adapter, 7760 struct leapraid_io_req_tracker *io_tracker) 7761 { 7762 if (io_tracker && io_tracker->chain) 7763 dma_pool_free(adapter->mem_desc.sg_chain_pool, 7764 io_tracker->chain, 7765 io_tracker->chain_dma); 7766 } 7767 7768 static int leapraid_request_host_memory(struct leapraid_adapter *adapter) 7769 { 7770 struct leapraid_adapter_features *facts = 7771 &adapter->adapter_attr.features; 7772 u16 rep_desc_q_cnt_allocated; 7773 unsigned int i, j; 7774 int rc; 7775 7776 /* Scatter-gather table size. */ 7777 adapter->shost->sg_tablesize = LEAPRAID_SG_DEPTH; 7778 if (reset_devices) 7779 adapter->shost->sg_tablesize = 7780 LEAPRAID_KDUMP_MIN_PHYS_SEGMENTS; 7781 /* High-priority commands queue depth. */ 7782 adapter->dynamic_task_desc.hp_cmd_qd = LEAPRAID_FIXED_HP_CMDS; 7783 /* Internal commands queue depth. */ 7784 adapter->dynamic_task_desc.inter_cmd_qd = LEAPRAID_FIXED_INTER_CMDS; 7785 /* Adapter commands total queue depth. */ 7786 if (reset_devices) 7787 adapter->adapter_attr.adapter_total_qd = 7788 LEAPRAID_DEFAULT_CMD_QD_OFFSET + 7789 adapter->dynamic_task_desc.inter_cmd_qd + 7790 adapter->dynamic_task_desc.hp_cmd_qd; 7791 else 7792 adapter->adapter_attr.adapter_total_qd = facts->req_slot + 7793 adapter->dynamic_task_desc.hp_cmd_qd; 7794 /* Reply message queue depth. */ 7795 adapter->adapter_attr.rep_msg_qd = 7796 adapter->adapter_attr.adapter_total_qd + 7797 LEAPRAID_DEFAULT_CMD_QD_OFFSET; 7798 /* Reply descriptor queue depth. */ 7799 adapter->adapter_attr.rep_desc_qd = 7800 round_up(adapter->adapter_attr.adapter_total_qd + 7801 adapter->adapter_attr.rep_msg_qd + 7802 LEAPRAID_TASKID_OFFSET_CTRL_CMD, 7803 LEAPRAID_REPLY_QD_ALIGNMENT); 7804 /* SCSI command I/O depth. */ 7805 adapter->adapter_attr.io_qd = 7806 adapter->adapter_attr.adapter_total_qd - 7807 adapter->dynamic_task_desc.hp_cmd_qd - 7808 adapter->dynamic_task_desc.inter_cmd_qd; 7809 /* SCSI host can queue. */ 7810 adapter->shost->can_queue = adapter->adapter_attr.io_qd - 7811 LEAPRAID_TASKID_OFFSET_CTRL_CMD; 7812 adapter->driver_cmds.ctl_cmd.taskid = adapter->shost->can_queue + 7813 LEAPRAID_TASKID_OFFSET_CTRL_CMD; 7814 7815 /* Allocate task descriptor. */ 7816 try_again: 7817 adapter->adapter_attr.task_desc_dma_size = 7818 (adapter->adapter_attr.adapter_total_qd + 7819 LEAPRAID_TASKID_OFFSET_CTRL_CMD) * 7820 LEAPRAID_REQUEST_SIZE; 7821 adapter->mem_desc.task_desc = 7822 dma_alloc_coherent(&adapter->pdev->dev, 7823 adapter->adapter_attr.task_desc_dma_size, 7824 &adapter->mem_desc.task_desc_dma, 7825 GFP_KERNEL); 7826 if (!adapter->mem_desc.task_desc) 7827 return -ENOMEM; 7828 7829 /* Allocate chain message pool. */ 7830 adapter->mem_desc.sg_chain_pool_size = 7831 LEAPRAID_DEFAULT_CHAINS_PER_IO * LEAPRAID_CHAIN_SEG_SIZE; 7832 adapter->mem_desc.sg_chain_pool = 7833 dma_pool_create("leapraid chain pool", 7834 &adapter->pdev->dev, 7835 adapter->mem_desc.sg_chain_pool_size, 7836 LEAPRAID_DMA_ALIGN, 0); 7837 if (!adapter->mem_desc.sg_chain_pool) 7838 return -ENOMEM; 7839 7840 /* Allocate I/O tracker to SCSI I/O. */ 7841 adapter->mem_desc.taskid_to_uniq_tag = 7842 kcalloc(adapter->shost->can_queue, sizeof(u16), GFP_KERNEL); 7843 if (!adapter->mem_desc.taskid_to_uniq_tag) 7844 return -ENOMEM; 7845 7846 adapter->dynamic_task_desc.hp_taskid = 7847 adapter->adapter_attr.io_qd + 7848 LEAPRAID_HP_TASKID_OFFSET_CTL_CMD; 7849 /* Allocate static high-priority task ID. */ 7850 adapter->driver_cmds.ctl_cmd.hp_taskid = 7851 adapter->dynamic_task_desc.hp_taskid; 7852 adapter->driver_cmds.tm_cmd.hp_taskid = 7853 adapter->dynamic_task_desc.hp_taskid + 7854 LEAPRAID_HP_TASKID_OFFSET_TM_CMD; 7855 7856 adapter->dynamic_task_desc.inter_taskid = 7857 adapter->dynamic_task_desc.hp_taskid + 7858 adapter->dynamic_task_desc.hp_cmd_qd; 7859 adapter->driver_cmds.scan_dev_cmd.inter_taskid = 7860 adapter->dynamic_task_desc.inter_taskid; 7861 adapter->driver_cmds.cfg_op_cmd.inter_taskid = 7862 adapter->dynamic_task_desc.inter_taskid + 7863 LEAPRAID_TASKID_OFFSET_CFG_OP_CMD; 7864 adapter->driver_cmds.transport_cmd.inter_taskid = 7865 adapter->dynamic_task_desc.inter_taskid + 7866 LEAPRAID_TASKID_OFFSET_TRANSPORT_CMD; 7867 adapter->driver_cmds.enc_cmd.inter_taskid = 7868 adapter->dynamic_task_desc.inter_taskid + 7869 LEAPRAID_TASKID_OFFSET_ENC_CMD; 7870 adapter->driver_cmds.notify_event_cmd.inter_taskid = 7871 adapter->dynamic_task_desc.inter_taskid + 7872 LEAPRAID_TASKID_OFFSET_NOTIFY_EVENT_CMD; 7873 dev_info(&adapter->pdev->dev, "queue depth:\n"); 7874 dev_info(&adapter->pdev->dev, " host->can_queue: %d\n", 7875 adapter->shost->can_queue); 7876 dev_info(&adapter->pdev->dev, " io_qd: %d\n", 7877 adapter->adapter_attr.io_qd); 7878 dev_info(&adapter->pdev->dev, " hpr_cmd_qd: %d\n", 7879 adapter->dynamic_task_desc.hp_cmd_qd); 7880 dev_info(&adapter->pdev->dev, " inter_cmd_qd: %d\n", 7881 adapter->dynamic_task_desc.inter_cmd_qd); 7882 dev_info(&adapter->pdev->dev, " adapter_total_qd: %d\n", 7883 adapter->adapter_attr.adapter_total_qd); 7884 7885 dev_info(&adapter->pdev->dev, "taskid range:\n"); 7886 dev_info(&adapter->pdev->dev, 7887 " adapter->dynamic_task_desc.hp_taskid: %d\n", 7888 adapter->dynamic_task_desc.hp_taskid); 7889 dev_info(&adapter->pdev->dev, 7890 " adapter->dynamic_task_desc.inter_taskid: %d\n", 7891 adapter->dynamic_task_desc.inter_taskid); 7892 7893 /* 7894 * Allocate sense data DMA buffer. 7895 * Constraint: Must reside within the same 4GB segment 7896 * (driver-maintained). 7897 */ 7898 adapter->mem_desc.sense_data = 7899 dma_alloc_coherent( 7900 &adapter->pdev->dev, 7901 adapter->adapter_attr.io_qd * SCSI_SENSE_BUFFERSIZE, 7902 &adapter->mem_desc.sense_data_dma, 7903 GFP_KERNEL); 7904 if (!adapter->mem_desc.sense_data) 7905 return -ENOMEM; 7906 7907 if (!leapraid_is_in_same_4g_seg(adapter->mem_desc.sense_data_dma, 7908 adapter->adapter_attr.io_qd * 7909 SCSI_SENSE_BUFFERSIZE)) { 7910 dev_warn(&adapter->pdev->dev, 7911 "Try 32bit DMA: Sense not in same 4G\n"); 7912 rc = -EAGAIN; 7913 goto out_fail; 7914 } 7915 7916 /* 7917 * Allocate reply frame buffer. 7918 * Constraint: Must reside in the same 4GB segment as the sense DMA. 7919 */ 7920 adapter->mem_desc.rep_msg = 7921 dma_alloc_coherent(&adapter->pdev->dev, 7922 adapter->adapter_attr.rep_msg_qd * 7923 LEAPRAID_REPLY_SIZE, 7924 &adapter->mem_desc.rep_msg_dma, 7925 GFP_KERNEL); 7926 if (!adapter->mem_desc.rep_msg) { 7927 rc = -ENOMEM; 7928 goto out_fail; 7929 } 7930 7931 if (!leapraid_is_in_same_4g_seg(adapter->mem_desc.rep_msg_dma, 7932 adapter->adapter_attr.rep_msg_qd * 7933 LEAPRAID_REPLY_SIZE)) { 7934 dev_warn(&adapter->pdev->dev, 7935 "Use 32 bit DMA due to rep msg is not in same 4g!\n"); 7936 rc = -EAGAIN; 7937 goto out_fail; 7938 } 7939 7940 /* Address of reply frame. */ 7941 adapter->mem_desc.rep_msg_addr = 7942 dma_alloc_coherent(&adapter->pdev->dev, 7943 adapter->adapter_attr.rep_msg_qd * 7944 LEAPRAID_REP_MSG_ADDR_SIZE, 7945 &adapter->mem_desc.rep_msg_addr_dma, 7946 GFP_KERNEL); 7947 if (!adapter->mem_desc.rep_msg_addr) 7948 return -ENOMEM; 7949 adapter->adapter_attr.rep_desc_q_seg_cnt = 7950 DIV_ROUND_UP(adapter->adapter_attr.rq_cnt, 7951 LEAPRAID_REP_DESC_CHUNK_SIZE); 7952 adapter->mem_desc.rep_desc_seg_maint = 7953 kzalloc_objs(struct leapraid_rep_desc_seg_maint, 7954 adapter->adapter_attr.rep_desc_q_seg_cnt); 7955 if (!adapter->mem_desc.rep_desc_seg_maint) 7956 return -ENOMEM; 7957 7958 rep_desc_q_cnt_allocated = 0; 7959 for (i = 0; i < adapter->adapter_attr.rep_desc_q_seg_cnt; i++) { 7960 adapter->mem_desc.rep_desc_seg_maint[i].rep_desc_maint = 7961 kzalloc_objs(struct leapraid_rep_desc_maint, 7962 LEAPRAID_REP_DESC_CHUNK_SIZE); 7963 if (!adapter->mem_desc.rep_desc_seg_maint[i].rep_desc_maint) 7964 return -ENOMEM; 7965 7966 adapter->mem_desc.rep_desc_seg_maint[i].rep_desc_seg = 7967 dma_alloc_coherent( 7968 &adapter->pdev->dev, 7969 (adapter->adapter_attr.rep_desc_qd * 7970 LEAPRAID_REP_DESC_ENTRY_SIZE) * 7971 LEAPRAID_REP_DESC_CHUNK_SIZE, 7972 &adapter->mem_desc.rep_desc_seg_maint[i] 7973 .rep_desc_seg_dma, 7974 GFP_KERNEL); 7975 if (!adapter->mem_desc.rep_desc_seg_maint[i].rep_desc_seg) 7976 return -ENOMEM; 7977 7978 for (j = 0; j < LEAPRAID_REP_DESC_CHUNK_SIZE; j++) { 7979 if (rep_desc_q_cnt_allocated >= 7980 adapter->adapter_attr.rq_cnt) 7981 break; 7982 adapter->mem_desc 7983 .rep_desc_seg_maint[i] 7984 .rep_desc_maint[j] 7985 .rep_desc = 7986 (void *)((u8 *)( 7987 adapter->mem_desc 7988 .rep_desc_seg_maint[i] 7989 .rep_desc_seg) + 7990 j * 7991 (adapter->adapter_attr.rep_desc_qd * 7992 LEAPRAID_REP_DESC_ENTRY_SIZE)); 7993 adapter->mem_desc 7994 .rep_desc_seg_maint[i] 7995 .rep_desc_maint[j] 7996 .rep_desc_dma = 7997 adapter->mem_desc 7998 .rep_desc_seg_maint[i] 7999 .rep_desc_seg_dma + 8000 j * 8001 (adapter->adapter_attr.rep_desc_qd * 8002 LEAPRAID_REP_DESC_ENTRY_SIZE); 8003 rep_desc_q_cnt_allocated++; 8004 } 8005 } 8006 8007 if (!reset_devices) { 8008 adapter->mem_desc.rep_desc_q_arr = 8009 dma_alloc_coherent( 8010 &adapter->pdev->dev, 8011 adapter->adapter_attr.rq_cnt * 8012 LEAPRAID_REP_RQ_CNT_SIZE, 8013 &adapter->mem_desc.rep_desc_q_arr_dma, 8014 GFP_KERNEL); 8015 if (!adapter->mem_desc.rep_desc_q_arr) 8016 return -ENOMEM; 8017 } 8018 8019 return 0; 8020 out_fail: 8021 if (rc == -EAGAIN) { 8022 leapraid_free_host_memory(adapter); 8023 adapter->adapter_attr.use_32_dma_mask = 1; 8024 rc = dma_set_mask_and_coherent(&adapter->pdev->dev, 8025 DMA_BIT_MASK(DMA_32_BITS)); 8026 if (rc) { 8027 dev_err(&adapter->pdev->dev, 8028 "Failed to set 32 DMA mask\n"); 8029 return rc; 8030 } 8031 goto try_again; 8032 } 8033 return rc; 8034 } 8035 8036 static int leapraid_alloc_dev_topo_bitmaps(struct leapraid_adapter *adapter) 8037 { 8038 u16 pd_hdls_sz; 8039 8040 pd_hdls_sz = 8041 BITS_TO_LONGS( 8042 adapter->adapter_attr.features.max_dev_handle + 1) * 8043 sizeof(unsigned long); 8044 8045 adapter->dev_topo.pd_hdls_sz = pd_hdls_sz; 8046 adapter->dev_topo.pd_hdls = 8047 kzalloc(adapter->dev_topo.pd_hdls_sz, GFP_KERNEL); 8048 if (!adapter->dev_topo.pd_hdls) 8049 return -ENOMEM; 8050 8051 adapter->dev_topo.blocking_hdls = 8052 kzalloc(adapter->dev_topo.pd_hdls_sz, GFP_KERNEL); 8053 if (!adapter->dev_topo.blocking_hdls) 8054 return -ENOMEM; 8055 8056 return 0; 8057 } 8058 8059 static void leapraid_free_dev_topo_bitmaps(struct leapraid_adapter *adapter) 8060 { 8061 kfree(adapter->dev_topo.pd_hdls); 8062 kfree(adapter->dev_topo.blocking_hdls); 8063 } 8064 8065 static int leapraid_init_driver_cmds(struct leapraid_adapter *adapter) 8066 { 8067 INIT_LIST_HEAD(&adapter->driver_cmds.special_cmd_list); 8068 8069 adapter->driver_cmds.scan_dev_cmd.status = LEAPRAID_CMD_NOT_USED; 8070 adapter->driver_cmds.scan_dev_cmd.cb_idx = LEAPRAID_SCAN_DEV_CB_IDX; 8071 list_add_tail(&adapter->driver_cmds.scan_dev_cmd.list, 8072 &adapter->driver_cmds.special_cmd_list); 8073 8074 adapter->driver_cmds.cfg_op_cmd.status = LEAPRAID_CMD_NOT_USED; 8075 adapter->driver_cmds.cfg_op_cmd.cb_idx = LEAPRAID_CONFIG_CB_IDX; 8076 mutex_init(&adapter->driver_cmds.cfg_op_cmd.mutex); 8077 list_add_tail(&adapter->driver_cmds.cfg_op_cmd.list, 8078 &adapter->driver_cmds.special_cmd_list); 8079 8080 adapter->driver_cmds.transport_cmd.status = LEAPRAID_CMD_NOT_USED; 8081 adapter->driver_cmds.transport_cmd.cb_idx = LEAPRAID_TRANSPORT_CB_IDX; 8082 mutex_init(&adapter->driver_cmds.transport_cmd.mutex); 8083 list_add_tail(&adapter->driver_cmds.transport_cmd.list, 8084 &adapter->driver_cmds.special_cmd_list); 8085 8086 adapter->driver_cmds.enc_cmd.status = LEAPRAID_CMD_NOT_USED; 8087 adapter->driver_cmds.enc_cmd.cb_idx = LEAPRAID_ENC_CB_IDX; 8088 mutex_init(&adapter->driver_cmds.enc_cmd.mutex); 8089 list_add_tail(&adapter->driver_cmds.enc_cmd.list, 8090 &adapter->driver_cmds.special_cmd_list); 8091 8092 adapter->driver_cmds.notify_event_cmd.status = LEAPRAID_CMD_NOT_USED; 8093 adapter->driver_cmds.notify_event_cmd.cb_idx = 8094 LEAPRAID_NOTIFY_EVENT_CB_IDX; 8095 mutex_init(&adapter->driver_cmds.notify_event_cmd.mutex); 8096 list_add_tail(&adapter->driver_cmds.notify_event_cmd.list, 8097 &adapter->driver_cmds.special_cmd_list); 8098 8099 adapter->driver_cmds.ctl_cmd.status = LEAPRAID_CMD_NOT_USED; 8100 adapter->driver_cmds.ctl_cmd.cb_idx = LEAPRAID_CTL_CB_IDX; 8101 mutex_init(&adapter->driver_cmds.ctl_cmd.mutex); 8102 list_add_tail(&adapter->driver_cmds.ctl_cmd.list, 8103 &adapter->driver_cmds.special_cmd_list); 8104 8105 adapter->driver_cmds.tm_cmd.status = LEAPRAID_CMD_NOT_USED; 8106 adapter->driver_cmds.tm_cmd.cb_idx = LEAPRAID_TM_CB_IDX; 8107 mutex_init(&adapter->driver_cmds.tm_cmd.mutex); 8108 list_add_tail(&adapter->driver_cmds.tm_cmd.list, 8109 &adapter->driver_cmds.special_cmd_list); 8110 8111 return 0; 8112 } 8113 8114 static void leapraid_unmask_evts(struct leapraid_adapter *adapter, u16 evt) 8115 { 8116 if (evt >= LEAPRAID_MAX_EVENT_NUM) 8117 return; 8118 8119 clear_bit(evt, (unsigned long *)adapter->fw_evt_s.leapraid_evt_masks); 8120 } 8121 8122 static void leapraid_init_event_mask(struct leapraid_adapter *adapter) 8123 { 8124 int i; 8125 8126 for (i = 0; i < LEAPRAID_EVT_MASK_COUNT; i++) 8127 adapter->fw_evt_s.leapraid_evt_masks[i] = 8128 LEAPRAID_INVALID_INITIAL_VALUE; 8129 8130 leapraid_unmask_evts(adapter, LEAPRAID_EVT_SAS_TOPO_CHANGE_LIST); 8131 leapraid_unmask_evts(adapter, LEAPRAID_EVT_SAS_ENCL_DEV_STATUS_CHANGE); 8132 leapraid_unmask_evts(adapter, LEAPRAID_EVT_SAS_DEV_STATUS_CHANGE); 8133 leapraid_unmask_evts(adapter, LEAPRAID_EVT_IR_CHANGE); 8134 } 8135 8136 static void leapraid_prepare_adapter_init_req( 8137 struct leapraid_adapter *adapter, 8138 struct leapraid_adapter_init_req *init_req) 8139 { 8140 ktime_t cur_time; 8141 int i, chunk; 8142 u32 reply_post_free_ary_sz; 8143 8144 memset(init_req, 0, sizeof(struct leapraid_adapter_init_req)); 8145 init_req->func = LEAPRAID_FUNC_ADAPTER_INIT; 8146 init_req->who_init = LEAPRAID_WHOINIT_LINUX_DRIVER; 8147 init_req->msg_ver = cpu_to_le16(LEAPRAID_MSG_VERSION); 8148 init_req->header_ver = cpu_to_le16(LEAPRAID_HEADER_VERSION); 8149 init_req->driver_ver = 8150 cpu_to_le32((LEAPRAID_MAJOR_VERSION << 8151 LEAPRAID_VER_MAJOR_SHIFT) | 8152 (LEAPRAID_MINOR_VERSION << LEAPRAID_VER_MINOR_SHIFT) | 8153 (LEAPRAID_BUILD_VERSION << LEAPRAID_VER_BUILD_SHIFT) | 8154 LEAPRAID_RELEASE_VERSION); 8155 if (adapter->notification_desc.msix_enable) 8156 init_req->host_msix_vectors = adapter->adapter_attr.rq_cnt; 8157 8158 init_req->req_frame_size = 8159 cpu_to_le16(LEAPRAID_REQUEST_SIZE / LEAPRAID_DWORDS_BYTE_SIZE); 8160 init_req->rep_desc_qd = 8161 cpu_to_le16(adapter->adapter_attr.rep_desc_qd); 8162 init_req->rep_msg_qd = 8163 cpu_to_le16(adapter->adapter_attr.rep_msg_qd); 8164 init_req->sense_buffer_add_high = 8165 cpu_to_le32((u64)adapter->mem_desc.sense_data_dma >> 32); 8166 init_req->rep_msg_dma_high = 8167 cpu_to_le32((u64)adapter->mem_desc.rep_msg_dma >> 32); 8168 init_req->task_desc_base_addr = 8169 cpu_to_le64((u64)adapter->mem_desc.task_desc_dma); 8170 init_req->rep_msg_addr_dma = 8171 cpu_to_le64((u64)adapter->mem_desc.rep_msg_addr_dma); 8172 if (!reset_devices) { 8173 reply_post_free_ary_sz = 8174 adapter->adapter_attr.rq_cnt * LEAPRAID_REP_RQ_CNT_SIZE; 8175 memset(adapter->mem_desc.rep_desc_q_arr, 0, 8176 reply_post_free_ary_sz); 8177 8178 chunk = LEAPRAID_REP_DESC_CHUNK_SIZE; 8179 for (i = 0; i < adapter->adapter_attr.rq_cnt; i++) 8180 adapter->mem_desc.rep_desc_q_arr[i].rep_desc_base_addr = 8181 cpu_to_le64 ((u64)adapter->mem_desc 8182 .rep_desc_seg_maint[i / chunk] 8183 .rep_desc_maint[i % chunk] 8184 .rep_desc_dma); 8185 8186 init_req->msg_flg = 8187 LEAPRAID_ADAPTER_INIT_MSGFLG_RDPQ_ARRAY_MODE; 8188 init_req->rep_desc_q_arr_addr = 8189 cpu_to_le64((u64)adapter->mem_desc.rep_desc_q_arr_dma); 8190 } else { 8191 init_req->rep_desc_q_arr_addr = 8192 cpu_to_le64((u64)adapter->mem_desc 8193 .rep_desc_seg_maint[0] 8194 .rep_desc_maint[0] 8195 .rep_desc_dma); 8196 } 8197 cur_time = ktime_get_real(); 8198 init_req->time_stamp = cpu_to_le64(ktime_to_ms(cur_time)); 8199 } 8200 8201 static int leapraid_send_adapter_init(struct leapraid_adapter *adapter) 8202 { 8203 struct leapraid_adapter_init_req init_req; 8204 struct leapraid_adapter_init_rep init_rep; 8205 u16 adapter_status; 8206 int rc; 8207 8208 leapraid_prepare_adapter_init_req(adapter, &init_req); 8209 8210 rc = leapraid_handshake_func(adapter, 8211 sizeof(struct leapraid_adapter_init_req), 8212 (u32 *)&init_req, 8213 sizeof(struct leapraid_adapter_init_rep), 8214 (u16 *)&init_rep); 8215 if (rc != 0) { 8216 dev_err(&adapter->pdev->dev, "%s: Handshake failed, rc=%d\n", 8217 __func__, rc); 8218 return rc; 8219 } 8220 8221 adapter_status = 8222 le16_to_cpu(init_rep.adapter_status) & 8223 LEAPRAID_ADAPTER_STATUS_MASK; 8224 if (adapter_status != LEAPRAID_ADAPTER_STATUS_SUCCESS) { 8225 dev_err(&adapter->pdev->dev, "%s: failed\n", __func__); 8226 rc = -EIO; 8227 } 8228 8229 return rc; 8230 } 8231 8232 static int leapraid_cfg_pages(struct leapraid_adapter *adapter) 8233 { 8234 union cfg_param_1 cfgp1 = {0}; 8235 union cfg_param_2 cfgp2 = {0}; 8236 union { 8237 struct leapraid_manufacturing_p0 manufacturing_page0; 8238 struct leapraid_bios_page3 bios_page3; 8239 struct leapraid_bios_page2 bios_page2; 8240 } cfg_page; 8241 int rc; 8242 8243 rc = leapraid_op_config_page(adapter, &cfg_page.bios_page3, cfgp1, 8244 cfgp2, GET_BIOS_PG3); 8245 if (rc) 8246 return rc; 8247 8248 adapter->adapter_attr.bios_version = 8249 le32_to_cpu(cfg_page.bios_page3.bios_version); 8250 8251 rc = leapraid_op_config_page(adapter, &cfg_page.bios_page2, cfgp1, 8252 cfgp2, GET_BIOS_PG2); 8253 if (rc) 8254 return rc; 8255 8256 adapter->boot_devs.requested_boot_dev.form = 8257 cfg_page.bios_page2.requested_boot_dev_form; 8258 memcpy(adapter->boot_devs.requested_boot_dev.pg_dev, 8259 &cfg_page.bios_page2.requested_boot_dev, 8260 LEAPRAID_BOOT_DEV_SIZE); 8261 adapter->boot_devs.requested_alt_boot_dev.form = 8262 cfg_page.bios_page2.requested_alt_boot_dev_form; 8263 memcpy(adapter->boot_devs.requested_alt_boot_dev.pg_dev, 8264 &cfg_page.bios_page2.requested_alt_boot_dev, 8265 LEAPRAID_BOOT_DEV_SIZE); 8266 adapter->boot_devs.current_boot_dev.form = 8267 cfg_page.bios_page2.current_boot_dev_form; 8268 memcpy(adapter->boot_devs.current_boot_dev.pg_dev, 8269 &cfg_page.bios_page2.current_boot_dev, 8270 LEAPRAID_BOOT_DEV_SIZE); 8271 8272 rc = leapraid_op_config_page(adapter, &cfg_page.manufacturing_page0, 8273 cfgp1, cfgp2, GET_MANUFACTURING_PG0); 8274 if (rc) 8275 return rc; 8276 8277 snprintf(adapter->adapter_attr.board_name, 8278 sizeof(adapter->adapter_attr.board_name), 8279 "%.*s", 8280 (int)sizeof(cfg_page.manufacturing_page0.board_name), 8281 cfg_page.manufacturing_page0.board_name); 8282 return rc; 8283 } 8284 8285 static int leapraid_evt_notify(struct leapraid_adapter *adapter) 8286 { 8287 struct leapraid_evt_notify_req *evt_notify_req; 8288 struct leapraid_evt_notify_rep *evt_notify_rep; 8289 u16 adapter_status; 8290 int rc = 0; 8291 int i; 8292 8293 mutex_lock(&adapter->driver_cmds.notify_event_cmd.mutex); 8294 adapter->driver_cmds.notify_event_cmd.status = LEAPRAID_CMD_PENDING; 8295 evt_notify_req = 8296 leapraid_get_task_desc( 8297 adapter, 8298 adapter->driver_cmds.notify_event_cmd.inter_taskid); 8299 memset(evt_notify_req, 0, sizeof(struct leapraid_evt_notify_req)); 8300 evt_notify_req->func = LEAPRAID_FUNC_EVENT_NOTIFY; 8301 for (i = 0; i < LEAPRAID_EVT_MASK_COUNT; i++) 8302 evt_notify_req->evt_masks[i] = 8303 cpu_to_le32(adapter->fw_evt_s.leapraid_evt_masks[i]); 8304 init_completion(&adapter->driver_cmds.notify_event_cmd.done); 8305 leapraid_fire_task(adapter, 8306 adapter->driver_cmds.notify_event_cmd.inter_taskid); 8307 wait_for_completion_timeout( 8308 &adapter->driver_cmds.notify_event_cmd.done, 8309 LEAPRAID_NOTIFY_EVENT_CMD_TIMEOUT * HZ); 8310 8311 if (!(adapter->driver_cmds.notify_event_cmd.status & 8312 LEAPRAID_CMD_DONE)) { 8313 rc = -EFAULT; 8314 goto out_cleanup; 8315 } 8316 8317 if (!(adapter->driver_cmds.notify_event_cmd.status & 8318 LEAPRAID_CMD_REPLY_VALID)) { 8319 rc = -EFAULT; 8320 goto out_cleanup; 8321 } 8322 8323 evt_notify_rep = (void *)&adapter->driver_cmds.notify_event_cmd.reply; 8324 adapter_status = le16_to_cpu(evt_notify_rep->adapter_status) & 8325 LEAPRAID_ADAPTER_STATUS_MASK; 8326 if (adapter_status != LEAPRAID_ADAPTER_STATUS_SUCCESS) 8327 rc = -EFAULT; 8328 8329 out_cleanup: 8330 adapter->driver_cmds.notify_event_cmd.status = LEAPRAID_CMD_NOT_USED; 8331 mutex_unlock(&adapter->driver_cmds.notify_event_cmd.mutex); 8332 8333 return rc; 8334 } 8335 8336 int leapraid_scan_dev(struct leapraid_adapter *adapter, bool async_scan_dev) 8337 { 8338 struct leapraid_scan_dev_req *scan_dev_req; 8339 struct leapraid_scan_dev_rep *scan_dev_rep; 8340 u16 adapter_status; 8341 int rc = 0; 8342 8343 dev_info(&adapter->pdev->dev, 8344 "Send device scan, async_scan_dev=%d!\n", async_scan_dev); 8345 8346 adapter->driver_cmds.scan_dev_cmd.status = LEAPRAID_CMD_PENDING; 8347 adapter->driver_cmds.scan_dev_cmd.async_scan_dev = async_scan_dev; 8348 scan_dev_req = 8349 leapraid_get_task_desc( 8350 adapter, 8351 adapter->driver_cmds.scan_dev_cmd.inter_taskid); 8352 memset(scan_dev_req, 0, sizeof(struct leapraid_scan_dev_req)); 8353 scan_dev_req->func = LEAPRAID_FUNC_SCAN_DEV; 8354 8355 if (async_scan_dev) { 8356 adapter->scan_dev_desc.first_scan_dev_fired = 1; 8357 leapraid_fire_task( 8358 adapter, 8359 adapter->driver_cmds.scan_dev_cmd.inter_taskid); 8360 return 0; 8361 } 8362 8363 init_completion(&adapter->driver_cmds.scan_dev_cmd.done); 8364 leapraid_fire_task(adapter, 8365 adapter->driver_cmds.scan_dev_cmd.inter_taskid); 8366 wait_for_completion_timeout(&adapter->driver_cmds.scan_dev_cmd.done, 8367 LEAPRAID_SCAN_DEV_CMD_TIMEOUT * HZ); 8368 if (!(adapter->driver_cmds.scan_dev_cmd.status & LEAPRAID_CMD_DONE)) { 8369 dev_err(&adapter->pdev->dev, "Device scan timeout!\n"); 8370 if (adapter->driver_cmds.scan_dev_cmd.status & 8371 LEAPRAID_CMD_RESET) 8372 rc = -EFAULT; 8373 else 8374 rc = -ETIME; 8375 goto out_cleanup; 8376 } 8377 8378 scan_dev_rep = (void *)&adapter->driver_cmds.scan_dev_cmd.reply; 8379 adapter_status = 8380 le16_to_cpu(scan_dev_rep->adapter_status) & 8381 LEAPRAID_ADAPTER_STATUS_MASK; 8382 if (adapter_status != LEAPRAID_ADAPTER_STATUS_SUCCESS) { 8383 dev_err(&adapter->pdev->dev, "Device scan failure!\n"); 8384 rc = -EFAULT; 8385 goto out_cleanup; 8386 } 8387 8388 out_cleanup: 8389 adapter->driver_cmds.scan_dev_cmd.status = LEAPRAID_CMD_NOT_USED; 8390 return rc; 8391 } 8392 8393 static void leapraid_init_task_tracker(struct leapraid_adapter *adapter) 8394 { 8395 unsigned long flags; 8396 8397 spin_lock_irqsave(&adapter->dynamic_task_desc.task_lock, flags); 8398 8399 spin_unlock_irqrestore(&adapter->dynamic_task_desc.task_lock, flags); 8400 } 8401 8402 static void leapraid_init_rep_msg_addr(struct leapraid_adapter *adapter) 8403 { 8404 u32 reply_address; 8405 unsigned int i; 8406 8407 for (i = 0, reply_address = (u32)adapter->mem_desc.rep_msg_dma; 8408 i < adapter->adapter_attr.rep_msg_qd; 8409 i++, reply_address += LEAPRAID_REPLY_SIZE) 8410 adapter->mem_desc.rep_msg_addr[i] = cpu_to_le32(reply_address); 8411 } 8412 8413 static void init_rep_desc( 8414 struct leapraid_rq *rq, 8415 int index, 8416 union leapraid_rep_desc_union *reply_post_free_contig) 8417 { 8418 struct leapraid_adapter *adapter = rq->adapter; 8419 unsigned int i; 8420 8421 if (!reset_devices) 8422 rq->rep_desc = 8423 adapter->mem_desc 8424 .rep_desc_seg_maint[index / 8425 LEAPRAID_REP_DESC_CHUNK_SIZE] 8426 .rep_desc_maint[index % 8427 LEAPRAID_REP_DESC_CHUNK_SIZE] 8428 .rep_desc; 8429 else 8430 rq->rep_desc = reply_post_free_contig; 8431 8432 rq->rep_post_host_idx = 0; 8433 for (i = 0; i < adapter->adapter_attr.rep_desc_qd; i++) 8434 rq->rep_desc[i].words = cpu_to_le64(ULLONG_MAX); 8435 } 8436 8437 static void leapraid_init_rep_desc(struct leapraid_adapter *adapter) 8438 { 8439 union leapraid_rep_desc_union *reply_post_free_contig; 8440 struct leapraid_int_rq *int_rq; 8441 struct leapraid_blk_mq_poll_rq *blk_mq_poll_rq; 8442 unsigned int i; 8443 int index; 8444 8445 index = 0; 8446 reply_post_free_contig = adapter->mem_desc 8447 .rep_desc_seg_maint[0] 8448 .rep_desc_maint[0] 8449 .rep_desc; 8450 8451 for (i = 0; i < adapter->notification_desc.iopoll_qdex; i++) { 8452 int_rq = &adapter->notification_desc.int_rqs[i]; 8453 init_rep_desc(&int_rq->rq, index, reply_post_free_contig); 8454 if (!reset_devices) 8455 index++; 8456 else 8457 reply_post_free_contig += 8458 adapter->adapter_attr.rep_desc_qd; 8459 } 8460 8461 for (i = 0; i < adapter->notification_desc.iopoll_qcnt; i++) { 8462 blk_mq_poll_rq = &adapter->notification_desc.blk_mq_poll_rqs[i]; 8463 init_rep_desc(&blk_mq_poll_rq->rq, 8464 index, reply_post_free_contig); 8465 if (!reset_devices) 8466 index++; 8467 else 8468 reply_post_free_contig += 8469 adapter->adapter_attr.rep_desc_qd; 8470 } 8471 } 8472 8473 static void leapraid_init_bar_idx_regs(struct leapraid_adapter *adapter) 8474 { 8475 struct leapraid_int_rq *int_rq; 8476 struct leapraid_blk_mq_poll_rq *blk_mq_poll_rq; 8477 unsigned int i, j; 8478 8479 adapter->rep_msg_host_idx = adapter->adapter_attr.rep_msg_qd - 1; 8480 writel(adapter->rep_msg_host_idx, 8481 &adapter->iomem_base->rep_msg_host_idx); 8482 8483 for (i = 0; i < adapter->notification_desc.iopoll_qdex; i++) { 8484 int_rq = &adapter->notification_desc.int_rqs[i]; 8485 for (j = 0; j < REP_POST_HOST_IDX_REG_CNT; j++) 8486 writel((int_rq->rq.msix_idx & 7) << 8487 LEAPRAID_RPHI_MSIX_IDX_SHIFT, 8488 &adapter->iomem_base->rep_post_reg_idx[j].idx); 8489 } 8490 8491 for (i = 0; i < adapter->notification_desc.iopoll_qcnt; i++) { 8492 blk_mq_poll_rq = 8493 &adapter->notification_desc.blk_mq_poll_rqs[i]; 8494 for (j = 0; j < REP_POST_HOST_IDX_REG_CNT; j++) 8495 writel((blk_mq_poll_rq->rq.msix_idx & 7) << 8496 LEAPRAID_RPHI_MSIX_IDX_SHIFT, 8497 &adapter->iomem_base->rep_post_reg_idx[j].idx); 8498 } 8499 } 8500 8501 static int leapraid_make_adapter_available(struct leapraid_adapter *adapter) 8502 { 8503 int rc; 8504 8505 leapraid_init_task_tracker(adapter); 8506 leapraid_init_rep_msg_addr(adapter); 8507 8508 if (adapter->scan_dev_desc.driver_loading) 8509 leapraid_configure_reply_queue_affinity(adapter); 8510 8511 leapraid_init_rep_desc(adapter); 8512 rc = leapraid_send_adapter_init(adapter); 8513 if (rc) 8514 return rc; 8515 8516 leapraid_init_bar_idx_regs(adapter); 8517 leapraid_unmask_int(adapter); 8518 rc = leapraid_cfg_pages(adapter); 8519 if (rc) 8520 return rc; 8521 8522 rc = leapraid_evt_notify(adapter); 8523 if (rc) 8524 return rc; 8525 8526 if (!adapter->access_ctrl.shost_recovering) { 8527 adapter->scan_dev_desc.wait_scan_dev_done = 1; 8528 return 0; 8529 } 8530 8531 return leapraid_scan_dev(adapter, false); 8532 } 8533 8534 int leapraid_ctrl_init(struct leapraid_adapter *adapter) 8535 { 8536 u32 cap; 8537 int rc; 8538 8539 rc = leapraid_init_driver_cmds(adapter); 8540 if (rc) { 8541 dev_err(&adapter->pdev->dev, "Init driver cmds failure\n"); 8542 goto out_free; 8543 } 8544 8545 rc = leapraid_set_pcie_and_notification(adapter); 8546 if (rc) 8547 goto out_free; 8548 8549 pci_set_drvdata(adapter->pdev, adapter->shost); 8550 8551 pcie_capability_read_dword(adapter->pdev, PCI_EXP_DEVCAP, &cap); 8552 8553 if (cap & PCI_EXP_DEVCAP_EXT_TAG) 8554 pcie_capability_set_word(adapter->pdev, PCI_EXP_DEVCTL, 8555 PCI_EXP_DEVCTL_EXT_TAG); 8556 8557 rc = leapraid_fw_log_init(adapter); 8558 if (rc) { 8559 dev_err(&adapter->pdev->dev, "FW log init failure\n"); 8560 goto out_free; 8561 } 8562 8563 rc = leapraid_request_host_memory(adapter); 8564 if (rc) { 8565 dev_err(&adapter->pdev->dev, "Request host memory failure\n"); 8566 goto out_free; 8567 } 8568 8569 init_waitqueue_head(&adapter->reset_desc.reset_wait_queue); 8570 init_waitqueue_head(&adapter->access_ctrl.shost_recover_wq); 8571 8572 rc = leapraid_alloc_dev_topo_bitmaps(adapter); 8573 if (rc) { 8574 dev_err(&adapter->pdev->dev, "Alloc topo bitmaps failure\n"); 8575 goto out_free; 8576 } 8577 8578 leapraid_init_event_mask(adapter); 8579 8580 rc = leapraid_make_adapter_available(adapter); 8581 if (rc) { 8582 dev_err(&adapter->pdev->dev, 8583 "Make adapter available failure\n"); 8584 goto out_free; 8585 } 8586 8587 leapraid_overheat_init(adapter); 8588 if (!adapter->overheat_desc.fault_overheat_wq) { 8589 rc = -ENOMEM; 8590 goto out_free; 8591 } 8592 8593 return 0; 8594 8595 out_free: 8596 adapter->access_ctrl.host_removing = 1; 8597 leapraid_fw_log_exit(adapter); 8598 leapraid_disable_controller(adapter); 8599 leapraid_free_host_memory(adapter); 8600 leapraid_free_dev_topo_bitmaps(adapter); 8601 pci_set_drvdata(adapter->pdev, NULL); 8602 return rc; 8603 } 8604 8605 void leapraid_remove_ctrl(struct leapraid_adapter *adapter) 8606 { 8607 leapraid_overheat_cleanup(adapter); 8608 leapraid_check_scheduled_fault_stop(adapter); 8609 leapraid_fw_log_stop(adapter); 8610 leapraid_fw_log_exit(adapter); 8611 leapraid_disable_controller(adapter); 8612 leapraid_free_host_memory(adapter); 8613 leapraid_free_dev_topo_bitmaps(adapter); 8614 leapraid_free_enc_list(adapter); 8615 pci_set_drvdata(adapter->pdev, NULL); 8616 } 8617