| .. | .. |
|---|
| 36 | 36 | #include <linux/netdevice.h> |
|---|
| 37 | 37 | #include <linux/vmalloc.h> |
|---|
| 38 | 38 | #include <linux/delay.h> |
|---|
| 39 | | -#include <linux/idr.h> |
|---|
| 40 | 39 | #include <linux/module.h> |
|---|
| 41 | 40 | #include <linux/printk.h> |
|---|
| 42 | 41 | #ifdef CONFIG_INFINIBAND_QIB_DCA |
|---|
| .. | .. |
|---|
| 95 | 94 | |
|---|
| 96 | 95 | static void verify_interrupt(struct timer_list *); |
|---|
| 97 | 96 | |
|---|
| 98 | | -static struct idr qib_unit_table; |
|---|
| 97 | +DEFINE_XARRAY_FLAGS(qib_dev_table, XA_FLAGS_ALLOC | XA_FLAGS_LOCK_IRQ); |
|---|
| 99 | 98 | u32 qib_cpulist_count; |
|---|
| 100 | 99 | unsigned long *qib_cpulist; |
|---|
| 101 | 100 | |
|---|
| .. | .. |
|---|
| 209 | 208 | rcd->rcvegrbuf_chunks = (rcd->rcvegrcnt + |
|---|
| 210 | 209 | rcd->rcvegrbufs_perchunk - 1) / |
|---|
| 211 | 210 | rcd->rcvegrbufs_perchunk; |
|---|
| 212 | | - BUG_ON(!is_power_of_2(rcd->rcvegrbufs_perchunk)); |
|---|
| 213 | 211 | rcd->rcvegrbufs_perchunk_shift = |
|---|
| 214 | 212 | ilog2(rcd->rcvegrbufs_perchunk); |
|---|
| 215 | 213 | } |
|---|
| .. | .. |
|---|
| 786 | 784 | { |
|---|
| 787 | 785 | } |
|---|
| 788 | 786 | |
|---|
| 789 | | -static inline struct qib_devdata *__qib_lookup(int unit) |
|---|
| 790 | | -{ |
|---|
| 791 | | - return idr_find(&qib_unit_table, unit); |
|---|
| 792 | | -} |
|---|
| 793 | | - |
|---|
| 794 | 787 | struct qib_devdata *qib_lookup(int unit) |
|---|
| 795 | 788 | { |
|---|
| 796 | | - struct qib_devdata *dd; |
|---|
| 797 | | - unsigned long flags; |
|---|
| 798 | | - |
|---|
| 799 | | - spin_lock_irqsave(&qib_devs_lock, flags); |
|---|
| 800 | | - dd = __qib_lookup(unit); |
|---|
| 801 | | - spin_unlock_irqrestore(&qib_devs_lock, flags); |
|---|
| 802 | | - |
|---|
| 803 | | - return dd; |
|---|
| 789 | + return xa_load(&qib_dev_table, unit); |
|---|
| 804 | 790 | } |
|---|
| 805 | 791 | |
|---|
| 806 | 792 | /* |
|---|
| .. | .. |
|---|
| 1047 | 1033 | { |
|---|
| 1048 | 1034 | unsigned long flags; |
|---|
| 1049 | 1035 | |
|---|
| 1050 | | - spin_lock_irqsave(&qib_devs_lock, flags); |
|---|
| 1051 | | - idr_remove(&qib_unit_table, dd->unit); |
|---|
| 1052 | | - list_del(&dd->list); |
|---|
| 1053 | | - spin_unlock_irqrestore(&qib_devs_lock, flags); |
|---|
| 1036 | + xa_lock_irqsave(&qib_dev_table, flags); |
|---|
| 1037 | + __xa_erase(&qib_dev_table, dd->unit); |
|---|
| 1038 | + xa_unlock_irqrestore(&qib_dev_table, flags); |
|---|
| 1054 | 1039 | |
|---|
| 1055 | 1040 | #ifdef CONFIG_DEBUG_FS |
|---|
| 1056 | 1041 | qib_dbg_ibdev_exit(&dd->verbs_dev); |
|---|
| .. | .. |
|---|
| 1071 | 1056 | |
|---|
| 1072 | 1057 | u64 qib_sps_ints(void) |
|---|
| 1073 | 1058 | { |
|---|
| 1074 | | - unsigned long flags; |
|---|
| 1059 | + unsigned long index, flags; |
|---|
| 1075 | 1060 | struct qib_devdata *dd; |
|---|
| 1076 | 1061 | u64 sps_ints = 0; |
|---|
| 1077 | 1062 | |
|---|
| 1078 | | - spin_lock_irqsave(&qib_devs_lock, flags); |
|---|
| 1079 | | - list_for_each_entry(dd, &qib_dev_list, list) { |
|---|
| 1063 | + xa_lock_irqsave(&qib_dev_table, flags); |
|---|
| 1064 | + xa_for_each(&qib_dev_table, index, dd) { |
|---|
| 1080 | 1065 | sps_ints += qib_int_counter(dd); |
|---|
| 1081 | 1066 | } |
|---|
| 1082 | | - spin_unlock_irqrestore(&qib_devs_lock, flags); |
|---|
| 1067 | + xa_unlock_irqrestore(&qib_dev_table, flags); |
|---|
| 1083 | 1068 | return sps_ints; |
|---|
| 1084 | 1069 | } |
|---|
| 1085 | 1070 | |
|---|
| .. | .. |
|---|
| 1088 | 1073 | * allocator, because the verbs cleanup process both does cleanup and |
|---|
| 1089 | 1074 | * free of the data structure. |
|---|
| 1090 | 1075 | * "extra" is for chip-specific data. |
|---|
| 1091 | | - * |
|---|
| 1092 | | - * Use the idr mechanism to get a unit number for this unit. |
|---|
| 1093 | 1076 | */ |
|---|
| 1094 | 1077 | struct qib_devdata *qib_alloc_devdata(struct pci_dev *pdev, size_t extra) |
|---|
| 1095 | 1078 | { |
|---|
| 1096 | | - unsigned long flags; |
|---|
| 1097 | 1079 | struct qib_devdata *dd; |
|---|
| 1098 | 1080 | int ret, nports; |
|---|
| 1099 | 1081 | |
|---|
| .. | .. |
|---|
| 1104 | 1086 | if (!dd) |
|---|
| 1105 | 1087 | return ERR_PTR(-ENOMEM); |
|---|
| 1106 | 1088 | |
|---|
| 1107 | | - INIT_LIST_HEAD(&dd->list); |
|---|
| 1108 | | - |
|---|
| 1109 | | - idr_preload(GFP_KERNEL); |
|---|
| 1110 | | - spin_lock_irqsave(&qib_devs_lock, flags); |
|---|
| 1111 | | - |
|---|
| 1112 | | - ret = idr_alloc(&qib_unit_table, dd, 0, 0, GFP_NOWAIT); |
|---|
| 1113 | | - if (ret >= 0) { |
|---|
| 1114 | | - dd->unit = ret; |
|---|
| 1115 | | - list_add(&dd->list, &qib_dev_list); |
|---|
| 1116 | | - } |
|---|
| 1117 | | - |
|---|
| 1118 | | - spin_unlock_irqrestore(&qib_devs_lock, flags); |
|---|
| 1119 | | - idr_preload_end(); |
|---|
| 1120 | | - |
|---|
| 1089 | + ret = xa_alloc_irq(&qib_dev_table, &dd->unit, dd, xa_limit_32b, |
|---|
| 1090 | + GFP_KERNEL); |
|---|
| 1121 | 1091 | if (ret < 0) { |
|---|
| 1122 | 1092 | qib_early_err(&pdev->dev, |
|---|
| 1123 | 1093 | "Could not allocate unit ID: error %d\n", -ret); |
|---|
| .. | .. |
|---|
| 1256 | 1226 | * These must be called before the driver is registered with |
|---|
| 1257 | 1227 | * the PCI subsystem. |
|---|
| 1258 | 1228 | */ |
|---|
| 1259 | | - idr_init(&qib_unit_table); |
|---|
| 1260 | | - |
|---|
| 1261 | 1229 | #ifdef CONFIG_INFINIBAND_QIB_DCA |
|---|
| 1262 | 1230 | dca_register_notify(&dca_notifier); |
|---|
| 1263 | 1231 | #endif |
|---|
| .. | .. |
|---|
| 1282 | 1250 | #ifdef CONFIG_DEBUG_FS |
|---|
| 1283 | 1251 | qib_dbg_exit(); |
|---|
| 1284 | 1252 | #endif |
|---|
| 1285 | | - idr_destroy(&qib_unit_table); |
|---|
| 1286 | 1253 | qib_dev_cleanup(); |
|---|
| 1287 | 1254 | bail: |
|---|
| 1288 | 1255 | return ret; |
|---|
| .. | .. |
|---|
| 1314 | 1281 | qib_cpulist_count = 0; |
|---|
| 1315 | 1282 | kfree(qib_cpulist); |
|---|
| 1316 | 1283 | |
|---|
| 1317 | | - idr_destroy(&qib_unit_table); |
|---|
| 1284 | + WARN_ON(!xa_empty(&qib_dev_table)); |
|---|
| 1318 | 1285 | qib_dev_cleanup(); |
|---|
| 1319 | 1286 | } |
|---|
| 1320 | 1287 | |
|---|
| .. | .. |
|---|
| 1792 | 1759 | qib_userlen = dd->ureg_align * dd->cfgctxts; |
|---|
| 1793 | 1760 | |
|---|
| 1794 | 1761 | /* Sanity checks passed, now create the new mappings */ |
|---|
| 1795 | | - qib_kregbase = ioremap_nocache(qib_physaddr, qib_kreglen); |
|---|
| 1762 | + qib_kregbase = ioremap(qib_physaddr, qib_kreglen); |
|---|
| 1796 | 1763 | if (!qib_kregbase) |
|---|
| 1797 | 1764 | goto bail; |
|---|
| 1798 | 1765 | |
|---|
| .. | .. |
|---|
| 1801 | 1768 | goto bail_kregbase; |
|---|
| 1802 | 1769 | |
|---|
| 1803 | 1770 | if (qib_userlen) { |
|---|
| 1804 | | - qib_userbase = ioremap_nocache(qib_physaddr + dd->uregbase, |
|---|
| 1771 | + qib_userbase = ioremap(qib_physaddr + dd->uregbase, |
|---|
| 1805 | 1772 | qib_userlen); |
|---|
| 1806 | 1773 | if (!qib_userbase) |
|---|
| 1807 | 1774 | goto bail_piobase; |
|---|