| @@ -1,34 +1,34 @@ | | | @@ -1,34 +1,34 @@ |
1 | /* $NetBSD: nvme.c,v 1.27 2017/05/29 02:20:34 nonaka Exp $ */ | | 1 | /* $NetBSD: nvme.c,v 1.28 2017/05/29 02:24:00 nonaka Exp $ */ |
2 | /* $OpenBSD: nvme.c,v 1.49 2016/04/18 05:59:50 dlg Exp $ */ | | 2 | /* $OpenBSD: nvme.c,v 1.49 2016/04/18 05:59:50 dlg Exp $ */ |
3 | | | 3 | |
4 | /* | | 4 | /* |
5 | * Copyright (c) 2014 David Gwynne <dlg@openbsd.org> | | 5 | * Copyright (c) 2014 David Gwynne <dlg@openbsd.org> |
6 | * | | 6 | * |
7 | * Permission to use, copy, modify, and distribute this software for any | | 7 | * Permission to use, copy, modify, and distribute this software for any |
8 | * purpose with or without fee is hereby granted, provided that the above | | 8 | * purpose with or without fee is hereby granted, provided that the above |
9 | * copyright notice and this permission notice appear in all copies. | | 9 | * copyright notice and this permission notice appear in all copies. |
10 | * | | 10 | * |
11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | | 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | | 12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | | 13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | | 14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | | 15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | | 16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | | 17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
18 | */ | | 18 | */ |
19 | | | 19 | |
20 | #include <sys/cdefs.h> | | 20 | #include <sys/cdefs.h> |
21 | __KERNEL_RCSID(0, "$NetBSD: nvme.c,v 1.27 2017/05/29 02:20:34 nonaka Exp $"); | | 21 | __KERNEL_RCSID(0, "$NetBSD: nvme.c,v 1.28 2017/05/29 02:24:00 nonaka Exp $"); |
22 | | | 22 | |
23 | #include <sys/param.h> | | 23 | #include <sys/param.h> |
24 | #include <sys/systm.h> | | 24 | #include <sys/systm.h> |
25 | #include <sys/kernel.h> | | 25 | #include <sys/kernel.h> |
26 | #include <sys/atomic.h> | | 26 | #include <sys/atomic.h> |
27 | #include <sys/bus.h> | | 27 | #include <sys/bus.h> |
28 | #include <sys/buf.h> | | 28 | #include <sys/buf.h> |
29 | #include <sys/conf.h> | | 29 | #include <sys/conf.h> |
30 | #include <sys/device.h> | | 30 | #include <sys/device.h> |
31 | #include <sys/kmem.h> | | 31 | #include <sys/kmem.h> |
32 | #include <sys/once.h> | | 32 | #include <sys/once.h> |
33 | #include <sys/proc.h> | | 33 | #include <sys/proc.h> |
34 | #include <sys/queue.h> | | 34 | #include <sys/queue.h> |
| @@ -111,32 +111,30 @@ static int nvme_command_passthrough(stru | | | @@ -111,32 +111,30 @@ static int nvme_command_passthrough(stru |
111 | struct nvme_pt_command *, uint16_t, struct lwp *, bool); | | 111 | struct nvme_pt_command *, uint16_t, struct lwp *, bool); |
112 | | | 112 | |
113 | static int nvme_get_number_of_queues(struct nvme_softc *, u_int *); | | 113 | static int nvme_get_number_of_queues(struct nvme_softc *, u_int *); |
114 | | | 114 | |
115 | #define NVME_TIMO_QOP 5 /* queue create and delete timeout */ | | 115 | #define NVME_TIMO_QOP 5 /* queue create and delete timeout */ |
116 | #define NVME_TIMO_IDENT 10 /* probe identify timeout */ | | 116 | #define NVME_TIMO_IDENT 10 /* probe identify timeout */ |
117 | #define NVME_TIMO_PT -1 /* passthrough cmd timeout */ | | 117 | #define NVME_TIMO_PT -1 /* passthrough cmd timeout */ |
118 | #define NVME_TIMO_SY 60 /* sync cache timeout */ | | 118 | #define NVME_TIMO_SY 60 /* sync cache timeout */ |
119 | | | 119 | |
120 | #define nvme_read4(_s, _r) \ | | 120 | #define nvme_read4(_s, _r) \ |
121 | bus_space_read_4((_s)->sc_iot, (_s)->sc_ioh, (_r)) | | 121 | bus_space_read_4((_s)->sc_iot, (_s)->sc_ioh, (_r)) |
122 | #define nvme_write4(_s, _r, _v) \ | | 122 | #define nvme_write4(_s, _r, _v) \ |
123 | bus_space_write_4((_s)->sc_iot, (_s)->sc_ioh, (_r), (_v)) | | 123 | bus_space_write_4((_s)->sc_iot, (_s)->sc_ioh, (_r), (_v)) |
124 | #ifdef __LP64__ | | 124 | /* |
125 | #define nvme_read8(_s, _r) \ | | 125 | * Some controllers, at least Apple NVMe, always require split |
126 | bus_space_read_8((_s)->sc_iot, (_s)->sc_ioh, (_r)) | | 126 | * transfers, so don't use bus_space_{read,write}_8() on LP64. |
127 | #define nvme_write8(_s, _r, _v) \ | | 127 | */ |
128 | bus_space_write_8((_s)->sc_iot, (_s)->sc_ioh, (_r), (_v)) | | | |
129 | #else /* __LP64__ */ | | | |
130 | static inline uint64_t | | 128 | static inline uint64_t |
131 | nvme_read8(struct nvme_softc *sc, bus_size_t r) | | 129 | nvme_read8(struct nvme_softc *sc, bus_size_t r) |
132 | { | | 130 | { |
133 | uint64_t v; | | 131 | uint64_t v; |
134 | uint32_t *a = (uint32_t *)&v; | | 132 | uint32_t *a = (uint32_t *)&v; |
135 | | | 133 | |
136 | #if _BYTE_ORDER == _LITTLE_ENDIAN | | 134 | #if _BYTE_ORDER == _LITTLE_ENDIAN |
137 | a[0] = nvme_read4(sc, r); | | 135 | a[0] = nvme_read4(sc, r); |
138 | a[1] = nvme_read4(sc, r + 4); | | 136 | a[1] = nvme_read4(sc, r + 4); |
139 | #else /* _BYTE_ORDER == _LITTLE_ENDIAN */ | | 137 | #else /* _BYTE_ORDER == _LITTLE_ENDIAN */ |
140 | a[1] = nvme_read4(sc, r); | | 138 | a[1] = nvme_read4(sc, r); |
141 | a[0] = nvme_read4(sc, r + 4); | | 139 | a[0] = nvme_read4(sc, r + 4); |
142 | #endif | | 140 | #endif |
| @@ -147,27 +145,26 @@ nvme_read8(struct nvme_softc *sc, bus_si | | | @@ -147,27 +145,26 @@ nvme_read8(struct nvme_softc *sc, bus_si |
147 | static inline void | | 145 | static inline void |
148 | nvme_write8(struct nvme_softc *sc, bus_size_t r, uint64_t v) | | 146 | nvme_write8(struct nvme_softc *sc, bus_size_t r, uint64_t v) |
149 | { | | 147 | { |
150 | uint32_t *a = (uint32_t *)&v; | | 148 | uint32_t *a = (uint32_t *)&v; |
151 | | | 149 | |
152 | #if _BYTE_ORDER == _LITTLE_ENDIAN | | 150 | #if _BYTE_ORDER == _LITTLE_ENDIAN |
153 | nvme_write4(sc, r, a[0]); | | 151 | nvme_write4(sc, r, a[0]); |
154 | nvme_write4(sc, r + 4, a[1]); | | 152 | nvme_write4(sc, r + 4, a[1]); |
155 | #else /* _BYTE_ORDER == _LITTLE_ENDIAN */ | | 153 | #else /* _BYTE_ORDER == _LITTLE_ENDIAN */ |
156 | nvme_write4(sc, r, a[1]); | | 154 | nvme_write4(sc, r, a[1]); |
157 | nvme_write4(sc, r + 4, a[0]); | | 155 | nvme_write4(sc, r + 4, a[0]); |
158 | #endif | | 156 | #endif |
159 | } | | 157 | } |
160 | #endif /* __LP64__ */ | | | |
161 | #define nvme_barrier(_s, _r, _l, _f) \ | | 158 | #define nvme_barrier(_s, _r, _l, _f) \ |
162 | bus_space_barrier((_s)->sc_iot, (_s)->sc_ioh, (_r), (_l), (_f)) | | 159 | bus_space_barrier((_s)->sc_iot, (_s)->sc_ioh, (_r), (_l), (_f)) |
163 | | | 160 | |
164 | #ifdef NVME_DEBUG | | 161 | #ifdef NVME_DEBUG |
165 | static __used void | | 162 | static __used void |
166 | nvme_dumpregs(struct nvme_softc *sc) | | 163 | nvme_dumpregs(struct nvme_softc *sc) |
167 | { | | 164 | { |
168 | uint64_t r8; | | 165 | uint64_t r8; |
169 | uint32_t r4; | | 166 | uint32_t r4; |
170 | | | 167 | |
171 | #define DEVNAME(_sc) device_xname((_sc)->sc_dev) | | 168 | #define DEVNAME(_sc) device_xname((_sc)->sc_dev) |
172 | r8 = nvme_read8(sc, NVME_CAP); | | 169 | r8 = nvme_read8(sc, NVME_CAP); |
173 | printf("%s: cap 0x%016"PRIx64"\n", DEVNAME(sc), nvme_read8(sc, NVME_CAP)); | | 170 | printf("%s: cap 0x%016"PRIx64"\n", DEVNAME(sc), nvme_read8(sc, NVME_CAP)); |