PCI/VPD: Move VPD access code to vpd.c
[linux-2.6-microblaze.git] / drivers / pci / vpd.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * File:        vpd.c
4  * Purpose:     Provide PCI VPD support
5  *
6  * Copyright (C) 2010 Broadcom Corporation.
7  */
8
9 #include <linux/pci.h>
10 #include <linux/delay.h>
11 #include <linux/export.h>
12 #include <linux/sched/signal.h>
13 #include "pci.h"
14
15 /* VPD access through PCI 2.2+ VPD capability */
16
17 /**
18  * pci_read_vpd - Read one entry from Vital Product Data
19  * @dev:        pci device struct
20  * @pos:        offset in vpd space
21  * @count:      number of bytes to read
22  * @buf:        pointer to where to store result
23  */
24 ssize_t pci_read_vpd(struct pci_dev *dev, loff_t pos, size_t count, void *buf)
25 {
26         if (!dev->vpd || !dev->vpd->ops)
27                 return -ENODEV;
28         return dev->vpd->ops->read(dev, pos, count, buf);
29 }
30 EXPORT_SYMBOL(pci_read_vpd);
31
32 /**
33  * pci_write_vpd - Write entry to Vital Product Data
34  * @dev:        pci device struct
35  * @pos:        offset in vpd space
36  * @count:      number of bytes to write
37  * @buf:        buffer containing write data
38  */
39 ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void *buf)
40 {
41         if (!dev->vpd || !dev->vpd->ops)
42                 return -ENODEV;
43         return dev->vpd->ops->write(dev, pos, count, buf);
44 }
45 EXPORT_SYMBOL(pci_write_vpd);
46
47 /**
48  * pci_set_vpd_size - Set size of Vital Product Data space
49  * @dev:        pci device struct
50  * @len:        size of vpd space
51  */
52 int pci_set_vpd_size(struct pci_dev *dev, size_t len)
53 {
54         if (!dev->vpd || !dev->vpd->ops)
55                 return -ENODEV;
56         return dev->vpd->ops->set_size(dev, len);
57 }
58 EXPORT_SYMBOL(pci_set_vpd_size);
59
60 #define PCI_VPD_MAX_SIZE (PCI_VPD_ADDR_MASK + 1)
61
62 /**
63  * pci_vpd_size - determine actual size of Vital Product Data
64  * @dev:        pci device struct
65  * @old_size:   current assumed size, also maximum allowed size
66  */
67 static size_t pci_vpd_size(struct pci_dev *dev, size_t old_size)
68 {
69         size_t off = 0;
70         unsigned char header[1+2];      /* 1 byte tag, 2 bytes length */
71
72         while (off < old_size &&
73                pci_read_vpd(dev, off, 1, header) == 1) {
74                 unsigned char tag;
75
76                 if (header[0] & PCI_VPD_LRDT) {
77                         /* Large Resource Data Type Tag */
78                         tag = pci_vpd_lrdt_tag(header);
79                         /* Only read length from known tag items */
80                         if ((tag == PCI_VPD_LTIN_ID_STRING) ||
81                             (tag == PCI_VPD_LTIN_RO_DATA) ||
82                             (tag == PCI_VPD_LTIN_RW_DATA)) {
83                                 if (pci_read_vpd(dev, off+1, 2,
84                                                  &header[1]) != 2) {
85                                         pci_warn(dev, "invalid large VPD tag %02x size at offset %zu",
86                                                  tag, off + 1);
87                                         return 0;
88                                 }
89                                 off += PCI_VPD_LRDT_TAG_SIZE +
90                                         pci_vpd_lrdt_size(header);
91                         }
92                 } else {
93                         /* Short Resource Data Type Tag */
94                         off += PCI_VPD_SRDT_TAG_SIZE +
95                                 pci_vpd_srdt_size(header);
96                         tag = pci_vpd_srdt_tag(header);
97                 }
98
99                 if (tag == PCI_VPD_STIN_END)    /* End tag descriptor */
100                         return off;
101
102                 if ((tag != PCI_VPD_LTIN_ID_STRING) &&
103                     (tag != PCI_VPD_LTIN_RO_DATA) &&
104                     (tag != PCI_VPD_LTIN_RW_DATA)) {
105                         pci_warn(dev, "invalid %s VPD tag %02x at offset %zu",
106                                  (header[0] & PCI_VPD_LRDT) ? "large" : "short",
107                                  tag, off);
108                         return 0;
109                 }
110         }
111         return 0;
112 }
113
114 /*
115  * Wait for last operation to complete.
116  * This code has to spin since there is no other notification from the PCI
117  * hardware. Since the VPD is often implemented by serial attachment to an
118  * EEPROM, it may take many milliseconds to complete.
119  *
120  * Returns 0 on success, negative values indicate error.
121  */
122 static int pci_vpd_wait(struct pci_dev *dev)
123 {
124         struct pci_vpd *vpd = dev->vpd;
125         unsigned long timeout = jiffies + msecs_to_jiffies(125);
126         unsigned long max_sleep = 16;
127         u16 status;
128         int ret;
129
130         if (!vpd->busy)
131                 return 0;
132
133         while (time_before(jiffies, timeout)) {
134                 ret = pci_user_read_config_word(dev, vpd->cap + PCI_VPD_ADDR,
135                                                 &status);
136                 if (ret < 0)
137                         return ret;
138
139                 if ((status & PCI_VPD_ADDR_F) == vpd->flag) {
140                         vpd->busy = 0;
141                         return 0;
142                 }
143
144                 if (fatal_signal_pending(current))
145                         return -EINTR;
146
147                 usleep_range(10, max_sleep);
148                 if (max_sleep < 1024)
149                         max_sleep *= 2;
150         }
151
152         pci_warn(dev, "VPD access failed.  This is likely a firmware bug on this device.  Contact the card vendor for a firmware update\n");
153         return -ETIMEDOUT;
154 }
155
156 static ssize_t pci_vpd_read(struct pci_dev *dev, loff_t pos, size_t count,
157                             void *arg)
158 {
159         struct pci_vpd *vpd = dev->vpd;
160         int ret;
161         loff_t end = pos + count;
162         u8 *buf = arg;
163
164         if (pos < 0)
165                 return -EINVAL;
166
167         if (!vpd->valid) {
168                 vpd->valid = 1;
169                 vpd->len = pci_vpd_size(dev, vpd->len);
170         }
171
172         if (vpd->len == 0)
173                 return -EIO;
174
175         if (pos > vpd->len)
176                 return 0;
177
178         if (end > vpd->len) {
179                 end = vpd->len;
180                 count = end - pos;
181         }
182
183         if (mutex_lock_killable(&vpd->lock))
184                 return -EINTR;
185
186         ret = pci_vpd_wait(dev);
187         if (ret < 0)
188                 goto out;
189
190         while (pos < end) {
191                 u32 val;
192                 unsigned int i, skip;
193
194                 ret = pci_user_write_config_word(dev, vpd->cap + PCI_VPD_ADDR,
195                                                  pos & ~3);
196                 if (ret < 0)
197                         break;
198                 vpd->busy = 1;
199                 vpd->flag = PCI_VPD_ADDR_F;
200                 ret = pci_vpd_wait(dev);
201                 if (ret < 0)
202                         break;
203
204                 ret = pci_user_read_config_dword(dev, vpd->cap + PCI_VPD_DATA, &val);
205                 if (ret < 0)
206                         break;
207
208                 skip = pos & 3;
209                 for (i = 0;  i < sizeof(u32); i++) {
210                         if (i >= skip) {
211                                 *buf++ = val;
212                                 if (++pos == end)
213                                         break;
214                         }
215                         val >>= 8;
216                 }
217         }
218 out:
219         mutex_unlock(&vpd->lock);
220         return ret ? ret : count;
221 }
222
223 static ssize_t pci_vpd_write(struct pci_dev *dev, loff_t pos, size_t count,
224                              const void *arg)
225 {
226         struct pci_vpd *vpd = dev->vpd;
227         const u8 *buf = arg;
228         loff_t end = pos + count;
229         int ret = 0;
230
231         if (pos < 0 || (pos & 3) || (count & 3))
232                 return -EINVAL;
233
234         if (!vpd->valid) {
235                 vpd->valid = 1;
236                 vpd->len = pci_vpd_size(dev, vpd->len);
237         }
238
239         if (vpd->len == 0)
240                 return -EIO;
241
242         if (end > vpd->len)
243                 return -EINVAL;
244
245         if (mutex_lock_killable(&vpd->lock))
246                 return -EINTR;
247
248         ret = pci_vpd_wait(dev);
249         if (ret < 0)
250                 goto out;
251
252         while (pos < end) {
253                 u32 val;
254
255                 val = *buf++;
256                 val |= *buf++ << 8;
257                 val |= *buf++ << 16;
258                 val |= *buf++ << 24;
259
260                 ret = pci_user_write_config_dword(dev, vpd->cap + PCI_VPD_DATA, val);
261                 if (ret < 0)
262                         break;
263                 ret = pci_user_write_config_word(dev, vpd->cap + PCI_VPD_ADDR,
264                                                  pos | PCI_VPD_ADDR_F);
265                 if (ret < 0)
266                         break;
267
268                 vpd->busy = 1;
269                 vpd->flag = 0;
270                 ret = pci_vpd_wait(dev);
271                 if (ret < 0)
272                         break;
273
274                 pos += sizeof(u32);
275         }
276 out:
277         mutex_unlock(&vpd->lock);
278         return ret ? ret : count;
279 }
280
281 static int pci_vpd_set_size(struct pci_dev *dev, size_t len)
282 {
283         struct pci_vpd *vpd = dev->vpd;
284
285         if (len == 0 || len > PCI_VPD_MAX_SIZE)
286                 return -EIO;
287
288         vpd->valid = 1;
289         vpd->len = len;
290
291         return 0;
292 }
293
294 static const struct pci_vpd_ops pci_vpd_ops = {
295         .read = pci_vpd_read,
296         .write = pci_vpd_write,
297         .set_size = pci_vpd_set_size,
298 };
299
300 static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count,
301                                void *arg)
302 {
303         struct pci_dev *tdev = pci_get_slot(dev->bus,
304                                             PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
305         ssize_t ret;
306
307         if (!tdev)
308                 return -ENODEV;
309
310         ret = pci_read_vpd(tdev, pos, count, arg);
311         pci_dev_put(tdev);
312         return ret;
313 }
314
315 static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count,
316                                 const void *arg)
317 {
318         struct pci_dev *tdev = pci_get_slot(dev->bus,
319                                             PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
320         ssize_t ret;
321
322         if (!tdev)
323                 return -ENODEV;
324
325         ret = pci_write_vpd(tdev, pos, count, arg);
326         pci_dev_put(tdev);
327         return ret;
328 }
329
330 static int pci_vpd_f0_set_size(struct pci_dev *dev, size_t len)
331 {
332         struct pci_dev *tdev = pci_get_slot(dev->bus,
333                                             PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
334         int ret;
335
336         if (!tdev)
337                 return -ENODEV;
338
339         ret = pci_set_vpd_size(tdev, len);
340         pci_dev_put(tdev);
341         return ret;
342 }
343
344 static const struct pci_vpd_ops pci_vpd_f0_ops = {
345         .read = pci_vpd_f0_read,
346         .write = pci_vpd_f0_write,
347         .set_size = pci_vpd_f0_set_size,
348 };
349
350 int pci_vpd_init(struct pci_dev *dev)
351 {
352         struct pci_vpd *vpd;
353         u8 cap;
354
355         cap = pci_find_capability(dev, PCI_CAP_ID_VPD);
356         if (!cap)
357                 return -ENODEV;
358
359         vpd = kzalloc(sizeof(*vpd), GFP_ATOMIC);
360         if (!vpd)
361                 return -ENOMEM;
362
363         vpd->len = PCI_VPD_MAX_SIZE;
364         if (dev->dev_flags & PCI_DEV_FLAGS_VPD_REF_F0)
365                 vpd->ops = &pci_vpd_f0_ops;
366         else
367                 vpd->ops = &pci_vpd_ops;
368         mutex_init(&vpd->lock);
369         vpd->cap = cap;
370         vpd->busy = 0;
371         vpd->valid = 0;
372         dev->vpd = vpd;
373         return 0;
374 }
375
376 void pci_vpd_release(struct pci_dev *dev)
377 {
378         kfree(dev->vpd);
379 }
380
381 int pci_vpd_find_tag(const u8 *buf, unsigned int off, unsigned int len, u8 rdt)
382 {
383         int i;
384
385         for (i = off; i < len; ) {
386                 u8 val = buf[i];
387
388                 if (val & PCI_VPD_LRDT) {
389                         /* Don't return success of the tag isn't complete */
390                         if (i + PCI_VPD_LRDT_TAG_SIZE > len)
391                                 break;
392
393                         if (val == rdt)
394                                 return i;
395
396                         i += PCI_VPD_LRDT_TAG_SIZE +
397                              pci_vpd_lrdt_size(&buf[i]);
398                 } else {
399                         u8 tag = val & ~PCI_VPD_SRDT_LEN_MASK;
400
401                         if (tag == rdt)
402                                 return i;
403
404                         if (tag == PCI_VPD_SRDT_END)
405                                 break;
406
407                         i += PCI_VPD_SRDT_TAG_SIZE +
408                              pci_vpd_srdt_size(&buf[i]);
409                 }
410         }
411
412         return -ENOENT;
413 }
414 EXPORT_SYMBOL_GPL(pci_vpd_find_tag);
415
416 int pci_vpd_find_info_keyword(const u8 *buf, unsigned int off,
417                               unsigned int len, const char *kw)
418 {
419         int i;
420
421         for (i = off; i + PCI_VPD_INFO_FLD_HDR_SIZE <= off + len;) {
422                 if (buf[i + 0] == kw[0] &&
423                     buf[i + 1] == kw[1])
424                         return i;
425
426                 i += PCI_VPD_INFO_FLD_HDR_SIZE +
427                      pci_vpd_info_field_size(&buf[i]);
428         }
429
430         return -ENOENT;
431 }
432 EXPORT_SYMBOL_GPL(pci_vpd_find_info_keyword);