xref: /freebsd/sys/dev/nvme/nvme.c (revision 839f11a4fe18e4ae2dd930766b551fa67e354735)
1 /*-
2  * Copyright (C) 2012 Intel Corporation
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29 
30 #include <sys/param.h>
31 #include <sys/bus.h>
32 #include <sys/conf.h>
33 #include <sys/module.h>
34 
35 #include <vm/uma.h>
36 
37 #include <dev/pci/pcireg.h>
38 #include <dev/pci/pcivar.h>
39 
40 #include "nvme_private.h"
41 
42 struct nvme_consumer {
43 	nvme_consumer_cb_fn_t		cb_fn;
44 	void				*cb_arg;
45 };
46 
47 struct nvme_consumer nvme_consumer[NVME_MAX_CONSUMERS];
48 
49 uma_zone_t nvme_request_zone;
50 
51 MALLOC_DEFINE(M_NVME, "nvme", "nvme(4) memory allocations");
52 
53 static int    nvme_probe(device_t);
54 static int    nvme_attach(device_t);
55 static int    nvme_detach(device_t);
56 
57 static devclass_t nvme_devclass;
58 
59 static device_method_t nvme_pci_methods[] = {
60 	/* Device interface */
61 	DEVMETHOD(device_probe,     nvme_probe),
62 	DEVMETHOD(device_attach,    nvme_attach),
63 	DEVMETHOD(device_detach,    nvme_detach),
64 	{ 0, 0 }
65 };
66 
67 static driver_t nvme_pci_driver = {
68 	"nvme",
69 	nvme_pci_methods,
70 	sizeof(struct nvme_controller),
71 };
72 
73 DRIVER_MODULE(nvme, pci, nvme_pci_driver, nvme_devclass, 0, 0);
74 MODULE_VERSION(nvme, 1);
75 
76 static struct _pcsid
77 {
78 	u_int32_t   type;
79 	const char  *desc;
80 } pci_ids[] = {
81 	{ 0x01118086,		"NVMe Controller"  },
82 	{ CHATHAM_PCI_ID,	"Chatham Prototype NVMe Controller"  },
83 	{ IDT32_PCI_ID,		"IDT NVMe Controller (32 channel)"  },
84 	{ IDT8_PCI_ID,		"IDT NVMe Controller (8 channel)" },
85 	{ 0x00000000,		NULL  }
86 };
87 
88 static int
89 nvme_probe (device_t device)
90 {
91 	struct _pcsid	*ep;
92 	u_int32_t	type;
93 
94 	type = pci_get_devid(device);
95 	ep = pci_ids;
96 
97 	while (ep->type && ep->type != type)
98 		++ep;
99 
100 	if (ep->desc) {
101 		device_set_desc(device, ep->desc);
102 		return (BUS_PROBE_DEFAULT);
103 	}
104 
105 #if defined(PCIS_STORAGE_NVM)
106 	if (pci_get_class(device)    == PCIC_STORAGE &&
107 	    pci_get_subclass(device) == PCIS_STORAGE_NVM &&
108 	    pci_get_progif(device)   == PCIP_STORAGE_NVM_ENTERPRISE_NVMHCI_1_0) {
109 		device_set_desc(device, "Generic NVMe Device");
110 		return (BUS_PROBE_GENERIC);
111 	}
112 #endif
113 
114 	return (ENXIO);
115 }
116 
117 static void
118 nvme_init(void)
119 {
120 	nvme_request_zone = uma_zcreate("nvme_request",
121 	    sizeof(struct nvme_request), NULL, NULL, NULL, NULL, 0, 0);
122 }
123 
124 SYSINIT(nvme_register, SI_SUB_DRIVERS, SI_ORDER_SECOND, nvme_init, NULL);
125 
126 static void
127 nvme_uninit(void)
128 {
129 	uma_zdestroy(nvme_request_zone);
130 }
131 
132 SYSUNINIT(nvme_unregister, SI_SUB_DRIVERS, SI_ORDER_SECOND, nvme_uninit, NULL);
133 
134 static void
135 nvme_load(void)
136 {
137 }
138 
139 static void
140 nvme_unload(void)
141 {
142 }
143 
144 static void
145 nvme_shutdown(void)
146 {
147 	device_t		*devlist;
148 	struct nvme_controller	*ctrlr;
149 	union cc_register	cc;
150 	union csts_register	csts;
151 	int			dev, devcount;
152 
153 	if (devclass_get_devices(nvme_devclass, &devlist, &devcount))
154 		return;
155 
156 	for (dev = 0; dev < devcount; dev++) {
157 		/*
158 		 * Only notify controller of shutdown when a real shutdown is
159 		 *  in process, not when a module unload occurs.  It seems at
160 		 *  least some controllers (Chatham at least) don't let you
161 		 *  re-enable the controller after shutdown notification has
162 		 *  been received.
163 		 */
164 		ctrlr = DEVICE2SOFTC(devlist[dev]);
165 		cc.raw = nvme_mmio_read_4(ctrlr, cc);
166 		cc.bits.shn = NVME_SHN_NORMAL;
167 		nvme_mmio_write_4(ctrlr, cc, cc.raw);
168 		csts.raw = nvme_mmio_read_4(ctrlr, csts);
169 		while (csts.bits.shst != NVME_SHST_COMPLETE) {
170 			DELAY(5);
171 			csts.raw = nvme_mmio_read_4(ctrlr, csts);
172 		}
173 	}
174 
175 	free(devlist, M_TEMP);
176 }
177 
178 static int
179 nvme_modevent(module_t mod, int type, void *arg)
180 {
181 
182 	switch (type) {
183 	case MOD_LOAD:
184 		nvme_load();
185 		break;
186 	case MOD_UNLOAD:
187 		nvme_unload();
188 		break;
189 	case MOD_SHUTDOWN:
190 		nvme_shutdown();
191 		break;
192 	default:
193 		break;
194 	}
195 
196 	return (0);
197 }
198 
199 moduledata_t nvme_mod = {
200 	"nvme",
201 	(modeventhand_t)nvme_modevent,
202 	0
203 };
204 
205 DECLARE_MODULE(nvme, nvme_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
206 
207 void
208 nvme_dump_command(struct nvme_command *cmd)
209 {
210 	printf("opc:%x f:%x r1:%x cid:%x nsid:%x r2:%x r3:%x "
211 	    "mptr:%qx prp1:%qx prp2:%qx cdw:%x %x %x %x %x %x\n",
212 	    cmd->opc, cmd->fuse, cmd->rsvd1, cmd->cid, cmd->nsid,
213 	    cmd->rsvd2, cmd->rsvd3,
214 	    (long long unsigned int)cmd->mptr,
215 	    (long long unsigned int)cmd->prp1,
216 	    (long long unsigned int)cmd->prp2,
217 	    cmd->cdw10, cmd->cdw11, cmd->cdw12, cmd->cdw13, cmd->cdw14,
218 	    cmd->cdw15);
219 }
220 
221 void
222 nvme_dump_completion(struct nvme_completion *cpl)
223 {
224 	printf("cdw0:%08x sqhd:%04x sqid:%04x "
225 	    "cid:%04x p:%x sc:%02x sct:%x m:%x dnr:%x\n",
226 	    cpl->cdw0, cpl->sqhd, cpl->sqid,
227 	    cpl->cid, cpl->p, cpl->sf_sc, cpl->sf_sct, cpl->sf_m,
228 	    cpl->sf_dnr);
229 }
230 
231 void
232 nvme_payload_map(void *arg, bus_dma_segment_t *seg, int nseg, int error)
233 {
234 	struct nvme_tracker 	*tr = arg;
235 	uint32_t		cur_nseg;
236 
237 	KASSERT(error == 0, ("nvme_payload_map error != 0\n"));
238 
239 	/*
240 	 * Note that we specified PAGE_SIZE for alignment and max
241 	 *  segment size when creating the bus dma tags.  So here
242 	 *  we can safely just transfer each segment to its
243 	 *  associated PRP entry.
244 	 */
245 	tr->req->cmd.prp1 = seg[0].ds_addr;
246 
247 	if (nseg == 2) {
248 		tr->req->cmd.prp2 = seg[1].ds_addr;
249 	} else if (nseg > 2) {
250 		cur_nseg = 1;
251 		tr->req->cmd.prp2 = (uint64_t)tr->prp_bus_addr;
252 		while (cur_nseg < nseg) {
253 			tr->prp[cur_nseg-1] =
254 			    (uint64_t)seg[cur_nseg].ds_addr;
255 			cur_nseg++;
256 		}
257 	}
258 
259 	nvme_qpair_submit_cmd(tr->qpair, tr);
260 }
261 
262 static int
263 nvme_attach(device_t dev)
264 {
265 	struct nvme_controller	*ctrlr = DEVICE2SOFTC(dev);
266 	int			status;
267 
268 	status = nvme_ctrlr_construct(ctrlr, dev);
269 
270 	if (status != 0)
271 		return (status);
272 
273 	/*
274 	 * Reset controller twice to ensure we do a transition from cc.en==1
275 	 *  to cc.en==0.  This is because we don't really know what status
276 	 *  the controller was left in when boot handed off to OS.
277 	 */
278 	status = nvme_ctrlr_reset(ctrlr);
279 	if (status != 0)
280 		return (status);
281 
282 	status = nvme_ctrlr_reset(ctrlr);
283 	if (status != 0)
284 		return (status);
285 
286 	ctrlr->config_hook.ich_func = nvme_ctrlr_start;
287 	ctrlr->config_hook.ich_arg = ctrlr;
288 
289 	config_intrhook_establish(&ctrlr->config_hook);
290 
291 	return (0);
292 }
293 
294 static int
295 nvme_detach (device_t dev)
296 {
297 	struct nvme_controller	*ctrlr = DEVICE2SOFTC(dev);
298 	struct nvme_namespace	*ns;
299 	int			i;
300 
301 	if (ctrlr->taskqueue) {
302 		taskqueue_drain(ctrlr->taskqueue, &ctrlr->task);
303 		taskqueue_free(ctrlr->taskqueue);
304 	}
305 
306 	for (i = 0; i < NVME_MAX_NAMESPACES; i++) {
307 		ns = &ctrlr->ns[i];
308 		if (ns->cdev)
309 			destroy_dev(ns->cdev);
310 	}
311 
312 	if (ctrlr->cdev)
313 		destroy_dev(ctrlr->cdev);
314 
315 	for (i = 0; i < ctrlr->num_io_queues; i++) {
316 		nvme_io_qpair_destroy(&ctrlr->ioq[i]);
317 	}
318 
319 	free(ctrlr->ioq, M_NVME);
320 
321 	nvme_admin_qpair_destroy(&ctrlr->adminq);
322 
323 	if (ctrlr->resource != NULL) {
324 		bus_release_resource(dev, SYS_RES_MEMORY,
325 		    ctrlr->resource_id, ctrlr->resource);
326 	}
327 
328 #ifdef CHATHAM2
329 	if (ctrlr->chatham_resource != NULL) {
330 		bus_release_resource(dev, SYS_RES_MEMORY,
331 		    ctrlr->chatham_resource_id, ctrlr->chatham_resource);
332 	}
333 #endif
334 
335 	if (ctrlr->tag)
336 		bus_teardown_intr(ctrlr->dev, ctrlr->res, ctrlr->tag);
337 
338 	if (ctrlr->res)
339 		bus_release_resource(ctrlr->dev, SYS_RES_IRQ,
340 		    rman_get_rid(ctrlr->res), ctrlr->res);
341 
342 	if (ctrlr->msix_enabled)
343 		pci_release_msi(dev);
344 
345 	return (0);
346 }
347 
348 static void
349 nvme_notify_consumer(struct nvme_consumer *consumer)
350 {
351 	device_t		*devlist;
352 	struct nvme_controller	*ctrlr;
353 	int			dev, ns, devcount;
354 
355 	if (devclass_get_devices(nvme_devclass, &devlist, &devcount))
356 		return;
357 
358 	for (dev = 0; dev < devcount; dev++) {
359 		ctrlr = DEVICE2SOFTC(devlist[dev]);
360 		for (ns = 0; ns < ctrlr->cdata.nn; ns++)
361 			(*consumer->cb_fn)(consumer->cb_arg, &ctrlr->ns[ns]);
362 	}
363 
364 	free(devlist, M_TEMP);
365 }
366 
367 struct nvme_consumer *
368 nvme_register_consumer(nvme_consumer_cb_fn_t cb_fn, void *cb_arg)
369 {
370 	int i;
371 
372 	/*
373 	 * TODO: add locking around consumer registration.  Not an issue
374 	 *  right now since we only have one nvme consumer - nvd(4).
375 	 */
376 	for (i = 0; i < NVME_MAX_CONSUMERS; i++)
377 		if (nvme_consumer[i].cb_fn == NULL) {
378 			nvme_consumer[i].cb_fn = cb_fn;
379 			nvme_consumer[i].cb_arg = cb_arg;
380 
381 			nvme_notify_consumer(&nvme_consumer[i]);
382 			return (&nvme_consumer[i]);
383 		}
384 
385 	printf("nvme(4): consumer not registered - no slots available\n");
386 	return (NULL);
387 }
388 
389 void
390 nvme_unregister_consumer(struct nvme_consumer *consumer)
391 {
392 
393 	consumer->cb_fn = NULL;
394 	consumer->cb_arg = NULL;
395 }
396 
397