Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ats.c
Go to the documentation of this file.
1 /*
2  * drivers/pci/ats.c
3  *
4  * Copyright (C) 2009 Intel Corporation, Yu Zhao <[email protected]>
5  * Copyright (C) 2011 Advanced Micro Devices,
6  *
7  * PCI Express I/O Virtualization (IOV) support.
8  * Address Translation Service 1.0
9  * Page Request Interface added by Joerg Roedel <[email protected]>
10  * PASID support added by Joerg Roedel <[email protected]>
11  */
12 
13 #include <linux/export.h>
14 #include <linux/pci-ats.h>
15 #include <linux/pci.h>
16 #include <linux/slab.h>
17 
18 #include "pci.h"
19 
20 static int ats_alloc_one(struct pci_dev *dev, int ps)
21 {
22  int pos;
23  u16 cap;
24  struct pci_ats *ats;
25 
27  if (!pos)
28  return -ENODEV;
29 
30  ats = kzalloc(sizeof(*ats), GFP_KERNEL);
31  if (!ats)
32  return -ENOMEM;
33 
34  ats->pos = pos;
35  ats->stu = ps;
36  pci_read_config_word(dev, pos + PCI_ATS_CAP, &cap);
37  ats->qdep = PCI_ATS_CAP_QDEP(cap) ? PCI_ATS_CAP_QDEP(cap) :
39  dev->ats = ats;
40 
41  return 0;
42 }
43 
44 static void ats_free_one(struct pci_dev *dev)
45 {
46  kfree(dev->ats);
47  dev->ats = NULL;
48 }
49 
57 int pci_enable_ats(struct pci_dev *dev, int ps)
58 {
59  int rc;
60  u16 ctrl;
61 
62  BUG_ON(dev->ats && dev->ats->is_enabled);
63 
64  if (ps < PCI_ATS_MIN_STU)
65  return -EINVAL;
66 
67  if (dev->is_physfn || dev->is_virtfn) {
68  struct pci_dev *pdev = dev->is_physfn ? dev : dev->physfn;
69 
70  mutex_lock(&pdev->sriov->lock);
71  if (pdev->ats)
72  rc = pdev->ats->stu == ps ? 0 : -EINVAL;
73  else
74  rc = ats_alloc_one(pdev, ps);
75 
76  if (!rc)
77  pdev->ats->ref_cnt++;
78  mutex_unlock(&pdev->sriov->lock);
79  if (rc)
80  return rc;
81  }
82 
83  if (!dev->is_physfn) {
84  rc = ats_alloc_one(dev, ps);
85  if (rc)
86  return rc;
87  }
88 
89  ctrl = PCI_ATS_CTRL_ENABLE;
90  if (!dev->is_virtfn)
91  ctrl |= PCI_ATS_CTRL_STU(ps - PCI_ATS_MIN_STU);
92  pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl);
93 
94  dev->ats->is_enabled = 1;
95 
96  return 0;
97 }
99 
104 void pci_disable_ats(struct pci_dev *dev)
105 {
106  u16 ctrl;
107 
108  BUG_ON(!dev->ats || !dev->ats->is_enabled);
109 
110  pci_read_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, &ctrl);
111  ctrl &= ~PCI_ATS_CTRL_ENABLE;
112  pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl);
113 
114  dev->ats->is_enabled = 0;
115 
116  if (dev->is_physfn || dev->is_virtfn) {
117  struct pci_dev *pdev = dev->is_physfn ? dev : dev->physfn;
118 
119  mutex_lock(&pdev->sriov->lock);
120  pdev->ats->ref_cnt--;
121  if (!pdev->ats->ref_cnt)
122  ats_free_one(pdev);
123  mutex_unlock(&pdev->sriov->lock);
124  }
125 
126  if (!dev->is_physfn)
127  ats_free_one(dev);
128 }
130 
132 {
133  u16 ctrl;
134 
135  if (!pci_ats_enabled(dev))
136  return;
138  BUG();
139 
140  ctrl = PCI_ATS_CTRL_ENABLE;
141  if (!dev->is_virtfn)
142  ctrl |= PCI_ATS_CTRL_STU(dev->ats->stu - PCI_ATS_MIN_STU);
143 
144  pci_write_config_word(dev, dev->ats->pos + PCI_ATS_CTRL, ctrl);
145 }
147 
160 int pci_ats_queue_depth(struct pci_dev *dev)
161 {
162  int pos;
163  u16 cap;
164 
165  if (dev->is_virtfn)
166  return 0;
167 
168  if (dev->ats)
169  return dev->ats->qdep;
170 
172  if (!pos)
173  return -ENODEV;
174 
175  pci_read_config_word(dev, pos + PCI_ATS_CAP, &cap);
176 
177  return PCI_ATS_CAP_QDEP(cap) ? PCI_ATS_CAP_QDEP(cap) :
179 }
181 
182 #ifdef CONFIG_PCI_PRI
183 
189 int pci_enable_pri(struct pci_dev *pdev, u32 reqs)
190 {
191  u16 control, status;
192  u32 max_requests;
193  int pos;
194 
196  if (!pos)
197  return -EINVAL;
198 
199  pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control);
200  pci_read_config_word(pdev, pos + PCI_PRI_STATUS, &status);
201  if ((control & PCI_PRI_CTRL_ENABLE) ||
202  !(status & PCI_PRI_STATUS_STOPPED))
203  return -EBUSY;
204 
205  pci_read_config_dword(pdev, pos + PCI_PRI_MAX_REQ, &max_requests);
206  reqs = min(max_requests, reqs);
207  pci_write_config_dword(pdev, pos + PCI_PRI_ALLOC_REQ, reqs);
208 
209  control |= PCI_PRI_CTRL_ENABLE;
210  pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);
211 
212  return 0;
213 }
214 EXPORT_SYMBOL_GPL(pci_enable_pri);
215 
222 void pci_disable_pri(struct pci_dev *pdev)
223 {
224  u16 control;
225  int pos;
226 
228  if (!pos)
229  return;
230 
231  pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control);
232  control &= ~PCI_PRI_CTRL_ENABLE;
233  pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);
234 }
235 EXPORT_SYMBOL_GPL(pci_disable_pri);
236 
243 bool pci_pri_enabled(struct pci_dev *pdev)
244 {
245  u16 control;
246  int pos;
247 
249  if (!pos)
250  return false;
251 
252  pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control);
253 
254  return (control & PCI_PRI_CTRL_ENABLE) ? true : false;
255 }
256 EXPORT_SYMBOL_GPL(pci_pri_enabled);
257 
265 int pci_reset_pri(struct pci_dev *pdev)
266 {
267  u16 control;
268  int pos;
269 
271  if (!pos)
272  return -EINVAL;
273 
274  pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control);
275  if (control & PCI_PRI_CTRL_ENABLE)
276  return -EBUSY;
277 
278  control |= PCI_PRI_CTRL_RESET;
279 
280  pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);
281 
282  return 0;
283 }
284 EXPORT_SYMBOL_GPL(pci_reset_pri);
285 
298 bool pci_pri_stopped(struct pci_dev *pdev)
299 {
300  u16 control, status;
301  int pos;
302 
304  if (!pos)
305  return true;
306 
307  pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control);
308  pci_read_config_word(pdev, pos + PCI_PRI_STATUS, &status);
309 
310  if (control & PCI_PRI_CTRL_ENABLE)
311  return false;
312 
313  return (status & PCI_PRI_STATUS_STOPPED) ? true : false;
314 }
315 EXPORT_SYMBOL_GPL(pci_pri_stopped);
316 
327 int pci_pri_status(struct pci_dev *pdev)
328 {
329  u16 status, control;
330  int pos;
331 
333  if (!pos)
334  return -EINVAL;
335 
336  pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control);
337  pci_read_config_word(pdev, pos + PCI_PRI_STATUS, &status);
338 
339  /* Stopped bit is undefined when enable == 1, so clear it */
340  if (control & PCI_PRI_CTRL_ENABLE)
341  status &= ~PCI_PRI_STATUS_STOPPED;
342 
343  return status;
344 }
345 EXPORT_SYMBOL_GPL(pci_pri_status);
346 #endif /* CONFIG_PCI_PRI */
347 
348 #ifdef CONFIG_PCI_PASID
349 
358 int pci_enable_pasid(struct pci_dev *pdev, int features)
359 {
360  u16 control, supported;
361  int pos;
362 
364  if (!pos)
365  return -EINVAL;
366 
367  pci_read_config_word(pdev, pos + PCI_PASID_CTRL, &control);
368  pci_read_config_word(pdev, pos + PCI_PASID_CAP, &supported);
369 
370  if (control & PCI_PASID_CTRL_ENABLE)
371  return -EINVAL;
372 
373  supported &= PCI_PASID_CAP_EXEC | PCI_PASID_CAP_PRIV;
374 
375  /* User wants to enable anything unsupported? */
376  if ((supported & features) != features)
377  return -EINVAL;
378 
379  control = PCI_PASID_CTRL_ENABLE | features;
380 
381  pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control);
382 
383  return 0;
384 }
385 EXPORT_SYMBOL_GPL(pci_enable_pasid);
386 
392 void pci_disable_pasid(struct pci_dev *pdev)
393 {
394  u16 control = 0;
395  int pos;
396 
398  if (!pos)
399  return;
400 
401  pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control);
402 }
403 EXPORT_SYMBOL_GPL(pci_disable_pasid);
404 
415 int pci_pasid_features(struct pci_dev *pdev)
416 {
417  u16 supported;
418  int pos;
419 
421  if (!pos)
422  return -EINVAL;
423 
424  pci_read_config_word(pdev, pos + PCI_PASID_CAP, &supported);
425 
426  supported &= PCI_PASID_CAP_EXEC | PCI_PASID_CAP_PRIV;
427 
428  return supported;
429 }
430 EXPORT_SYMBOL_GPL(pci_pasid_features);
431 
432 #define PASID_NUMBER_SHIFT 8
433 #define PASID_NUMBER_MASK (0x1f << PASID_NUMBER_SHIFT)
434 
441 int pci_max_pasids(struct pci_dev *pdev)
442 {
443  u16 supported;
444  int pos;
445 
447  if (!pos)
448  return -EINVAL;
449 
450  pci_read_config_word(pdev, pos + PCI_PASID_CAP, &supported);
451 
452  supported = (supported & PASID_NUMBER_MASK) >> PASID_NUMBER_SHIFT;
453 
454  return (1 << supported);
455 }
456 EXPORT_SYMBOL_GPL(pci_max_pasids);
457 #endif /* CONFIG_PCI_PASID */