]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /*- |
2 | * BSD LICENSE | |
3 | * | |
4 | * Copyright (c) Intel Corporation. | |
5 | * All rights reserved. | |
6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | |
10 | * | |
11 | * * Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | |
13 | * * Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in | |
15 | * the documentation and/or other materials provided with the | |
16 | * distribution. | |
17 | * * Neither the name of Intel Corporation nor the names of its | |
18 | * contributors may be used to endorse or promote products derived | |
19 | * from this software without specific prior written permission. | |
20 | * | |
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
24 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
25 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
27 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
32 | */ | |
33 | ||
34 | #include "nvme_internal.h" | |
35 | ||
36 | struct nvme_quirk { | |
37 | struct spdk_pci_id id; | |
38 | uint64_t flags; | |
39 | }; | |
40 | ||
41 | static const struct nvme_quirk nvme_quirks[] = { | |
42 | { {SPDK_PCI_VID_INTEL, 0x0953, SPDK_PCI_ANY_ID, SPDK_PCI_ANY_ID}, | |
43 | NVME_INTEL_QUIRK_READ_LATENCY | | |
44 | NVME_INTEL_QUIRK_WRITE_LATENCY | | |
45 | NVME_INTEL_QUIRK_STRIPING | | |
11fdf7f2 | 46 | NVME_QUIRK_READ_ZERO_AFTER_DEALLOCATE |
7c673cae FG |
47 | }, |
48 | { {SPDK_PCI_VID_INTEL, 0x0A53, SPDK_PCI_ANY_ID, SPDK_PCI_ANY_ID}, | |
11fdf7f2 TL |
49 | NVME_INTEL_QUIRK_READ_LATENCY | |
50 | NVME_INTEL_QUIRK_WRITE_LATENCY | | |
51 | NVME_INTEL_QUIRK_STRIPING | | |
52 | NVME_QUIRK_READ_ZERO_AFTER_DEALLOCATE | |
7c673cae FG |
53 | }, |
54 | { {SPDK_PCI_VID_INTEL, 0x0A54, SPDK_PCI_ANY_ID, SPDK_PCI_ANY_ID}, | |
11fdf7f2 TL |
55 | NVME_INTEL_QUIRK_READ_LATENCY | |
56 | NVME_INTEL_QUIRK_WRITE_LATENCY | | |
57 | NVME_INTEL_QUIRK_STRIPING | | |
58 | NVME_QUIRK_READ_ZERO_AFTER_DEALLOCATE | |
59 | }, | |
60 | { {SPDK_PCI_VID_INTEL, 0x0A55, SPDK_PCI_ANY_ID, SPDK_PCI_ANY_ID}, | |
61 | NVME_INTEL_QUIRK_READ_LATENCY | | |
62 | NVME_INTEL_QUIRK_WRITE_LATENCY | | |
63 | NVME_INTEL_QUIRK_STRIPING | | |
64 | NVME_QUIRK_READ_ZERO_AFTER_DEALLOCATE | |
7c673cae FG |
65 | }, |
66 | { {SPDK_PCI_VID_MEMBLAZE, 0x0540, SPDK_PCI_ANY_ID, SPDK_PCI_ANY_ID}, | |
67 | NVME_QUIRK_DELAY_BEFORE_CHK_RDY | |
68 | }, | |
11fdf7f2 TL |
69 | { {SPDK_PCI_VID_SAMSUNG, 0xa821, SPDK_PCI_ANY_ID, SPDK_PCI_ANY_ID}, |
70 | NVME_QUIRK_DELAY_BEFORE_CHK_RDY | |
71 | }, | |
72 | { {SPDK_PCI_VID_SAMSUNG, 0xa822, SPDK_PCI_ANY_ID, SPDK_PCI_ANY_ID}, | |
73 | NVME_QUIRK_DELAY_BEFORE_CHK_RDY | |
74 | }, | |
75 | { {SPDK_PCI_VID_VIRTUALBOX, 0x4e56, SPDK_PCI_ANY_ID, SPDK_PCI_ANY_ID}, | |
76 | NVME_QUIRK_DELAY_AFTER_QUEUE_ALLOC | |
77 | }, | |
78 | { {SPDK_PCI_VID_INTEL, 0x5845, SPDK_PCI_ANY_ID, SPDK_PCI_ANY_ID}, | |
79 | NVME_QUIRK_IDENTIFY_CNS | | |
80 | NVME_INTEL_QUIRK_NO_LOG_PAGES | |
81 | }, | |
82 | { {SPDK_PCI_VID_CNEXLABS, 0x1f1f, SPDK_PCI_ANY_ID, SPDK_PCI_ANY_ID}, | |
83 | NVME_QUIRK_IDENTIFY_CNS | | |
84 | NVME_QUIRK_OCSSD | |
85 | }, | |
9f95a23c TL |
86 | { {SPDK_PCI_VID_VMWARE, 0x07f0, SPDK_PCI_ANY_ID, SPDK_PCI_ANY_ID}, |
87 | NVME_QUIRK_SHST_COMPLETE | |
88 | }, | |
7c673cae FG |
89 | { {0x0000, 0x0000, 0x0000, 0x0000}, 0} |
90 | }; | |
91 | ||
92 | /* Compare each field. SPDK_PCI_ANY_ID in s1 matches everything */ | |
93 | static bool | |
94 | pci_id_match(const struct spdk_pci_id *s1, const struct spdk_pci_id *s2) | |
95 | { | |
96 | if ((s1->vendor_id == SPDK_PCI_ANY_ID || s1->vendor_id == s2->vendor_id) && | |
97 | (s1->device_id == SPDK_PCI_ANY_ID || s1->device_id == s2->device_id) && | |
98 | (s1->subvendor_id == SPDK_PCI_ANY_ID || s1->subvendor_id == s2->subvendor_id) && | |
99 | (s1->subdevice_id == SPDK_PCI_ANY_ID || s1->subdevice_id == s2->subdevice_id)) { | |
100 | return true; | |
101 | } | |
102 | return false; | |
103 | } | |
104 | ||
105 | uint64_t | |
106 | nvme_get_quirks(const struct spdk_pci_id *id) | |
107 | { | |
108 | const struct nvme_quirk *quirk = nvme_quirks; | |
109 | ||
11fdf7f2 TL |
110 | SPDK_DEBUGLOG(SPDK_LOG_NVME, "Searching for %04x:%04x [%04x:%04x]...\n", |
111 | id->vendor_id, id->device_id, | |
112 | id->subvendor_id, id->subdevice_id); | |
113 | ||
7c673cae FG |
114 | while (quirk->id.vendor_id) { |
115 | if (pci_id_match(&quirk->id, id)) { | |
11fdf7f2 TL |
116 | SPDK_DEBUGLOG(SPDK_LOG_NVME, "Matched quirk %04x:%04x [%04x:%04x]:\n", |
117 | quirk->id.vendor_id, quirk->id.device_id, | |
118 | quirk->id.subvendor_id, quirk->id.subdevice_id); | |
119 | ||
120 | #define PRINT_QUIRK(quirk_flag) \ | |
121 | do { \ | |
122 | if (quirk->flags & (quirk_flag)) { \ | |
123 | SPDK_DEBUGLOG(SPDK_LOG_NVME, "Quirk enabled: %s\n", #quirk_flag); \ | |
124 | } \ | |
125 | } while (0) | |
126 | ||
127 | PRINT_QUIRK(NVME_INTEL_QUIRK_READ_LATENCY); | |
128 | PRINT_QUIRK(NVME_INTEL_QUIRK_WRITE_LATENCY); | |
129 | PRINT_QUIRK(NVME_QUIRK_DELAY_BEFORE_CHK_RDY); | |
130 | PRINT_QUIRK(NVME_INTEL_QUIRK_STRIPING); | |
131 | PRINT_QUIRK(NVME_QUIRK_DELAY_AFTER_QUEUE_ALLOC); | |
132 | PRINT_QUIRK(NVME_QUIRK_READ_ZERO_AFTER_DEALLOCATE); | |
133 | PRINT_QUIRK(NVME_QUIRK_IDENTIFY_CNS); | |
134 | PRINT_QUIRK(NVME_QUIRK_OCSSD); | |
135 | ||
7c673cae FG |
136 | return quirk->flags; |
137 | } | |
138 | quirk++; | |
139 | } | |
11fdf7f2 TL |
140 | |
141 | SPDK_DEBUGLOG(SPDK_LOG_NVME, "No quirks found.\n"); | |
142 | ||
143 | return 0; | |
7c673cae | 144 | } |