.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Adaptec AAC series RAID controller driver |
---|
3 | 4 | * (c) Copyright 2001 Red Hat Inc. |
---|
.. | .. |
---|
9 | 10 | * 2010-2015 PMC-Sierra, Inc. (aacraid@pmc-sierra.com) |
---|
10 | 11 | * 2016-2017 Microsemi Corp. (aacraid@microsemi.com) |
---|
11 | 12 | * |
---|
12 | | - * This program is free software; you can redistribute it and/or modify |
---|
13 | | - * it under the terms of the GNU General Public License as published by |
---|
14 | | - * the Free Software Foundation; either version 2, or (at your option) |
---|
15 | | - * any later version. |
---|
16 | | - * |
---|
17 | | - * This program is distributed in the hope that it will be useful, |
---|
18 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
19 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
20 | | - * GNU General Public License for more details. |
---|
21 | | - * |
---|
22 | | - * You should have received a copy of the GNU General Public License |
---|
23 | | - * along with this program; see the file COPYING. If not, write to |
---|
24 | | - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
---|
25 | | - * |
---|
26 | 13 | * Module Name: |
---|
27 | 14 | * commsup.c |
---|
28 | 15 | * |
---|
29 | 16 | * Abstract: Contain all routines that are required for FSA host/adapter |
---|
30 | 17 | * communication. |
---|
31 | | - * |
---|
32 | 18 | */ |
---|
33 | 19 | |
---|
34 | 20 | #include <linux/kernel.h> |
---|
.. | .. |
---|
44 | 30 | #include <linux/delay.h> |
---|
45 | 31 | #include <linux/kthread.h> |
---|
46 | 32 | #include <linux/interrupt.h> |
---|
47 | | -#include <linux/semaphore.h> |
---|
48 | 33 | #include <linux/bcd.h> |
---|
49 | 34 | #include <scsi/scsi.h> |
---|
50 | 35 | #include <scsi/scsi_host.h> |
---|
.. | .. |
---|
189 | 174 | fibptr->hw_fib_va = hw_fib; |
---|
190 | 175 | fibptr->data = (void *) fibptr->hw_fib_va->data; |
---|
191 | 176 | fibptr->next = fibptr+1; /* Forward chain the fibs */ |
---|
192 | | - sema_init(&fibptr->event_wait, 0); |
---|
| 177 | + init_completion(&fibptr->event_wait); |
---|
193 | 178 | spin_lock_init(&fibptr->event_lock); |
---|
194 | 179 | hw_fib->header.XferState = cpu_to_le32(0xffffffff); |
---|
195 | 180 | hw_fib->header.SenderSize = |
---|
.. | .. |
---|
229 | 214 | /** |
---|
230 | 215 | * aac_fib_alloc_tag-allocate a fib using tags |
---|
231 | 216 | * @dev: Adapter to allocate the fib for |
---|
| 217 | + * @scmd: SCSI command |
---|
232 | 218 | * |
---|
233 | 219 | * Allocate a fib from the adapter fib pool using tags |
---|
234 | 220 | * from the blk layer. |
---|
.. | .. |
---|
247 | 233 | fibptr->type = FSAFS_NTC_FIB_CONTEXT; |
---|
248 | 234 | fibptr->callback_data = NULL; |
---|
249 | 235 | fibptr->callback = NULL; |
---|
| 236 | + fibptr->flags = 0; |
---|
250 | 237 | |
---|
251 | 238 | return fibptr; |
---|
252 | 239 | } |
---|
.. | .. |
---|
419 | 406 | * aac_queue_get - get the next free QE |
---|
420 | 407 | * @dev: Adapter |
---|
421 | 408 | * @index: Returned index |
---|
422 | | - * @priority: Priority of fib |
---|
423 | | - * @fib: Fib to associate with the queue entry |
---|
| 409 | + * @qid: Queue number |
---|
| 410 | + * @hw_fib: Fib to associate with the queue entry |
---|
424 | 411 | * @wait: Wait if queue full |
---|
425 | 412 | * @fibptr: Driver fib object to go with fib |
---|
426 | 413 | * @nonotify: Don't notify the adapter |
---|
.. | .. |
---|
623 | 610 | } |
---|
624 | 611 | if (wait) { |
---|
625 | 612 | fibptr->flags |= FIB_CONTEXT_FLAG_WAIT; |
---|
626 | | - if (down_interruptible(&fibptr->event_wait)) { |
---|
| 613 | + if (wait_for_completion_interruptible(&fibptr->event_wait)) { |
---|
627 | 614 | fibptr->flags &= ~FIB_CONTEXT_FLAG_WAIT; |
---|
628 | 615 | return -EFAULT; |
---|
629 | 616 | } |
---|
.. | .. |
---|
659 | 646 | * hardware failure has occurred. |
---|
660 | 647 | */ |
---|
661 | 648 | unsigned long timeout = jiffies + (180 * HZ); /* 3 minutes */ |
---|
662 | | - while (down_trylock(&fibptr->event_wait)) { |
---|
| 649 | + while (!try_wait_for_completion(&fibptr->event_wait)) { |
---|
663 | 650 | int blink; |
---|
664 | 651 | if (time_is_before_eq_jiffies(timeout)) { |
---|
665 | 652 | struct aac_queue * q = &dev->queues->queue[AdapNormCmdQueue]; |
---|
.. | .. |
---|
689 | 676 | */ |
---|
690 | 677 | schedule(); |
---|
691 | 678 | } |
---|
692 | | - } else if (down_interruptible(&fibptr->event_wait)) { |
---|
| 679 | + } else if (wait_for_completion_interruptible(&fibptr->event_wait)) { |
---|
693 | 680 | /* Do nothing ... satisfy |
---|
694 | | - * down_interruptible must_check */ |
---|
| 681 | + * wait_for_completion_interruptible must_check */ |
---|
695 | 682 | } |
---|
696 | 683 | |
---|
697 | 684 | spin_lock_irqsave(&fibptr->event_lock, flags); |
---|
.. | .. |
---|
777 | 764 | return -EFAULT; |
---|
778 | 765 | |
---|
779 | 766 | fibptr->flags |= FIB_CONTEXT_FLAG_WAIT; |
---|
780 | | - if (down_interruptible(&fibptr->event_wait)) |
---|
| 767 | + if (wait_for_completion_interruptible(&fibptr->event_wait)) |
---|
781 | 768 | fibptr->done = 2; |
---|
782 | 769 | fibptr->flags &= ~(FIB_CONTEXT_FLAG_WAIT); |
---|
783 | 770 | |
---|
.. | .. |
---|
948 | 935 | |
---|
949 | 936 | /** |
---|
950 | 937 | * aac_fib_complete - fib completion handler |
---|
951 | | - * @fib: FIB to complete |
---|
| 938 | + * @fibptr: FIB to complete |
---|
952 | 939 | * |
---|
953 | 940 | * Will do all necessary work to complete a FIB. |
---|
954 | 941 | */ |
---|
.. | .. |
---|
1063 | 1050 | } |
---|
1064 | 1051 | } |
---|
1065 | 1052 | |
---|
| 1053 | +#define AIF_SNIFF_TIMEOUT (500*HZ) |
---|
1066 | 1054 | /** |
---|
1067 | 1055 | * aac_handle_aif - Handle a message from the firmware |
---|
1068 | 1056 | * @dev: Which adapter this fib is from |
---|
.. | .. |
---|
1071 | 1059 | * This routine handles a driver notify fib from the adapter and |
---|
1072 | 1060 | * dispatches it to the appropriate routine for handling. |
---|
1073 | 1061 | */ |
---|
1074 | | - |
---|
1075 | | -#define AIF_SNIFF_TIMEOUT (500*HZ) |
---|
1076 | 1062 | static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) |
---|
1077 | 1063 | { |
---|
1078 | 1064 | struct hw_fib * hw_fib = fibptr->hw_fib_va; |
---|
.. | .. |
---|
1378 | 1364 | |
---|
1379 | 1365 | container = 0; |
---|
1380 | 1366 | retry_next: |
---|
1381 | | - if (device_config_needed == NOTHING) |
---|
1382 | | - for (; container < dev->maximum_num_containers; ++container) { |
---|
1383 | | - if ((dev->fsa_dev[container].config_waiting_on == 0) && |
---|
1384 | | - (dev->fsa_dev[container].config_needed != NOTHING) && |
---|
1385 | | - time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT)) { |
---|
1386 | | - device_config_needed = |
---|
1387 | | - dev->fsa_dev[container].config_needed; |
---|
1388 | | - dev->fsa_dev[container].config_needed = NOTHING; |
---|
1389 | | - channel = CONTAINER_TO_CHANNEL(container); |
---|
1390 | | - id = CONTAINER_TO_ID(container); |
---|
1391 | | - lun = CONTAINER_TO_LUN(container); |
---|
1392 | | - break; |
---|
| 1367 | + if (device_config_needed == NOTHING) { |
---|
| 1368 | + for (; container < dev->maximum_num_containers; ++container) { |
---|
| 1369 | + if ((dev->fsa_dev[container].config_waiting_on == 0) && |
---|
| 1370 | + (dev->fsa_dev[container].config_needed != NOTHING) && |
---|
| 1371 | + time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT)) { |
---|
| 1372 | + device_config_needed = |
---|
| 1373 | + dev->fsa_dev[container].config_needed; |
---|
| 1374 | + dev->fsa_dev[container].config_needed = NOTHING; |
---|
| 1375 | + channel = CONTAINER_TO_CHANNEL(container); |
---|
| 1376 | + id = CONTAINER_TO_ID(container); |
---|
| 1377 | + lun = CONTAINER_TO_LUN(container); |
---|
| 1378 | + break; |
---|
| 1379 | + } |
---|
1393 | 1380 | } |
---|
1394 | 1381 | } |
---|
1395 | 1382 | if (device_config_needed == NOTHING) |
---|
.. | .. |
---|
1444 | 1431 | "enclosure services event"); |
---|
1445 | 1432 | scsi_device_set_state(device, SDEV_RUNNING); |
---|
1446 | 1433 | } |
---|
1447 | | - /* FALLTHRU */ |
---|
| 1434 | + fallthrough; |
---|
1448 | 1435 | case CHANGE: |
---|
1449 | 1436 | if ((channel == CONTAINER_CHANNEL) |
---|
1450 | 1437 | && (!dev->fsa_dev[container].valid)) { |
---|
.. | .. |
---|
1477 | 1464 | } |
---|
1478 | 1465 | } |
---|
1479 | 1466 | |
---|
| 1467 | +static void aac_schedule_bus_scan(struct aac_dev *aac) |
---|
| 1468 | +{ |
---|
| 1469 | + if (aac->sa_firmware) |
---|
| 1470 | + aac_schedule_safw_scan_worker(aac); |
---|
| 1471 | + else |
---|
| 1472 | + aac_schedule_src_reinit_aif_worker(aac); |
---|
| 1473 | +} |
---|
| 1474 | + |
---|
1480 | 1475 | static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) |
---|
1481 | 1476 | { |
---|
1482 | 1477 | int index, quirks; |
---|
1483 | 1478 | int retval; |
---|
1484 | | - struct Scsi_Host *host; |
---|
1485 | | - struct scsi_device *dev; |
---|
1486 | | - struct scsi_cmnd *command; |
---|
1487 | | - struct scsi_cmnd *command_list; |
---|
| 1479 | + struct Scsi_Host *host = aac->scsi_host_ptr; |
---|
1488 | 1480 | int jafo = 0; |
---|
1489 | 1481 | int bled; |
---|
1490 | 1482 | u64 dmamask; |
---|
.. | .. |
---|
1500 | 1492 | * - The card is dead, or will be very shortly ;-/ so no new |
---|
1501 | 1493 | * commands are completing in the interrupt service. |
---|
1502 | 1494 | */ |
---|
1503 | | - host = aac->scsi_host_ptr; |
---|
1504 | | - scsi_block_requests(host); |
---|
1505 | 1495 | aac_adapter_disable_int(aac); |
---|
1506 | 1496 | if (aac->thread && aac->thread->pid != current->pid) { |
---|
1507 | 1497 | spin_unlock_irq(host->host_lock); |
---|
.. | .. |
---|
1539 | 1529 | || fib->flags & FIB_CONTEXT_FLAG_WAIT) { |
---|
1540 | 1530 | unsigned long flagv; |
---|
1541 | 1531 | spin_lock_irqsave(&fib->event_lock, flagv); |
---|
1542 | | - up(&fib->event_wait); |
---|
| 1532 | + complete(&fib->event_wait); |
---|
1543 | 1533 | spin_unlock_irqrestore(&fib->event_lock, flagv); |
---|
1544 | 1534 | schedule(); |
---|
1545 | 1535 | retval = 0; |
---|
.. | .. |
---|
1561 | 1551 | aac_fib_map_free(aac); |
---|
1562 | 1552 | dma_free_coherent(&aac->pdev->dev, aac->comm_size, aac->comm_addr, |
---|
1563 | 1553 | aac->comm_phys); |
---|
| 1554 | + aac_adapter_ioremap(aac, 0); |
---|
1564 | 1555 | aac->comm_addr = NULL; |
---|
1565 | 1556 | aac->comm_phys = 0; |
---|
1566 | 1557 | kfree(aac->queues); |
---|
.. | .. |
---|
1571 | 1562 | dmamask = DMA_BIT_MASK(32); |
---|
1572 | 1563 | quirks = aac_get_driver_ident(index)->quirks; |
---|
1573 | 1564 | if (quirks & AAC_QUIRK_31BIT) |
---|
1574 | | - retval = pci_set_dma_mask(aac->pdev, dmamask); |
---|
| 1565 | + retval = dma_set_mask(&aac->pdev->dev, dmamask); |
---|
1575 | 1566 | else if (!(quirks & AAC_QUIRK_SRC)) |
---|
1576 | | - retval = pci_set_dma_mask(aac->pdev, dmamask); |
---|
| 1567 | + retval = dma_set_mask(&aac->pdev->dev, dmamask); |
---|
1577 | 1568 | else |
---|
1578 | | - retval = pci_set_consistent_dma_mask(aac->pdev, dmamask); |
---|
| 1569 | + retval = dma_set_coherent_mask(&aac->pdev->dev, dmamask); |
---|
1579 | 1570 | |
---|
1580 | 1571 | if (quirks & AAC_QUIRK_31BIT && !retval) { |
---|
1581 | 1572 | dmamask = DMA_BIT_MASK(31); |
---|
1582 | | - retval = pci_set_consistent_dma_mask(aac->pdev, dmamask); |
---|
| 1573 | + retval = dma_set_coherent_mask(&aac->pdev->dev, dmamask); |
---|
1583 | 1574 | } |
---|
1584 | 1575 | |
---|
1585 | 1576 | if (retval) |
---|
.. | .. |
---|
1612 | 1603 | * This is where the assumption that the Adapter is quiesced |
---|
1613 | 1604 | * is important. |
---|
1614 | 1605 | */ |
---|
1615 | | - command_list = NULL; |
---|
1616 | | - __shost_for_each_device(dev, host) { |
---|
1617 | | - unsigned long flags; |
---|
1618 | | - spin_lock_irqsave(&dev->list_lock, flags); |
---|
1619 | | - list_for_each_entry(command, &dev->cmd_list, list) |
---|
1620 | | - if (command->SCp.phase == AAC_OWNER_FIRMWARE) { |
---|
1621 | | - command->SCp.buffer = (struct scatterlist *)command_list; |
---|
1622 | | - command_list = command; |
---|
1623 | | - } |
---|
1624 | | - spin_unlock_irqrestore(&dev->list_lock, flags); |
---|
1625 | | - } |
---|
1626 | | - while ((command = command_list)) { |
---|
1627 | | - command_list = (struct scsi_cmnd *)command->SCp.buffer; |
---|
1628 | | - command->SCp.buffer = NULL; |
---|
1629 | | - command->result = DID_OK << 16 |
---|
1630 | | - | COMMAND_COMPLETE << 8 |
---|
1631 | | - | SAM_STAT_TASK_SET_FULL; |
---|
1632 | | - command->SCp.phase = AAC_OWNER_ERROR_HANDLER; |
---|
1633 | | - command->scsi_done(command); |
---|
1634 | | - } |
---|
1635 | | - /* |
---|
1636 | | - * Any Device that was already marked offline needs to be marked |
---|
1637 | | - * running |
---|
1638 | | - */ |
---|
1639 | | - __shost_for_each_device(dev, host) { |
---|
1640 | | - if (!scsi_device_online(dev)) |
---|
1641 | | - scsi_device_set_state(dev, SDEV_RUNNING); |
---|
1642 | | - } |
---|
1643 | | - retval = 0; |
---|
| 1606 | + scsi_host_complete_all_commands(host, DID_RESET); |
---|
1644 | 1607 | |
---|
| 1608 | + retval = 0; |
---|
1645 | 1609 | out: |
---|
1646 | 1610 | aac->in_reset = 0; |
---|
1647 | | - scsi_unblock_requests(host); |
---|
1648 | 1611 | |
---|
1649 | 1612 | /* |
---|
1650 | 1613 | * Issue bus rescan to catch any configuration that might have |
---|
.. | .. |
---|
1652 | 1615 | */ |
---|
1653 | 1616 | if (!retval && !is_kdump_kernel()) { |
---|
1654 | 1617 | dev_info(&aac->pdev->dev, "Scheduling bus rescan\n"); |
---|
1655 | | - aac_schedule_safw_scan_worker(aac); |
---|
| 1618 | + aac_schedule_bus_scan(aac); |
---|
1656 | 1619 | } |
---|
1657 | 1620 | |
---|
1658 | 1621 | if (jafo) { |
---|
.. | .. |
---|
1664 | 1627 | int aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) |
---|
1665 | 1628 | { |
---|
1666 | 1629 | unsigned long flagv = 0; |
---|
1667 | | - int retval; |
---|
1668 | | - struct Scsi_Host * host; |
---|
| 1630 | + int retval, unblock_retval; |
---|
| 1631 | + struct Scsi_Host *host = aac->scsi_host_ptr; |
---|
1669 | 1632 | int bled; |
---|
1670 | 1633 | |
---|
1671 | 1634 | if (spin_trylock_irqsave(&aac->fib_lock, flagv) == 0) |
---|
.. | .. |
---|
1683 | 1646 | * target (block maximum 60 seconds). Although not necessary, |
---|
1684 | 1647 | * it does make us a good storage citizen. |
---|
1685 | 1648 | */ |
---|
1686 | | - host = aac->scsi_host_ptr; |
---|
1687 | | - scsi_block_requests(host); |
---|
| 1649 | + scsi_host_block(host); |
---|
1688 | 1650 | |
---|
1689 | 1651 | /* Quiesce build, flush cache, write through mode */ |
---|
1690 | 1652 | if (forced < 2) |
---|
.. | .. |
---|
1695 | 1657 | retval = _aac_reset_adapter(aac, bled, reset_type); |
---|
1696 | 1658 | spin_unlock_irqrestore(host->host_lock, flagv); |
---|
1697 | 1659 | |
---|
| 1660 | + unblock_retval = scsi_host_unblock(host, SDEV_RUNNING); |
---|
| 1661 | + if (!retval) |
---|
| 1662 | + retval = unblock_retval; |
---|
1698 | 1663 | if ((forced < 2) && (retval == -ENODEV)) { |
---|
1699 | 1664 | /* Unwind aac_send_shutdown() IOP_RESET unsupported/disabled */ |
---|
1700 | 1665 | struct fib * fibctx = aac_fib_alloc(aac); |
---|
.. | .. |
---|
1829 | 1794 | * Set the event to wake up the |
---|
1830 | 1795 | * thread that will waiting. |
---|
1831 | 1796 | */ |
---|
1832 | | - up(&fibctx->wait_sem); |
---|
| 1797 | + complete(&fibctx->completion); |
---|
1833 | 1798 | } else { |
---|
1834 | 1799 | printk(KERN_WARNING "aifd: didn't allocate NewFib.\n"); |
---|
1835 | 1800 | kfree(fib); |
---|
.. | .. |
---|
1971 | 1936 | mutex_unlock(&dev->scan_mutex); |
---|
1972 | 1937 | |
---|
1973 | 1938 | return rcode; |
---|
| 1939 | +} |
---|
| 1940 | + |
---|
| 1941 | +void aac_src_reinit_aif_worker(struct work_struct *work) |
---|
| 1942 | +{ |
---|
| 1943 | + struct aac_dev *dev = container_of(to_delayed_work(work), |
---|
| 1944 | + struct aac_dev, src_reinit_aif_worker); |
---|
| 1945 | + |
---|
| 1946 | + wait_event(dev->scsi_host_ptr->host_wait, |
---|
| 1947 | + !scsi_host_in_recovery(dev->scsi_host_ptr)); |
---|
| 1948 | + aac_reinit_aif(dev, dev->cardtype); |
---|
1974 | 1949 | } |
---|
1975 | 1950 | |
---|
1976 | 1951 | /** |
---|
.. | .. |
---|
2166 | 2141 | * Set the event to wake up the |
---|
2167 | 2142 | * thread that is waiting. |
---|
2168 | 2143 | */ |
---|
2169 | | - up(&fibctx->wait_sem); |
---|
| 2144 | + complete(&fibctx->completion); |
---|
2170 | 2145 | |
---|
2171 | 2146 | entry = entry->next; |
---|
2172 | 2147 | } |
---|
.. | .. |
---|
2377 | 2352 | goto out; |
---|
2378 | 2353 | } |
---|
2379 | 2354 | |
---|
2380 | | -int aac_send_safw_hostttime(struct aac_dev *dev, struct timespec64 *now) |
---|
| 2355 | +static int aac_send_safw_hostttime(struct aac_dev *dev, struct timespec64 *now) |
---|
2381 | 2356 | { |
---|
2382 | 2357 | struct tm cur_tm; |
---|
2383 | 2358 | char wellness_str[] = "<HW>TD\010\0\0\0\0\0\0\0\0\0DW\0\0ZZ"; |
---|
.. | .. |
---|
2406 | 2381 | return ret; |
---|
2407 | 2382 | } |
---|
2408 | 2383 | |
---|
2409 | | -int aac_send_hosttime(struct aac_dev *dev, struct timespec64 *now) |
---|
| 2384 | +static int aac_send_hosttime(struct aac_dev *dev, struct timespec64 *now) |
---|
2410 | 2385 | { |
---|
2411 | 2386 | int ret = -ENOMEM; |
---|
2412 | 2387 | struct fib *fibptr; |
---|
.. | .. |
---|
2442 | 2417 | |
---|
2443 | 2418 | /** |
---|
2444 | 2419 | * aac_command_thread - command processing thread |
---|
2445 | | - * @dev: Adapter to monitor |
---|
| 2420 | + * @data: Adapter to monitor |
---|
2446 | 2421 | * |
---|
2447 | 2422 | * Waits on the commandready event in it's queue. When the event gets set |
---|
2448 | 2423 | * it will pull FIBs off it's queue. It will continue to pull FIBs off |
---|
.. | .. |
---|
2587 | 2562 | void aac_free_irq(struct aac_dev *dev) |
---|
2588 | 2563 | { |
---|
2589 | 2564 | int i; |
---|
2590 | | - int cpu; |
---|
2591 | 2565 | |
---|
2592 | | - cpu = cpumask_first(cpu_online_mask); |
---|
2593 | 2566 | if (aac_is_src(dev)) { |
---|
2594 | 2567 | if (dev->max_msix > 1) { |
---|
2595 | 2568 | for (i = 0; i < dev->max_msix; i++) |
---|