.. | .. |
---|
19 | 19 | #include <asm/sclp.h> |
---|
20 | 20 | |
---|
21 | 21 | #define SLOT_NAME_SIZE 10 |
---|
22 | | -static LIST_HEAD(s390_hotplug_slot_list); |
---|
23 | 22 | |
---|
24 | 23 | static int zpci_fn_configured(enum zpci_state state) |
---|
25 | 24 | { |
---|
.. | .. |
---|
27 | 26 | state == ZPCI_FN_STATE_ONLINE; |
---|
28 | 27 | } |
---|
29 | 28 | |
---|
30 | | -/* |
---|
31 | | - * struct slot - slot information for each *physical* slot |
---|
32 | | - */ |
---|
33 | | -struct slot { |
---|
34 | | - struct list_head slot_list; |
---|
35 | | - struct hotplug_slot *hotplug_slot; |
---|
36 | | - struct zpci_dev *zdev; |
---|
37 | | -}; |
---|
38 | | - |
---|
39 | | -static inline int slot_configure(struct slot *slot) |
---|
| 29 | +static inline int zdev_configure(struct zpci_dev *zdev) |
---|
40 | 30 | { |
---|
41 | | - int ret = sclp_pci_configure(slot->zdev->fid); |
---|
| 31 | + int ret = sclp_pci_configure(zdev->fid); |
---|
42 | 32 | |
---|
43 | | - zpci_dbg(3, "conf fid:%x, rc:%d\n", slot->zdev->fid, ret); |
---|
| 33 | + zpci_dbg(3, "conf fid:%x, rc:%d\n", zdev->fid, ret); |
---|
44 | 34 | if (!ret) |
---|
45 | | - slot->zdev->state = ZPCI_FN_STATE_CONFIGURED; |
---|
| 35 | + zdev->state = ZPCI_FN_STATE_CONFIGURED; |
---|
46 | 36 | |
---|
47 | 37 | return ret; |
---|
48 | 38 | } |
---|
49 | 39 | |
---|
50 | | -static inline int slot_deconfigure(struct slot *slot) |
---|
| 40 | +static inline int zdev_deconfigure(struct zpci_dev *zdev) |
---|
51 | 41 | { |
---|
52 | | - int ret = sclp_pci_deconfigure(slot->zdev->fid); |
---|
| 42 | + int ret = sclp_pci_deconfigure(zdev->fid); |
---|
53 | 43 | |
---|
54 | | - zpci_dbg(3, "deconf fid:%x, rc:%d\n", slot->zdev->fid, ret); |
---|
| 44 | + zpci_dbg(3, "deconf fid:%x, rc:%d\n", zdev->fid, ret); |
---|
55 | 45 | if (!ret) |
---|
56 | | - slot->zdev->state = ZPCI_FN_STATE_STANDBY; |
---|
| 46 | + zdev->state = ZPCI_FN_STATE_STANDBY; |
---|
57 | 47 | |
---|
58 | 48 | return ret; |
---|
59 | 49 | } |
---|
60 | 50 | |
---|
61 | 51 | static int enable_slot(struct hotplug_slot *hotplug_slot) |
---|
62 | 52 | { |
---|
63 | | - struct slot *slot = hotplug_slot->private; |
---|
| 53 | + struct zpci_dev *zdev = container_of(hotplug_slot, struct zpci_dev, |
---|
| 54 | + hotplug_slot); |
---|
| 55 | + struct zpci_bus *zbus = zdev->zbus; |
---|
64 | 56 | int rc; |
---|
65 | 57 | |
---|
66 | | - if (slot->zdev->state != ZPCI_FN_STATE_STANDBY) |
---|
| 58 | + if (zdev->state != ZPCI_FN_STATE_STANDBY) |
---|
67 | 59 | return -EIO; |
---|
68 | 60 | |
---|
69 | | - rc = slot_configure(slot); |
---|
| 61 | + rc = zdev_configure(zdev); |
---|
70 | 62 | if (rc) |
---|
71 | 63 | return rc; |
---|
72 | 64 | |
---|
73 | | - rc = zpci_enable_device(slot->zdev); |
---|
| 65 | + rc = zpci_enable_device(zdev); |
---|
74 | 66 | if (rc) |
---|
75 | 67 | goto out_deconfigure; |
---|
76 | 68 | |
---|
77 | | - pci_scan_slot(slot->zdev->bus, ZPCI_DEVFN); |
---|
| 69 | + pci_scan_slot(zbus->bus, zdev->devfn); |
---|
78 | 70 | pci_lock_rescan_remove(); |
---|
79 | | - pci_bus_add_devices(slot->zdev->bus); |
---|
| 71 | + pci_bus_add_devices(zbus->bus); |
---|
80 | 72 | pci_unlock_rescan_remove(); |
---|
81 | 73 | |
---|
82 | 74 | return rc; |
---|
83 | 75 | |
---|
84 | 76 | out_deconfigure: |
---|
85 | | - slot_deconfigure(slot); |
---|
| 77 | + zdev_deconfigure(zdev); |
---|
86 | 78 | return rc; |
---|
87 | 79 | } |
---|
88 | 80 | |
---|
89 | 81 | static int disable_slot(struct hotplug_slot *hotplug_slot) |
---|
90 | 82 | { |
---|
91 | | - struct slot *slot = hotplug_slot->private; |
---|
| 83 | + struct zpci_dev *zdev = container_of(hotplug_slot, struct zpci_dev, |
---|
| 84 | + hotplug_slot); |
---|
92 | 85 | struct pci_dev *pdev; |
---|
93 | 86 | int rc; |
---|
94 | 87 | |
---|
95 | | - if (!zpci_fn_configured(slot->zdev->state)) |
---|
| 88 | + if (!zpci_fn_configured(zdev->state)) |
---|
96 | 89 | return -EIO; |
---|
97 | 90 | |
---|
98 | | - pdev = pci_get_slot(slot->zdev->bus, ZPCI_DEVFN); |
---|
99 | | - if (pdev) { |
---|
100 | | - pci_stop_and_remove_bus_device_locked(pdev); |
---|
| 91 | + pdev = pci_get_slot(zdev->zbus->bus, zdev->devfn); |
---|
| 92 | + if (pdev && pci_num_vf(pdev)) { |
---|
101 | 93 | pci_dev_put(pdev); |
---|
| 94 | + return -EBUSY; |
---|
102 | 95 | } |
---|
| 96 | + pci_dev_put(pdev); |
---|
103 | 97 | |
---|
104 | | - rc = zpci_disable_device(slot->zdev); |
---|
| 98 | + zpci_remove_device(zdev, false); |
---|
| 99 | + |
---|
| 100 | + rc = zpci_disable_device(zdev); |
---|
105 | 101 | if (rc) |
---|
106 | 102 | return rc; |
---|
107 | 103 | |
---|
108 | | - return slot_deconfigure(slot); |
---|
| 104 | + return zdev_deconfigure(zdev); |
---|
109 | 105 | } |
---|
110 | 106 | |
---|
111 | 107 | static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) |
---|
112 | 108 | { |
---|
113 | | - struct slot *slot = hotplug_slot->private; |
---|
| 109 | + struct zpci_dev *zdev = container_of(hotplug_slot, struct zpci_dev, |
---|
| 110 | + hotplug_slot); |
---|
114 | 111 | |
---|
115 | | - switch (slot->zdev->state) { |
---|
116 | | - case ZPCI_FN_STATE_STANDBY: |
---|
117 | | - *value = 0; |
---|
118 | | - break; |
---|
119 | | - default: |
---|
120 | | - *value = 1; |
---|
121 | | - break; |
---|
122 | | - } |
---|
| 112 | + *value = zpci_is_device_configured(zdev) ? 1 : 0; |
---|
123 | 113 | return 0; |
---|
124 | 114 | } |
---|
125 | 115 | |
---|
.. | .. |
---|
130 | 120 | return 0; |
---|
131 | 121 | } |
---|
132 | 122 | |
---|
133 | | -static struct hotplug_slot_ops s390_hotplug_slot_ops = { |
---|
| 123 | +static const struct hotplug_slot_ops s390_hotplug_slot_ops = { |
---|
134 | 124 | .enable_slot = enable_slot, |
---|
135 | 125 | .disable_slot = disable_slot, |
---|
136 | 126 | .get_power_status = get_power_status, |
---|
.. | .. |
---|
139 | 129 | |
---|
140 | 130 | int zpci_init_slot(struct zpci_dev *zdev) |
---|
141 | 131 | { |
---|
142 | | - struct hotplug_slot *hotplug_slot; |
---|
143 | | - struct hotplug_slot_info *info; |
---|
144 | 132 | char name[SLOT_NAME_SIZE]; |
---|
145 | | - struct slot *slot; |
---|
146 | | - int rc; |
---|
| 133 | + struct zpci_bus *zbus = zdev->zbus; |
---|
147 | 134 | |
---|
148 | | - if (!zdev) |
---|
149 | | - return 0; |
---|
150 | | - |
---|
151 | | - slot = kzalloc(sizeof(*slot), GFP_KERNEL); |
---|
152 | | - if (!slot) |
---|
153 | | - goto error; |
---|
154 | | - |
---|
155 | | - hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL); |
---|
156 | | - if (!hotplug_slot) |
---|
157 | | - goto error_hp; |
---|
158 | | - hotplug_slot->private = slot; |
---|
159 | | - |
---|
160 | | - slot->hotplug_slot = hotplug_slot; |
---|
161 | | - slot->zdev = zdev; |
---|
162 | | - |
---|
163 | | - info = kzalloc(sizeof(*info), GFP_KERNEL); |
---|
164 | | - if (!info) |
---|
165 | | - goto error_info; |
---|
166 | | - hotplug_slot->info = info; |
---|
167 | | - |
---|
168 | | - hotplug_slot->ops = &s390_hotplug_slot_ops; |
---|
169 | | - |
---|
170 | | - get_power_status(hotplug_slot, &info->power_status); |
---|
171 | | - get_adapter_status(hotplug_slot, &info->adapter_status); |
---|
| 135 | + zdev->hotplug_slot.ops = &s390_hotplug_slot_ops; |
---|
172 | 136 | |
---|
173 | 137 | snprintf(name, SLOT_NAME_SIZE, "%08x", zdev->fid); |
---|
174 | | - rc = pci_hp_register(slot->hotplug_slot, zdev->bus, |
---|
175 | | - ZPCI_DEVFN, name); |
---|
176 | | - if (rc) |
---|
177 | | - goto error_reg; |
---|
178 | | - |
---|
179 | | - list_add(&slot->slot_list, &s390_hotplug_slot_list); |
---|
180 | | - return 0; |
---|
181 | | - |
---|
182 | | -error_reg: |
---|
183 | | - kfree(info); |
---|
184 | | -error_info: |
---|
185 | | - kfree(hotplug_slot); |
---|
186 | | -error_hp: |
---|
187 | | - kfree(slot); |
---|
188 | | -error: |
---|
189 | | - return -ENOMEM; |
---|
| 138 | + return pci_hp_register(&zdev->hotplug_slot, zbus->bus, |
---|
| 139 | + zdev->devfn, name); |
---|
190 | 140 | } |
---|
191 | 141 | |
---|
192 | 142 | void zpci_exit_slot(struct zpci_dev *zdev) |
---|
193 | 143 | { |
---|
194 | | - struct slot *slot, *next; |
---|
195 | | - |
---|
196 | | - list_for_each_entry_safe(slot, next, &s390_hotplug_slot_list, |
---|
197 | | - slot_list) { |
---|
198 | | - if (slot->zdev != zdev) |
---|
199 | | - continue; |
---|
200 | | - list_del(&slot->slot_list); |
---|
201 | | - pci_hp_deregister(slot->hotplug_slot); |
---|
202 | | - kfree(slot->hotplug_slot->info); |
---|
203 | | - kfree(slot->hotplug_slot); |
---|
204 | | - kfree(slot); |
---|
205 | | - } |
---|
| 144 | + pci_hp_deregister(&zdev->hotplug_slot); |
---|
206 | 145 | } |
---|