diff options
Diffstat (limited to 'drivers/scsi/mpt3sas/mpt3sas_base.c')
-rw-r--r-- | drivers/scsi/mpt3sas/mpt3sas_base.c | 53 |
1 files changed, 43 insertions, 10 deletions
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 1560115079c7..14a781b6b88d 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c | |||
@@ -4,7 +4,8 @@ | |||
4 | * | 4 | * |
5 | * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.c | 5 | * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.c |
6 | * Copyright (C) 2012-2014 LSI Corporation | 6 | * Copyright (C) 2012-2014 LSI Corporation |
7 | * (mailto:DL-MPTFusionLinux@lsi.com) | 7 | * Copyright (C) 2013-2014 Avago Technologies |
8 | * (mailto: MPT-FusionLinux.pdl@avagotech.com) | ||
8 | * | 9 | * |
9 | * This program is free software; you can redistribute it and/or | 10 | * This program is free software; you can redistribute it and/or |
10 | * modify it under the terms of the GNU General Public License | 11 | * modify it under the terms of the GNU General Public License |
@@ -619,6 +620,9 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc, | |||
619 | case MPI2_EVENT_LOG_ENTRY_ADDED: | 620 | case MPI2_EVENT_LOG_ENTRY_ADDED: |
620 | desc = "Log Entry Added"; | 621 | desc = "Log Entry Added"; |
621 | break; | 622 | break; |
623 | case MPI2_EVENT_TEMP_THRESHOLD: | ||
624 | desc = "Temperature Threshold"; | ||
625 | break; | ||
622 | } | 626 | } |
623 | 627 | ||
624 | if (!desc) | 628 | if (!desc) |
@@ -1580,6 +1584,8 @@ _base_free_irq(struct MPT3SAS_ADAPTER *ioc) | |||
1580 | 1584 | ||
1581 | list_for_each_entry_safe(reply_q, next, &ioc->reply_queue_list, list) { | 1585 | list_for_each_entry_safe(reply_q, next, &ioc->reply_queue_list, list) { |
1582 | list_del(&reply_q->list); | 1586 | list_del(&reply_q->list); |
1587 | irq_set_affinity_hint(reply_q->vector, NULL); | ||
1588 | free_cpumask_var(reply_q->affinity_hint); | ||
1583 | synchronize_irq(reply_q->vector); | 1589 | synchronize_irq(reply_q->vector); |
1584 | free_irq(reply_q->vector, reply_q); | 1590 | free_irq(reply_q->vector, reply_q); |
1585 | kfree(reply_q); | 1591 | kfree(reply_q); |
@@ -1609,6 +1615,11 @@ _base_request_irq(struct MPT3SAS_ADAPTER *ioc, u8 index, u32 vector) | |||
1609 | reply_q->ioc = ioc; | 1615 | reply_q->ioc = ioc; |
1610 | reply_q->msix_index = index; | 1616 | reply_q->msix_index = index; |
1611 | reply_q->vector = vector; | 1617 | reply_q->vector = vector; |
1618 | |||
1619 | if (!alloc_cpumask_var(&reply_q->affinity_hint, GFP_KERNEL)) | ||
1620 | return -ENOMEM; | ||
1621 | cpumask_clear(reply_q->affinity_hint); | ||
1622 | |||
1612 | atomic_set(&reply_q->busy, 0); | 1623 | atomic_set(&reply_q->busy, 0); |
1613 | if (ioc->msix_enable) | 1624 | if (ioc->msix_enable) |
1614 | snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d-msix%d", | 1625 | snprintf(reply_q->name, MPT_NAME_LENGTH, "%s%d-msix%d", |
@@ -1643,6 +1654,7 @@ static void | |||
1643 | _base_assign_reply_queues(struct MPT3SAS_ADAPTER *ioc) | 1654 | _base_assign_reply_queues(struct MPT3SAS_ADAPTER *ioc) |
1644 | { | 1655 | { |
1645 | unsigned int cpu, nr_cpus, nr_msix, index = 0; | 1656 | unsigned int cpu, nr_cpus, nr_msix, index = 0; |
1657 | struct adapter_reply_queue *reply_q; | ||
1646 | 1658 | ||
1647 | if (!_base_is_controller_msix_enabled(ioc)) | 1659 | if (!_base_is_controller_msix_enabled(ioc)) |
1648 | return; | 1660 | return; |
@@ -1657,20 +1669,30 @@ _base_assign_reply_queues(struct MPT3SAS_ADAPTER *ioc) | |||
1657 | 1669 | ||
1658 | cpu = cpumask_first(cpu_online_mask); | 1670 | cpu = cpumask_first(cpu_online_mask); |
1659 | 1671 | ||
1660 | do { | 1672 | list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { |
1673 | |||
1661 | unsigned int i, group = nr_cpus / nr_msix; | 1674 | unsigned int i, group = nr_cpus / nr_msix; |
1662 | 1675 | ||
1676 | if (cpu >= nr_cpus) | ||
1677 | break; | ||
1678 | |||
1663 | if (index < nr_cpus % nr_msix) | 1679 | if (index < nr_cpus % nr_msix) |
1664 | group++; | 1680 | group++; |
1665 | 1681 | ||
1666 | for (i = 0 ; i < group ; i++) { | 1682 | for (i = 0 ; i < group ; i++) { |
1667 | ioc->cpu_msix_table[cpu] = index; | 1683 | ioc->cpu_msix_table[cpu] = index; |
1684 | cpumask_or(reply_q->affinity_hint, | ||
1685 | reply_q->affinity_hint, get_cpu_mask(cpu)); | ||
1668 | cpu = cpumask_next(cpu, cpu_online_mask); | 1686 | cpu = cpumask_next(cpu, cpu_online_mask); |
1669 | } | 1687 | } |
1670 | 1688 | ||
1689 | if (irq_set_affinity_hint(reply_q->vector, | ||
1690 | reply_q->affinity_hint)) | ||
1691 | dinitprintk(ioc, pr_info(MPT3SAS_FMT | ||
1692 | "error setting affinity hint for irq vector %d\n", | ||
1693 | ioc->name, reply_q->vector)); | ||
1671 | index++; | 1694 | index++; |
1672 | 1695 | } | |
1673 | } while (cpu < nr_cpus); | ||
1674 | } | 1696 | } |
1675 | 1697 | ||
1676 | /** | 1698 | /** |
@@ -2500,6 +2522,7 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc) | |||
2500 | mpt3sas_config_get_ioc_pg8(ioc, &mpi_reply, &ioc->ioc_pg8); | 2522 | mpt3sas_config_get_ioc_pg8(ioc, &mpi_reply, &ioc->ioc_pg8); |
2501 | mpt3sas_config_get_iounit_pg0(ioc, &mpi_reply, &ioc->iounit_pg0); | 2523 | mpt3sas_config_get_iounit_pg0(ioc, &mpi_reply, &ioc->iounit_pg0); |
2502 | mpt3sas_config_get_iounit_pg1(ioc, &mpi_reply, &ioc->iounit_pg1); | 2524 | mpt3sas_config_get_iounit_pg1(ioc, &mpi_reply, &ioc->iounit_pg1); |
2525 | mpt3sas_config_get_iounit_pg8(ioc, &mpi_reply, &ioc->iounit_pg8); | ||
2503 | _base_display_ioc_capabilities(ioc); | 2526 | _base_display_ioc_capabilities(ioc); |
2504 | 2527 | ||
2505 | /* | 2528 | /* |
@@ -2516,6 +2539,9 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc) | |||
2516 | MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING; | 2539 | MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING; |
2517 | ioc->iounit_pg1.Flags = cpu_to_le32(iounit_pg1_flags); | 2540 | ioc->iounit_pg1.Flags = cpu_to_le32(iounit_pg1_flags); |
2518 | mpt3sas_config_set_iounit_pg1(ioc, &mpi_reply, &ioc->iounit_pg1); | 2541 | mpt3sas_config_set_iounit_pg1(ioc, &mpi_reply, &ioc->iounit_pg1); |
2542 | |||
2543 | if (ioc->iounit_pg8.NumSensors) | ||
2544 | ioc->temp_sensors_count = ioc->iounit_pg8.NumSensors; | ||
2519 | } | 2545 | } |
2520 | 2546 | ||
2521 | /** | 2547 | /** |
@@ -2659,8 +2685,14 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) | |||
2659 | 2685 | ||
2660 | if (sg_tablesize < MPT3SAS_MIN_PHYS_SEGMENTS) | 2686 | if (sg_tablesize < MPT3SAS_MIN_PHYS_SEGMENTS) |
2661 | sg_tablesize = MPT3SAS_MIN_PHYS_SEGMENTS; | 2687 | sg_tablesize = MPT3SAS_MIN_PHYS_SEGMENTS; |
2662 | else if (sg_tablesize > MPT3SAS_MAX_PHYS_SEGMENTS) | 2688 | else if (sg_tablesize > MPT3SAS_MAX_PHYS_SEGMENTS) { |
2663 | sg_tablesize = MPT3SAS_MAX_PHYS_SEGMENTS; | 2689 | sg_tablesize = min_t(unsigned short, sg_tablesize, |
2690 | SCSI_MAX_SG_CHAIN_SEGMENTS); | ||
2691 | pr_warn(MPT3SAS_FMT | ||
2692 | "sg_tablesize(%u) is bigger than kernel" | ||
2693 | " defined SCSI_MAX_SG_SEGMENTS(%u)\n", ioc->name, | ||
2694 | sg_tablesize, MPT3SAS_MAX_PHYS_SEGMENTS); | ||
2695 | } | ||
2664 | ioc->shost->sg_tablesize = sg_tablesize; | 2696 | ioc->shost->sg_tablesize = sg_tablesize; |
2665 | 2697 | ||
2666 | ioc->hi_priority_depth = facts->HighPriorityCredit; | 2698 | ioc->hi_priority_depth = facts->HighPriorityCredit; |
@@ -3419,7 +3451,7 @@ mpt3sas_base_sas_iounit_control(struct MPT3SAS_ADAPTER *ioc, | |||
3419 | u16 smid; | 3451 | u16 smid; |
3420 | u32 ioc_state; | 3452 | u32 ioc_state; |
3421 | unsigned long timeleft; | 3453 | unsigned long timeleft; |
3422 | u8 issue_reset; | 3454 | bool issue_reset = false; |
3423 | int rc; | 3455 | int rc; |
3424 | void *request; | 3456 | void *request; |
3425 | u16 wait_state_count; | 3457 | u16 wait_state_count; |
@@ -3483,7 +3515,7 @@ mpt3sas_base_sas_iounit_control(struct MPT3SAS_ADAPTER *ioc, | |||
3483 | _debug_dump_mf(mpi_request, | 3515 | _debug_dump_mf(mpi_request, |
3484 | sizeof(Mpi2SasIoUnitControlRequest_t)/4); | 3516 | sizeof(Mpi2SasIoUnitControlRequest_t)/4); |
3485 | if (!(ioc->base_cmds.status & MPT3_CMD_RESET)) | 3517 | if (!(ioc->base_cmds.status & MPT3_CMD_RESET)) |
3486 | issue_reset = 1; | 3518 | issue_reset = true; |
3487 | goto issue_host_reset; | 3519 | goto issue_host_reset; |
3488 | } | 3520 | } |
3489 | if (ioc->base_cmds.status & MPT3_CMD_REPLY_VALID) | 3521 | if (ioc->base_cmds.status & MPT3_CMD_REPLY_VALID) |
@@ -3523,7 +3555,7 @@ mpt3sas_base_scsi_enclosure_processor(struct MPT3SAS_ADAPTER *ioc, | |||
3523 | u16 smid; | 3555 | u16 smid; |
3524 | u32 ioc_state; | 3556 | u32 ioc_state; |
3525 | unsigned long timeleft; | 3557 | unsigned long timeleft; |
3526 | u8 issue_reset; | 3558 | bool issue_reset = false; |
3527 | int rc; | 3559 | int rc; |
3528 | void *request; | 3560 | void *request; |
3529 | u16 wait_state_count; | 3561 | u16 wait_state_count; |
@@ -3581,7 +3613,7 @@ mpt3sas_base_scsi_enclosure_processor(struct MPT3SAS_ADAPTER *ioc, | |||
3581 | _debug_dump_mf(mpi_request, | 3613 | _debug_dump_mf(mpi_request, |
3582 | sizeof(Mpi2SepRequest_t)/4); | 3614 | sizeof(Mpi2SepRequest_t)/4); |
3583 | if (!(ioc->base_cmds.status & MPT3_CMD_RESET)) | 3615 | if (!(ioc->base_cmds.status & MPT3_CMD_RESET)) |
3584 | issue_reset = 1; | 3616 | issue_reset = false; |
3585 | goto issue_host_reset; | 3617 | goto issue_host_reset; |
3586 | } | 3618 | } |
3587 | if (ioc->base_cmds.status & MPT3_CMD_REPLY_VALID) | 3619 | if (ioc->base_cmds.status & MPT3_CMD_REPLY_VALID) |
@@ -4720,6 +4752,7 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) | |||
4720 | _base_unmask_events(ioc, MPI2_EVENT_IR_PHYSICAL_DISK); | 4752 | _base_unmask_events(ioc, MPI2_EVENT_IR_PHYSICAL_DISK); |
4721 | _base_unmask_events(ioc, MPI2_EVENT_IR_OPERATION_STATUS); | 4753 | _base_unmask_events(ioc, MPI2_EVENT_IR_OPERATION_STATUS); |
4722 | _base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED); | 4754 | _base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED); |
4755 | _base_unmask_events(ioc, MPI2_EVENT_TEMP_THRESHOLD); | ||
4723 | 4756 | ||
4724 | r = _base_make_ioc_operational(ioc, CAN_SLEEP); | 4757 | r = _base_make_ioc_operational(ioc, CAN_SLEEP); |
4725 | if (r) | 4758 | if (r) |