| @@ -1,34 +1,34 @@ | | | @@ -1,34 +1,34 @@ |
1 | /* $NetBSD: nvme.c,v 1.44.2.4 2020/09/27 10:30:16 martin Exp $ */ | | 1 | /* $NetBSD: nvme.c,v 1.44.2.5 2020/12/07 20:04:07 martin 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.44.2.4 2020/09/27 10:30:16 martin Exp $"); | | 21 | __KERNEL_RCSID(0, "$NetBSD: nvme.c,v 1.44.2.5 2020/12/07 20:04:07 martin 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> |
| @@ -618,26 +618,32 @@ nvme_childdet(device_t self, device_t ch | | | @@ -618,26 +618,32 @@ nvme_childdet(device_t self, device_t ch |
618 | | | 618 | |
619 | int | | 619 | int |
620 | nvme_ns_identify(struct nvme_softc *sc, uint16_t nsid) | | 620 | nvme_ns_identify(struct nvme_softc *sc, uint16_t nsid) |
621 | { | | 621 | { |
622 | struct nvme_sqe sqe; | | 622 | struct nvme_sqe sqe; |
623 | struct nvm_identify_namespace *identify; | | 623 | struct nvm_identify_namespace *identify; |
624 | struct nvme_dmamem *mem; | | 624 | struct nvme_dmamem *mem; |
625 | struct nvme_ccb *ccb; | | 625 | struct nvme_ccb *ccb; |
626 | struct nvme_namespace *ns; | | 626 | struct nvme_namespace *ns; |
627 | int rv; | | 627 | int rv; |
628 | | | 628 | |
629 | KASSERT(nsid > 0); | | 629 | KASSERT(nsid > 0); |
630 | | | 630 | |
| | | 631 | ns = nvme_ns_get(sc, nsid); |
| | | 632 | KASSERT(ns); |
| | | 633 | |
| | | 634 | if (ns->ident != NULL) |
| | | 635 | return 0; |
| | | 636 | |
631 | ccb = nvme_ccb_get(sc->sc_admin_q, false); | | 637 | ccb = nvme_ccb_get(sc->sc_admin_q, false); |
632 | KASSERT(ccb != NULL); /* it's a bug if we don't have spare ccb here */ | | 638 | KASSERT(ccb != NULL); /* it's a bug if we don't have spare ccb here */ |
633 | | | 639 | |
634 | mem = nvme_dmamem_alloc(sc, sizeof(*identify)); | | 640 | mem = nvme_dmamem_alloc(sc, sizeof(*identify)); |
635 | if (mem == NULL) { | | 641 | if (mem == NULL) { |
636 | nvme_ccb_put(sc->sc_admin_q, ccb); | | 642 | nvme_ccb_put(sc->sc_admin_q, ccb); |
637 | return ENOMEM; | | 643 | return ENOMEM; |
638 | } | | 644 | } |
639 | | | 645 | |
640 | memset(&sqe, 0, sizeof(sqe)); | | 646 | memset(&sqe, 0, sizeof(sqe)); |
641 | sqe.opcode = NVM_ADMIN_IDENTIFY; | | 647 | sqe.opcode = NVM_ADMIN_IDENTIFY; |
642 | htolem32(&sqe.nsid, nsid); | | 648 | htolem32(&sqe.nsid, nsid); |
643 | htolem64(&sqe.entry.prp[0], NVME_DMA_DVA(mem)); | | 649 | htolem64(&sqe.entry.prp[0], NVME_DMA_DVA(mem)); |
| @@ -655,29 +661,26 @@ nvme_ns_identify(struct nvme_softc *sc, | | | @@ -655,29 +661,26 @@ nvme_ns_identify(struct nvme_softc *sc, |
655 | if (rv != 0) { | | 661 | if (rv != 0) { |
656 | rv = EIO; | | 662 | rv = EIO; |
657 | goto done; | | 663 | goto done; |
658 | } | | 664 | } |
659 | | | 665 | |
660 | /* commit */ | | 666 | /* commit */ |
661 | | | 667 | |
662 | identify = kmem_zalloc(sizeof(*identify), KM_SLEEP); | | 668 | identify = kmem_zalloc(sizeof(*identify), KM_SLEEP); |
663 | *identify = *((volatile struct nvm_identify_namespace *)NVME_DMA_KVA(mem)); | | 669 | *identify = *((volatile struct nvm_identify_namespace *)NVME_DMA_KVA(mem)); |
664 | | | 670 | |
665 | /* Convert data to host endian */ | | 671 | /* Convert data to host endian */ |
666 | nvme_identify_namespace_swapbytes(identify); | | 672 | nvme_identify_namespace_swapbytes(identify); |
667 | | | 673 | |
668 | ns = nvme_ns_get(sc, nsid); | | | |
669 | KASSERT(ns); | | | |
670 | KASSERT(ns->ident == NULL); | | | |
671 | ns->ident = identify; | | 674 | ns->ident = identify; |
672 | | | 675 | |
673 | done: | | 676 | done: |
674 | nvme_dmamem_free(sc, mem); | | 677 | nvme_dmamem_free(sc, mem); |
675 | | | 678 | |
676 | return rv; | | 679 | return rv; |
677 | } | | 680 | } |
678 | | | 681 | |
679 | int | | 682 | int |
680 | nvme_ns_dobio(struct nvme_softc *sc, uint16_t nsid, void *cookie, | | 683 | nvme_ns_dobio(struct nvme_softc *sc, uint16_t nsid, void *cookie, |
681 | struct buf *bp, void *data, size_t datasize, | | 684 | struct buf *bp, void *data, size_t datasize, |
682 | int secsize, daddr_t blkno, int flags, nvme_nnc_done nnc_done) | | 685 | int secsize, daddr_t blkno, int flags, nvme_nnc_done nnc_done) |
683 | { | | 686 | { |