@@ -289,7 +289,7 @@ static void context_reset(struct afu_cmd *cmd)
289
289
atomic64_set (& afu -> room , room );
290
290
if (room )
291
291
goto write_rrin ;
292
- udelay (nretry );
292
+ udelay (1 << nretry );
293
293
} while (nretry ++ < MC_ROOM_RETRY_CNT );
294
294
295
295
pr_err ("%s: no cmd_room to send reset\n" , __func__ );
@@ -303,7 +303,7 @@ static void context_reset(struct afu_cmd *cmd)
303
303
if (rrin != 0x1 )
304
304
break ;
305
305
/* Double delay each time */
306
- udelay (2 << nretry );
306
+ udelay (1 << nretry );
307
307
} while (nretry ++ < MC_ROOM_RETRY_CNT );
308
308
}
309
309
@@ -338,7 +338,7 @@ static int send_cmd(struct afu *afu, struct afu_cmd *cmd)
338
338
atomic64_set (& afu -> room , room );
339
339
if (room )
340
340
goto write_ioarrin ;
341
- udelay (nretry );
341
+ udelay (1 << nretry );
342
342
} while (nretry ++ < MC_ROOM_RETRY_CNT );
343
343
344
344
dev_err (dev , "%s: no cmd_room to send 0x%X\n" ,
@@ -352,7 +352,7 @@ static int send_cmd(struct afu *afu, struct afu_cmd *cmd)
352
352
* afu->room.
353
353
*/
354
354
if (nretry ++ < MC_ROOM_RETRY_CNT ) {
355
- udelay (nretry );
355
+ udelay (1 << nretry );
356
356
goto retry ;
357
357
}
358
358
@@ -683,28 +683,23 @@ static void stop_afu(struct cxlflash_cfg *cfg)
683
683
}
684
684
685
685
/**
686
- * term_mc () - terminates the master context
686
+ * term_intr () - disables all AFU interrupts
687
687
* @cfg: Internal structure associated with the host.
688
688
* @level: Depth of allocation, where to begin waterfall tear down.
689
689
*
690
690
* Safe to call with AFU/MC in partially allocated/initialized state.
691
691
*/
692
- static void term_mc (struct cxlflash_cfg * cfg , enum undo_level level )
692
+ static void term_intr (struct cxlflash_cfg * cfg , enum undo_level level )
693
693
{
694
- int rc = 0 ;
695
694
struct afu * afu = cfg -> afu ;
696
695
struct device * dev = & cfg -> dev -> dev ;
697
696
698
697
if (!afu || !cfg -> mcctx ) {
699
- dev_err (dev , "%s: returning from term_mc with NULL afu or MC\n" ,
700
- __func__ );
698
+ dev_err (dev , "%s: returning with NULL afu or MC\n" , __func__ );
701
699
return ;
702
700
}
703
701
704
702
switch (level ) {
705
- case UNDO_START :
706
- rc = cxl_stop_context (cfg -> mcctx );
707
- BUG_ON (rc );
708
703
case UNMAP_THREE :
709
704
cxl_unmap_afu_irq (cfg -> mcctx , 3 , afu );
710
705
case UNMAP_TWO :
@@ -713,9 +708,34 @@ static void term_mc(struct cxlflash_cfg *cfg, enum undo_level level)
713
708
cxl_unmap_afu_irq (cfg -> mcctx , 1 , afu );
714
709
case FREE_IRQ :
715
710
cxl_free_afu_irqs (cfg -> mcctx );
716
- case RELEASE_CONTEXT :
717
- cfg -> mcctx = NULL ;
711
+ /* fall through */
712
+ case UNDO_NOOP :
713
+ /* No action required */
714
+ break ;
715
+ }
716
+ }
717
+
718
+ /**
719
+ * term_mc() - terminates the master context
720
+ * @cfg: Internal structure associated with the host.
721
+ * @level: Depth of allocation, where to begin waterfall tear down.
722
+ *
723
+ * Safe to call with AFU/MC in partially allocated/initialized state.
724
+ */
725
+ static void term_mc (struct cxlflash_cfg * cfg )
726
+ {
727
+ int rc = 0 ;
728
+ struct afu * afu = cfg -> afu ;
729
+ struct device * dev = & cfg -> dev -> dev ;
730
+
731
+ if (!afu || !cfg -> mcctx ) {
732
+ dev_err (dev , "%s: returning with NULL afu or MC\n" , __func__ );
733
+ return ;
718
734
}
735
+
736
+ rc = cxl_stop_context (cfg -> mcctx );
737
+ WARN_ON (rc );
738
+ cfg -> mcctx = NULL ;
719
739
}
720
740
721
741
/**
@@ -726,10 +746,20 @@ static void term_mc(struct cxlflash_cfg *cfg, enum undo_level level)
726
746
*/
727
747
static void term_afu (struct cxlflash_cfg * cfg )
728
748
{
749
+ /*
750
+ * Tear down is carefully orchestrated to ensure
751
+ * no interrupts can come in when the problem state
752
+ * area is unmapped.
753
+ *
754
+ * 1) Disable all AFU interrupts
755
+ * 2) Unmap the problem state area
756
+ * 3) Stop the master context
757
+ */
758
+ term_intr (cfg , UNMAP_THREE );
729
759
if (cfg -> afu )
730
760
stop_afu (cfg );
731
761
732
- term_mc (cfg , UNDO_START );
762
+ term_mc (cfg );
733
763
734
764
pr_debug ("%s: returning\n" , __func__ );
735
765
}
@@ -1597,41 +1627,24 @@ static int start_afu(struct cxlflash_cfg *cfg)
1597
1627
}
1598
1628
1599
1629
/**
1600
- * init_mc () - create and register as the master context
1630
+ * init_intr () - setup interrupt handlers for the master context
1601
1631
* @cfg: Internal structure associated with the host.
1602
1632
*
1603
1633
* Return: 0 on success, -errno on failure
1604
1634
*/
1605
- static int init_mc (struct cxlflash_cfg * cfg )
1635
+ static enum undo_level init_intr (struct cxlflash_cfg * cfg ,
1636
+ struct cxl_context * ctx )
1606
1637
{
1607
- struct cxl_context * ctx ;
1608
- struct device * dev = & cfg -> dev -> dev ;
1609
1638
struct afu * afu = cfg -> afu ;
1639
+ struct device * dev = & cfg -> dev -> dev ;
1610
1640
int rc = 0 ;
1611
- enum undo_level level ;
1612
-
1613
- ctx = cxl_get_context (cfg -> dev );
1614
- if (unlikely (!ctx ))
1615
- return - ENOMEM ;
1616
- cfg -> mcctx = ctx ;
1617
-
1618
- /* Set it up as a master with the CXL */
1619
- cxl_set_master (ctx );
1620
-
1621
- /* During initialization reset the AFU to start from a clean slate */
1622
- rc = cxl_afu_reset (cfg -> mcctx );
1623
- if (unlikely (rc )) {
1624
- dev_err (dev , "%s: initial AFU reset failed rc=%d\n" ,
1625
- __func__ , rc );
1626
- level = RELEASE_CONTEXT ;
1627
- goto out ;
1628
- }
1641
+ enum undo_level level = UNDO_NOOP ;
1629
1642
1630
1643
rc = cxl_allocate_afu_irqs (ctx , 3 );
1631
1644
if (unlikely (rc )) {
1632
1645
dev_err (dev , "%s: call to allocate_afu_irqs failed rc=%d!\n" ,
1633
1646
__func__ , rc );
1634
- level = RELEASE_CONTEXT ;
1647
+ level = UNDO_NOOP ;
1635
1648
goto out ;
1636
1649
}
1637
1650
@@ -1661,8 +1674,47 @@ static int init_mc(struct cxlflash_cfg *cfg)
1661
1674
level = UNMAP_TWO ;
1662
1675
goto out ;
1663
1676
}
1677
+ out :
1678
+ return level ;
1679
+ }
1664
1680
1665
- rc = 0 ;
1681
+ /**
1682
+ * init_mc() - create and register as the master context
1683
+ * @cfg: Internal structure associated with the host.
1684
+ *
1685
+ * Return: 0 on success, -errno on failure
1686
+ */
1687
+ static int init_mc (struct cxlflash_cfg * cfg )
1688
+ {
1689
+ struct cxl_context * ctx ;
1690
+ struct device * dev = & cfg -> dev -> dev ;
1691
+ int rc = 0 ;
1692
+ enum undo_level level ;
1693
+
1694
+ ctx = cxl_get_context (cfg -> dev );
1695
+ if (unlikely (!ctx )) {
1696
+ rc = - ENOMEM ;
1697
+ goto ret ;
1698
+ }
1699
+ cfg -> mcctx = ctx ;
1700
+
1701
+ /* Set it up as a master with the CXL */
1702
+ cxl_set_master (ctx );
1703
+
1704
+ /* During initialization reset the AFU to start from a clean slate */
1705
+ rc = cxl_afu_reset (cfg -> mcctx );
1706
+ if (unlikely (rc )) {
1707
+ dev_err (dev , "%s: initial AFU reset failed rc=%d\n" ,
1708
+ __func__ , rc );
1709
+ goto ret ;
1710
+ }
1711
+
1712
+ level = init_intr (cfg , ctx );
1713
+ if (unlikely (level )) {
1714
+ dev_err (dev , "%s: setting up interrupts failed rc=%d\n" ,
1715
+ __func__ , rc );
1716
+ goto out ;
1717
+ }
1666
1718
1667
1719
/* This performs the equivalent of the CXL_IOCTL_START_WORK.
1668
1720
* The CXL_IOCTL_GET_PROCESS_ELEMENT is implicit in the process
@@ -1678,7 +1730,7 @@ static int init_mc(struct cxlflash_cfg *cfg)
1678
1730
pr_debug ("%s: returning rc=%d\n" , __func__ , rc );
1679
1731
return rc ;
1680
1732
out :
1681
- term_mc (cfg , level );
1733
+ term_intr (cfg , level );
1682
1734
goto ret ;
1683
1735
}
1684
1736
@@ -1751,7 +1803,8 @@ static int init_afu(struct cxlflash_cfg *cfg)
1751
1803
err2 :
1752
1804
kref_put (& afu -> mapcount , afu_unmap );
1753
1805
err1 :
1754
- term_mc (cfg , UNDO_START );
1806
+ term_intr (cfg , UNMAP_THREE );
1807
+ term_mc (cfg );
1755
1808
goto out ;
1756
1809
}
1757
1810
@@ -2488,8 +2541,7 @@ static pci_ers_result_t cxlflash_pci_error_detected(struct pci_dev *pdev,
2488
2541
if (unlikely (rc ))
2489
2542
dev_err (dev , "%s: Failed to mark user contexts!(%d)\n" ,
2490
2543
__func__ , rc );
2491
- stop_afu (cfg );
2492
- term_mc (cfg , UNDO_START );
2544
+ term_afu (cfg );
2493
2545
return PCI_ERS_RESULT_NEED_RESET ;
2494
2546
case pci_channel_io_perm_failure :
2495
2547
cfg -> state = STATE_FAILTERM ;
0 commit comments