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: releng/9.2/sys/dev/nvme/nvme_ns_cmd.c 253630 2013-07-24 22:46:27Z jimharris $");
29
30 #include "nvme_private.h"
31
32 int
33 nvme_ns_cmd_read(struct nvme_namespace *ns, void *payload, uint64_t lba,
34 uint32_t lba_count, nvme_cb_fn_t cb_fn, void *cb_arg)
35 {
36 struct nvme_request *req;
37 struct nvme_command *cmd;
38
39 req = nvme_allocate_request_vaddr(payload,
40 lba_count*nvme_ns_get_sector_size(ns), cb_fn, cb_arg);
41
42 if (req == NULL)
43 return (ENOMEM);
44 cmd = &req->cmd;
45 cmd->opc = NVME_OPC_READ;
46 cmd->nsid = ns->id;
47
48 /* TODO: create a read command data structure */
49 *(uint64_t *)&cmd->cdw10 = lba;
50 cmd->cdw12 = lba_count-1;
51
52 nvme_ctrlr_submit_io_request(ns->ctrlr, req);
53
54 return (0);
55 }
56
57 int
58 nvme_ns_cmd_read_bio(struct nvme_namespace *ns, struct bio *bp,
59 nvme_cb_fn_t cb_fn, void *cb_arg)
60 {
61 struct nvme_request *req;
62 struct nvme_command *cmd;
63 uint64_t lba;
64 uint64_t lba_count;
65
66 req = nvme_allocate_request_bio(bp, cb_fn, cb_arg);
67
68 if (req == NULL)
69 return (ENOMEM);
70 cmd = &req->cmd;
71 cmd->opc = NVME_OPC_READ;
72 cmd->nsid = ns->id;
73
74 lba = bp->bio_offset / nvme_ns_get_sector_size(ns);
75 lba_count = bp->bio_bcount / nvme_ns_get_sector_size(ns);
76
77 /* TODO: create a read command data structure */
78 *(uint64_t *)&cmd->cdw10 = lba;
79 cmd->cdw12 = lba_count-1;
80
81 nvme_ctrlr_submit_io_request(ns->ctrlr, req);
82
83 return (0);
84 }
85
86 int
87 nvme_ns_cmd_write(struct nvme_namespace *ns, void *payload, uint64_t lba,
88 uint32_t lba_count, nvme_cb_fn_t cb_fn, void *cb_arg)
89 {
90 struct nvme_request *req;
91 struct nvme_command *cmd;
92
93 req = nvme_allocate_request_vaddr(payload,
94 lba_count*nvme_ns_get_sector_size(ns), cb_fn, cb_arg);
95
96 if (req == NULL)
97 return (ENOMEM);
98
99 cmd = &req->cmd;
100 cmd->opc = NVME_OPC_WRITE;
101 cmd->nsid = ns->id;
102
103 /* TODO: create a write command data structure */
104 *(uint64_t *)&cmd->cdw10 = lba;
105 cmd->cdw12 = lba_count-1;
106
107 nvme_ctrlr_submit_io_request(ns->ctrlr, req);
108
109 return (0);
110 }
111
112 int
113 nvme_ns_cmd_write_bio(struct nvme_namespace *ns, struct bio *bp,
114 nvme_cb_fn_t cb_fn, void *cb_arg)
115 {
116 struct nvme_request *req;
117 struct nvme_command *cmd;
118 uint64_t lba;
119 uint64_t lba_count;
120
121 req = nvme_allocate_request_bio(bp, cb_fn, cb_arg);
122
123 if (req == NULL)
124 return (ENOMEM);
125 cmd = &req->cmd;
126 cmd->opc = NVME_OPC_WRITE;
127 cmd->nsid = ns->id;
128
129 lba = bp->bio_offset / nvme_ns_get_sector_size(ns);
130 lba_count = bp->bio_bcount / nvme_ns_get_sector_size(ns);
131
132 /* TODO: create a write command data structure */
133 *(uint64_t *)&cmd->cdw10 = lba;
134 cmd->cdw12 = lba_count-1;
135
136 nvme_ctrlr_submit_io_request(ns->ctrlr, req);
137
138 return (0);
139 }
140
141 int
142 nvme_ns_cmd_deallocate(struct nvme_namespace *ns, void *payload,
143 uint8_t num_ranges, nvme_cb_fn_t cb_fn, void *cb_arg)
144 {
145 struct nvme_request *req;
146 struct nvme_command *cmd;
147
148 req = nvme_allocate_request_vaddr(payload,
149 num_ranges * sizeof(struct nvme_dsm_range), cb_fn, cb_arg);
150
151 if (req == NULL)
152 return (ENOMEM);
153
154 cmd = &req->cmd;
155 cmd->opc = NVME_OPC_DATASET_MANAGEMENT;
156 cmd->nsid = ns->id;
157
158 /* TODO: create a delete command data structure */
159 cmd->cdw10 = num_ranges - 1;
160 cmd->cdw11 = NVME_DSM_ATTR_DEALLOCATE;
161
162 nvme_ctrlr_submit_io_request(ns->ctrlr, req);
163
164 return (0);
165 }
166
167 int
168 nvme_ns_cmd_flush(struct nvme_namespace *ns, nvme_cb_fn_t cb_fn, void *cb_arg)
169 {
170 struct nvme_request *req;
171 struct nvme_command *cmd;
172
173 req = nvme_allocate_request_null(cb_fn, cb_arg);
174
175 if (req == NULL)
176 return (ENOMEM);
177
178 cmd = &req->cmd;
179 cmd->opc = NVME_OPC_FLUSH;
180 cmd->nsid = ns->id;
181
182 nvme_ctrlr_submit_io_request(ns->ctrlr, req);
183
184 return (0);
185 }
Cache object: 81ee7cdd7167666173e360f1f8c4b40e
|