Sat Apr 18 16:58:00 2020 UTC ()
make compile with XBD_DEBUG


(jdolecek)
diff -r1.118 -r1.119 src/sys/arch/xen/xen/xbd_xenbus.c

cvs diff -r1.118 -r1.119 src/sys/arch/xen/xen/xbd_xenbus.c (switch to unified diff)

--- src/sys/arch/xen/xen/xbd_xenbus.c 2020/04/17 10:35:06 1.118
+++ src/sys/arch/xen/xen/xbd_xenbus.c 2020/04/18 16:58:00 1.119
@@ -1,1376 +1,1370 @@ @@ -1,1376 +1,1370 @@
1/* $NetBSD: xbd_xenbus.c,v 1.118 2020/04/17 10:35:06 jdolecek Exp $ */ 1/* $NetBSD: xbd_xenbus.c,v 1.119 2020/04/18 16:58:00 jdolecek Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2006 Manuel Bouyer. 4 * Copyright (c) 2006 Manuel Bouyer.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 * 25 *
26 */ 26 */
27 27
28/* 28/*
29 * The file contains the xbd frontend code required for block-level 29 * The file contains the xbd frontend code required for block-level
30 * communications (similar to hard disks) between two Xen domains. 30 * communications (similar to hard disks) between two Xen domains.
31 * 31 *
32 * We are not supposed to receive solicitations spontaneously from backend. The 32 * We are not supposed to receive solicitations spontaneously from backend. The
33 * protocol is therefore fairly simple and uses only one ring to communicate 33 * protocol is therefore fairly simple and uses only one ring to communicate
34 * with backend: frontend posts requests to the ring then wait for their 34 * with backend: frontend posts requests to the ring then wait for their
35 * replies asynchronously. 35 * replies asynchronously.
36 * 36 *
37 * xbd follows NetBSD's disk(9) convention. At any time, a LWP can schedule 37 * xbd follows NetBSD's disk(9) convention. At any time, a LWP can schedule
38 * an operation request for the device (be it open(), read(), write(), ...). 38 * an operation request for the device (be it open(), read(), write(), ...).
39 * Calls are typically processed that way: 39 * Calls are typically processed that way:
40 * - initiate request: xbdread/write/open/ioctl/.. 40 * - initiate request: xbdread/write/open/ioctl/..
41 * - depending on operation, it is handled directly by disk(9) subsystem or 41 * - depending on operation, it is handled directly by disk(9) subsystem or
42 * goes through physio(9) first. 42 * goes through physio(9) first.
43 * - the request is ultimately processed by xbd_diskstart() that prepares the 43 * - the request is ultimately processed by xbd_diskstart() that prepares the
44 * xbd requests, post them in the ring I/O queue, then signal the backend. 44 * xbd requests, post them in the ring I/O queue, then signal the backend.
45 * 45 *
46 * When a response is available in the queue, the backend signals the frontend 46 * When a response is available in the queue, the backend signals the frontend
47 * via its event channel. This triggers xbd_handler(), which will link back 47 * via its event channel. This triggers xbd_handler(), which will link back
48 * the response to its request through the request ID, and mark the I/O as 48 * the response to its request through the request ID, and mark the I/O as
49 * completed. 49 * completed.
50 */ 50 */
51 51
52#include <sys/cdefs.h> 52#include <sys/cdefs.h>
53__KERNEL_RCSID(0, "$NetBSD: xbd_xenbus.c,v 1.118 2020/04/17 10:35:06 jdolecek Exp $"); 53__KERNEL_RCSID(0, "$NetBSD: xbd_xenbus.c,v 1.119 2020/04/18 16:58:00 jdolecek Exp $");
54 54
55#include "opt_xen.h" 55#include "opt_xen.h"
56 56
57 57
58#include <sys/param.h> 58#include <sys/param.h>
59#include <sys/buf.h> 59#include <sys/buf.h>
60#include <sys/bufq.h> 60#include <sys/bufq.h>
61#include <sys/device.h> 61#include <sys/device.h>
62#include <sys/disk.h> 62#include <sys/disk.h>
63#include <sys/disklabel.h> 63#include <sys/disklabel.h>
64#include <sys/conf.h> 64#include <sys/conf.h>
65#include <sys/fcntl.h> 65#include <sys/fcntl.h>
66#include <sys/kernel.h> 66#include <sys/kernel.h>
67#include <sys/proc.h> 67#include <sys/proc.h>
68#include <sys/systm.h> 68#include <sys/systm.h>
69#include <sys/stat.h> 69#include <sys/stat.h>
70#include <sys/vnode.h> 70#include <sys/vnode.h>
71#include <sys/mutex.h> 71#include <sys/mutex.h>
72 72
73#include <dev/dkvar.h> 73#include <dev/dkvar.h>
74 74
75#include <uvm/uvm.h> 75#include <uvm/uvm.h>
76 76
77#include <xen/hypervisor.h> 77#include <xen/hypervisor.h>
78#include <xen/evtchn.h> 78#include <xen/evtchn.h>
79#include <xen/granttables.h> 79#include <xen/granttables.h>
80#include <xen/include/public/io/blkif.h> 80#include <xen/include/public/io/blkif.h>
81#include <xen/include/public/io/protocols.h> 81#include <xen/include/public/io/protocols.h>
82 82
83#include <xen/xenbus.h> 83#include <xen/xenbus.h>
84#include "locators.h" 84#include "locators.h"
85 85
86#undef XBD_DEBUG 86#undef XBD_DEBUG
87#ifdef XBD_DEBUG 87#ifdef XBD_DEBUG
88#define DPRINTF(x) printf x; 88#define DPRINTF(x) printf x;
89#else 89#else
90#define DPRINTF(x) 90#define DPRINTF(x)
91#endif 91#endif
92 92
93#define GRANT_INVALID_REF -1 93#define GRANT_INVALID_REF -1
94 94
95#define XBD_RING_SIZE __CONST_RING_SIZE(blkif, PAGE_SIZE) 95#define XBD_RING_SIZE __CONST_RING_SIZE(blkif, PAGE_SIZE)
96#define XBD_MAX_XFER (PAGE_SIZE * BLKIF_MAX_SEGMENTS_PER_REQUEST) 96#define XBD_MAX_XFER (PAGE_SIZE * BLKIF_MAX_SEGMENTS_PER_REQUEST)
97#define XBD_MAX_CHUNK 32*1024 /* max I/O size we process in 1 req */ 97#define XBD_MAX_CHUNK 32*1024 /* max I/O size we process in 1 req */
98#define XBD_XFER_LIMIT (2*XBD_MAX_XFER) 98#define XBD_XFER_LIMIT (2*XBD_MAX_XFER)
99 99
100#define XEN_BSHIFT 9 /* log2(XEN_BSIZE) */ 100#define XEN_BSHIFT 9 /* log2(XEN_BSIZE) */
101#define XEN_BSIZE (1 << XEN_BSHIFT)  101#define XEN_BSIZE (1 << XEN_BSHIFT)
102 102
103CTASSERT((MAXPHYS <= 2*XBD_MAX_CHUNK)); 103CTASSERT((MAXPHYS <= 2*XBD_MAX_CHUNK));
104CTASSERT(XEN_BSIZE == DEV_BSIZE); 104CTASSERT(XEN_BSIZE == DEV_BSIZE);
105 105
106struct xbd_indirect { 106struct xbd_indirect {
107 SLIST_ENTRY(xbd_indirect) in_next; 107 SLIST_ENTRY(xbd_indirect) in_next;
108 struct blkif_request_segment *in_addr; 108 struct blkif_request_segment *in_addr;
109 grant_ref_t in_gntref; 109 grant_ref_t in_gntref;
110}; 110};
111 111
112struct xbd_req { 112struct xbd_req {
113 SLIST_ENTRY(xbd_req) req_next; 113 SLIST_ENTRY(xbd_req) req_next;
114 uint16_t req_id; /* ID passed to backend */ 114 uint16_t req_id; /* ID passed to backend */
115 bus_dmamap_t req_dmamap; 115 bus_dmamap_t req_dmamap;
116 struct xbd_req *req_parent, *req_child; 116 struct xbd_req *req_parent, *req_child;
117 bool req_parent_done; 117 bool req_parent_done;
118 union { 118 union {
119 struct { 119 struct {
120 grant_ref_t req_gntref[XBD_XFER_LIMIT >> PAGE_SHIFT]; 120 grant_ref_t req_gntref[XBD_XFER_LIMIT >> PAGE_SHIFT];
121 struct buf *req_bp; /* buffer associated with this request */ 121 struct buf *req_bp; /* buffer associated with this request */
122 void *req_data; /* pointer to the data buffer */ 122 void *req_data; /* pointer to the data buffer */
123 struct xbd_indirect *req_indirect; /* indirect page */ 123 struct xbd_indirect *req_indirect; /* indirect page */
124 } req_rw; 124 } req_rw;
125 struct { 125 struct {
126 int s_error; 126 int s_error;
127 int s_done; 127 int s_done;
128 } req_sync; 128 } req_sync;
129 } u; 129 } u;
130}; 130};
131#define req_gntref u.req_rw.req_gntref 131#define req_gntref u.req_rw.req_gntref
132#define req_bp u.req_rw.req_bp 132#define req_bp u.req_rw.req_bp
133#define req_data u.req_rw.req_data 133#define req_data u.req_rw.req_data
134#define req_indirect u.req_rw.req_indirect 134#define req_indirect u.req_rw.req_indirect
135#define req_sync u.req_sync 135#define req_sync u.req_sync
136 136
137struct xbd_xenbus_softc { 137struct xbd_xenbus_softc {
138 struct dk_softc sc_dksc; /* Must be first in this struct */ 138 struct dk_softc sc_dksc; /* Must be first in this struct */
139 struct xenbus_device *sc_xbusd; 139 struct xenbus_device *sc_xbusd;
140 unsigned int sc_evtchn; 140 unsigned int sc_evtchn;
141 141
142 struct intrhand *sc_ih; /* Interrupt handler for this instance. */ 142 struct intrhand *sc_ih; /* Interrupt handler for this instance. */
143 kmutex_t sc_lock; 143 kmutex_t sc_lock;
144 kcondvar_t sc_cache_flush_cv; 144 kcondvar_t sc_cache_flush_cv;
145 kcondvar_t sc_req_cv; 145 kcondvar_t sc_req_cv;
146 kcondvar_t sc_detach_cv; 146 kcondvar_t sc_detach_cv;
147 kcondvar_t sc_suspend_cv; 147 kcondvar_t sc_suspend_cv;
148 148
149 blkif_front_ring_t sc_ring; 149 blkif_front_ring_t sc_ring;
150 grant_ref_t sc_ring_gntref; 150 grant_ref_t sc_ring_gntref;
151 151
152 struct xbd_req sc_reqs[XBD_RING_SIZE]; 152 struct xbd_req sc_reqs[XBD_RING_SIZE];
153 SLIST_HEAD(,xbd_req) sc_xbdreq_head; /* list of free requests */ 153 SLIST_HEAD(,xbd_req) sc_xbdreq_head; /* list of free requests */
154 154
155 struct xbd_indirect sc_indirect[XBD_RING_SIZE]; 155 struct xbd_indirect sc_indirect[XBD_RING_SIZE];
156 SLIST_HEAD(,xbd_indirect) sc_indirect_head; 156 SLIST_HEAD(,xbd_indirect) sc_indirect_head;
157 157
158 vmem_addr_t sc_unalign_buffer; 158 vmem_addr_t sc_unalign_buffer;
159 struct xbd_req *sc_unalign_used; 159 struct xbd_req *sc_unalign_used;
160 160
161 int sc_backend_status; /* our status with backend */ 161 int sc_backend_status; /* our status with backend */
162#define BLKIF_STATE_DISCONNECTED 0 162#define BLKIF_STATE_DISCONNECTED 0
163#define BLKIF_STATE_CONNECTED 1 163#define BLKIF_STATE_CONNECTED 1
164#define BLKIF_STATE_SUSPENDED 2 164#define BLKIF_STATE_SUSPENDED 2
165 165
166 int sc_shutdown; 166 int sc_shutdown;
167#define BLKIF_SHUTDOWN_RUN 0 /* no shutdown */ 167#define BLKIF_SHUTDOWN_RUN 0 /* no shutdown */
168#define BLKIF_SHUTDOWN_REMOTE 1 /* backend-initiated shutdown in progress */ 168#define BLKIF_SHUTDOWN_REMOTE 1 /* backend-initiated shutdown in progress */
169#define BLKIF_SHUTDOWN_LOCAL 2 /* locally-initiated shutdown in progress */ 169#define BLKIF_SHUTDOWN_LOCAL 2 /* locally-initiated shutdown in progress */
170 170
171 uint64_t sc_sectors; /* number of sectors for this device */ 171 uint64_t sc_sectors; /* number of sectors for this device */
172 u_long sc_secsize; /* sector size */ 172 u_long sc_secsize; /* sector size */
173 uint64_t sc_xbdsize; /* size of disk in DEV_BSIZE */ 173 uint64_t sc_xbdsize; /* size of disk in DEV_BSIZE */
174 u_long sc_info; /* VDISK_* */ 174 u_long sc_info; /* VDISK_* */
175 u_long sc_handle; /* from backend */ 175 u_long sc_handle; /* from backend */
176 int sc_features; 176 int sc_features;
177#define BLKIF_FEATURE_CACHE_FLUSH 0x1 177#define BLKIF_FEATURE_CACHE_FLUSH 0x1
178#define BLKIF_FEATURE_BARRIER 0x2 178#define BLKIF_FEATURE_BARRIER 0x2
179#define BLKIF_FEATURE_PERSISTENT 0x4 179#define BLKIF_FEATURE_PERSISTENT 0x4
180#define BLKIF_FEATURE_INDIRECT 0x8 180#define BLKIF_FEATURE_INDIRECT 0x8
181#define BLKIF_FEATURE_BITS \ 181#define BLKIF_FEATURE_BITS \
182 "\20\1CACHE-FLUSH\2BARRIER\3PERSISTENT\4INDIRECT" 182 "\20\1CACHE-FLUSH\2BARRIER\3PERSISTENT\4INDIRECT"
183 struct evcnt sc_cnt_map_unalign; 183 struct evcnt sc_cnt_map_unalign;
184 struct evcnt sc_cnt_unalign_busy; 184 struct evcnt sc_cnt_unalign_busy;
185 struct evcnt sc_cnt_queue_full; 185 struct evcnt sc_cnt_queue_full;
186 struct evcnt sc_cnt_indirect; 186 struct evcnt sc_cnt_indirect;
187}; 187};
188 188
189static int xbd_xenbus_match(device_t, cfdata_t, void *); 189static int xbd_xenbus_match(device_t, cfdata_t, void *);
190static void xbd_xenbus_attach(device_t, device_t, void *); 190static void xbd_xenbus_attach(device_t, device_t, void *);
191static int xbd_xenbus_detach(device_t, int); 191static int xbd_xenbus_detach(device_t, int);
192 192
193static bool xbd_xenbus_suspend(device_t, const pmf_qual_t *); 193static bool xbd_xenbus_suspend(device_t, const pmf_qual_t *);
194static bool xbd_xenbus_resume(device_t, const pmf_qual_t *); 194static bool xbd_xenbus_resume(device_t, const pmf_qual_t *);
195 195
196static int xbd_handler(void *); 196static int xbd_handler(void *);
197static int xbd_diskstart(device_t, struct buf *); 197static int xbd_diskstart(device_t, struct buf *);
198static void xbd_iosize(device_t, int *); 198static void xbd_iosize(device_t, int *);
199static void xbd_backend_changed(void *, XenbusState); 199static void xbd_backend_changed(void *, XenbusState);
200static void xbd_connect(struct xbd_xenbus_softc *); 200static void xbd_connect(struct xbd_xenbus_softc *);
201static void xbd_features(struct xbd_xenbus_softc *); 201static void xbd_features(struct xbd_xenbus_softc *);
202 202
203static void xbd_diskstart_submit(struct xbd_xenbus_softc *, int, 203static void xbd_diskstart_submit(struct xbd_xenbus_softc *, int,
204 struct buf *bp, int, bus_dmamap_t, grant_ref_t *); 204 struct buf *bp, int, bus_dmamap_t, grant_ref_t *);
205static void xbd_diskstart_submit_indirect(struct xbd_xenbus_softc *, 205static void xbd_diskstart_submit_indirect(struct xbd_xenbus_softc *,
206 struct xbd_req *, struct buf *bp); 206 struct xbd_req *, struct buf *bp);
207static int xbd_map_align(struct xbd_xenbus_softc *, struct xbd_req *); 207static int xbd_map_align(struct xbd_xenbus_softc *, struct xbd_req *);
208static void xbd_unmap_align(struct xbd_xenbus_softc *, struct xbd_req *, bool); 208static void xbd_unmap_align(struct xbd_xenbus_softc *, struct xbd_req *, bool);
209 209
210static void xbdminphys(struct buf *); 210static void xbdminphys(struct buf *);
211 211
212CFATTACH_DECL3_NEW(xbd, sizeof(struct xbd_xenbus_softc), 212CFATTACH_DECL3_NEW(xbd, sizeof(struct xbd_xenbus_softc),
213 xbd_xenbus_match, xbd_xenbus_attach, xbd_xenbus_detach, NULL, NULL, NULL, 213 xbd_xenbus_match, xbd_xenbus_attach, xbd_xenbus_detach, NULL, NULL, NULL,
214 DVF_DETACH_SHUTDOWN); 214 DVF_DETACH_SHUTDOWN);
215 215
216dev_type_open(xbdopen); 216dev_type_open(xbdopen);
217dev_type_close(xbdclose); 217dev_type_close(xbdclose);
218dev_type_read(xbdread); 218dev_type_read(xbdread);
219dev_type_write(xbdwrite); 219dev_type_write(xbdwrite);
220dev_type_ioctl(xbdioctl); 220dev_type_ioctl(xbdioctl);
221dev_type_strategy(xbdstrategy); 221dev_type_strategy(xbdstrategy);
222dev_type_dump(xbddump); 222dev_type_dump(xbddump);
223dev_type_size(xbdsize); 223dev_type_size(xbdsize);
224 224
225const struct bdevsw xbd_bdevsw = { 225const struct bdevsw xbd_bdevsw = {
226 .d_open = xbdopen, 226 .d_open = xbdopen,
227 .d_close = xbdclose, 227 .d_close = xbdclose,
228 .d_strategy = xbdstrategy, 228 .d_strategy = xbdstrategy,
229 .d_ioctl = xbdioctl, 229 .d_ioctl = xbdioctl,
230 .d_dump = xbddump, 230 .d_dump = xbddump,
231 .d_psize = xbdsize, 231 .d_psize = xbdsize,
232 .d_discard = nodiscard, 232 .d_discard = nodiscard,
233 .d_flag = D_DISK | D_MPSAFE 233 .d_flag = D_DISK | D_MPSAFE
234}; 234};
235 235
236const struct cdevsw xbd_cdevsw = { 236const struct cdevsw xbd_cdevsw = {
237 .d_open = xbdopen, 237 .d_open = xbdopen,
238 .d_close = xbdclose, 238 .d_close = xbdclose,
239 .d_read = xbdread, 239 .d_read = xbdread,
240 .d_write = xbdwrite, 240 .d_write = xbdwrite,
241 .d_ioctl = xbdioctl, 241 .d_ioctl = xbdioctl,
242 .d_stop = nostop, 242 .d_stop = nostop,
243 .d_tty = notty, 243 .d_tty = notty,
244 .d_poll = nopoll, 244 .d_poll = nopoll,
245 .d_mmap = nommap, 245 .d_mmap = nommap,
246 .d_kqfilter = nokqfilter, 246 .d_kqfilter = nokqfilter,
247 .d_discard = nodiscard, 247 .d_discard = nodiscard,
248 .d_flag = D_DISK | D_MPSAFE 248 .d_flag = D_DISK | D_MPSAFE
249}; 249};
250 250
251extern struct cfdriver xbd_cd; 251extern struct cfdriver xbd_cd;
252 252
253static const struct dkdriver xbddkdriver = { 253static const struct dkdriver xbddkdriver = {
254 .d_strategy = xbdstrategy, 254 .d_strategy = xbdstrategy,
255 .d_minphys = xbdminphys, 255 .d_minphys = xbdminphys,
256 .d_open = xbdopen, 256 .d_open = xbdopen,
257 .d_close = xbdclose, 257 .d_close = xbdclose,
258 .d_diskstart = xbd_diskstart, 258 .d_diskstart = xbd_diskstart,
259 .d_iosize = xbd_iosize, 259 .d_iosize = xbd_iosize,
260}; 260};
261 261
262static int 262static int
263xbd_xenbus_match(device_t parent, cfdata_t match, void *aux) 263xbd_xenbus_match(device_t parent, cfdata_t match, void *aux)
264{ 264{
265 struct xenbusdev_attach_args *xa = aux; 265 struct xenbusdev_attach_args *xa = aux;
266 266
267 if (strcmp(xa->xa_type, "vbd") != 0) 267 if (strcmp(xa->xa_type, "vbd") != 0)
268 return 0; 268 return 0;
269 269
270 if (match->cf_loc[XENBUSCF_ID] != XENBUSCF_ID_DEFAULT && 270 if (match->cf_loc[XENBUSCF_ID] != XENBUSCF_ID_DEFAULT &&
271 match->cf_loc[XENBUSCF_ID] != xa->xa_id) 271 match->cf_loc[XENBUSCF_ID] != xa->xa_id)
272 return 0; 272 return 0;
273 273
274 return 1; 274 return 1;
275} 275}
276 276
277static void 277static void
278xbd_xenbus_attach(device_t parent, device_t self, void *aux) 278xbd_xenbus_attach(device_t parent, device_t self, void *aux)
279{ 279{
280 struct xbd_xenbus_softc *sc = device_private(self); 280 struct xbd_xenbus_softc *sc = device_private(self);
281 struct xenbusdev_attach_args *xa = aux; 281 struct xenbusdev_attach_args *xa = aux;
282 blkif_sring_t *ring; 282 blkif_sring_t *ring;
283 RING_IDX i; 283 RING_IDX i;
284#ifdef XBD_DEBUG 
285 char **dir, *val; 
286 int dir_n = 0; 
287 char id_str[20]; 
288 int err; 
289#endif 
290 284
291 config_pending_incr(self); 285 config_pending_incr(self);
292 aprint_normal(": Xen Virtual Block Device Interface\n"); 286 aprint_normal(": Xen Virtual Block Device Interface\n");
293 287
294 dk_init(&sc->sc_dksc, self, DKTYPE_ESDI); 288 dk_init(&sc->sc_dksc, self, DKTYPE_ESDI);
295 disk_init(&sc->sc_dksc.sc_dkdev, device_xname(self), &xbddkdriver); 289 disk_init(&sc->sc_dksc.sc_dkdev, device_xname(self), &xbddkdriver);
296 290
297 sc->sc_xbusd = xa->xa_xbusd; 291 sc->sc_xbusd = xa->xa_xbusd;
298 sc->sc_xbusd->xbusd_otherend_changed = xbd_backend_changed; 292 sc->sc_xbusd->xbusd_otherend_changed = xbd_backend_changed;
299 293
300 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_BIO); 294 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_BIO);
301 cv_init(&sc->sc_cache_flush_cv, "xbdsync"); 295 cv_init(&sc->sc_cache_flush_cv, "xbdsync");
302 cv_init(&sc->sc_req_cv, "xbdreq"); 296 cv_init(&sc->sc_req_cv, "xbdreq");
303 cv_init(&sc->sc_detach_cv, "xbddetach"); 297 cv_init(&sc->sc_detach_cv, "xbddetach");
304 cv_init(&sc->sc_suspend_cv, "xbdsuspend"); 298 cv_init(&sc->sc_suspend_cv, "xbdsuspend");
305 299
306 xbd_features(sc); 300 xbd_features(sc);
307 301
308 /* initialize free requests list */ 302 /* initialize free requests list */
309 SLIST_INIT(&sc->sc_xbdreq_head); 303 SLIST_INIT(&sc->sc_xbdreq_head);
310 for (i = 0; i < XBD_RING_SIZE; i++) { 304 for (i = 0; i < XBD_RING_SIZE; i++) {
311 sc->sc_reqs[i].req_id = i; 305 sc->sc_reqs[i].req_id = i;
312 SLIST_INSERT_HEAD(&sc->sc_xbdreq_head, &sc->sc_reqs[i], 306 SLIST_INSERT_HEAD(&sc->sc_xbdreq_head, &sc->sc_reqs[i],
313 req_next); 307 req_next);
314 } 308 }
315 309
316 if (sc->sc_features & BLKIF_FEATURE_INDIRECT) { 310 if (sc->sc_features & BLKIF_FEATURE_INDIRECT) {
317 /* initialize indirect page list */ 311 /* initialize indirect page list */
318 for (i = 0; i < XBD_RING_SIZE; i++) { 312 for (i = 0; i < XBD_RING_SIZE; i++) {
319 vmem_addr_t va; 313 vmem_addr_t va;
320 if (uvm_km_kmem_alloc(kmem_va_arena, 314 if (uvm_km_kmem_alloc(kmem_va_arena,
321 PAGE_SIZE, VM_SLEEP | VM_INSTANTFIT, &va) != 0) { 315 PAGE_SIZE, VM_SLEEP | VM_INSTANTFIT, &va) != 0) {
322 aprint_error_dev(self, 316 aprint_error_dev(self,
323 "can't alloc indirect pages\n"); 317 "can't alloc indirect pages\n");
324 return; 318 return;
325 } 319 }
326 sc->sc_indirect[i].in_addr = (void *)va; 320 sc->sc_indirect[i].in_addr = (void *)va;
327 SLIST_INSERT_HEAD(&sc->sc_indirect_head, 321 SLIST_INSERT_HEAD(&sc->sc_indirect_head,
328 &sc->sc_indirect[i], in_next); 322 &sc->sc_indirect[i], in_next);
329 } 323 }
330 } 324 }
331 325
332 sc->sc_backend_status = BLKIF_STATE_DISCONNECTED; 326 sc->sc_backend_status = BLKIF_STATE_DISCONNECTED;
333 sc->sc_shutdown = BLKIF_SHUTDOWN_REMOTE; 327 sc->sc_shutdown = BLKIF_SHUTDOWN_REMOTE;
334 328
335 ring = (void *)uvm_km_alloc(kernel_map, PAGE_SIZE, 0, UVM_KMF_WIRED); 329 ring = (void *)uvm_km_alloc(kernel_map, PAGE_SIZE, 0, UVM_KMF_WIRED);
336 if (ring == NULL) 330 if (ring == NULL)
337 panic("%s: can't alloc ring", device_xname(self)); 331 panic("%s: can't alloc ring", device_xname(self));
338 sc->sc_ring.sring = ring; 332 sc->sc_ring.sring = ring;
339 333
340 evcnt_attach_dynamic(&sc->sc_cnt_map_unalign, EVCNT_TYPE_MISC, 334 evcnt_attach_dynamic(&sc->sc_cnt_map_unalign, EVCNT_TYPE_MISC,
341 NULL, device_xname(self), "map unaligned"); 335 NULL, device_xname(self), "map unaligned");
342 evcnt_attach_dynamic(&sc->sc_cnt_unalign_busy, EVCNT_TYPE_MISC, 336 evcnt_attach_dynamic(&sc->sc_cnt_unalign_busy, EVCNT_TYPE_MISC,
343 NULL, device_xname(self), "map unaligned"); 337 NULL, device_xname(self), "map unaligned");
344 evcnt_attach_dynamic(&sc->sc_cnt_queue_full, EVCNT_TYPE_MISC, 338 evcnt_attach_dynamic(&sc->sc_cnt_queue_full, EVCNT_TYPE_MISC,
345 NULL, device_xname(self), "queue full"); 339 NULL, device_xname(self), "queue full");
346 evcnt_attach_dynamic(&sc->sc_cnt_indirect, EVCNT_TYPE_MISC, 340 evcnt_attach_dynamic(&sc->sc_cnt_indirect, EVCNT_TYPE_MISC,
347 NULL, device_xname(self), "indirect segment"); 341 NULL, device_xname(self), "indirect segment");
348 342
349 for (i = 0; i < XBD_RING_SIZE; i++) { 343 for (i = 0; i < XBD_RING_SIZE; i++) {
350 if (bus_dmamap_create(sc->sc_xbusd->xbusd_dmat, 344 if (bus_dmamap_create(sc->sc_xbusd->xbusd_dmat,
351 MAXPHYS, XBD_XFER_LIMIT >> PAGE_SHIFT, 345 MAXPHYS, XBD_XFER_LIMIT >> PAGE_SHIFT,
352 PAGE_SIZE, PAGE_SIZE, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, 346 PAGE_SIZE, PAGE_SIZE, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW,
353 &sc->sc_reqs[i].req_dmamap) != 0) { 347 &sc->sc_reqs[i].req_dmamap) != 0) {
354 aprint_error_dev(self, "can't alloc dma maps\n"); 348 aprint_error_dev(self, "can't alloc dma maps\n");
355 return; 349 return;
356 } 350 }
357 } 351 }
358 352
359 if (uvm_km_kmem_alloc(kmem_va_arena, 353 if (uvm_km_kmem_alloc(kmem_va_arena,
360 MAXPHYS, VM_SLEEP | VM_INSTANTFIT, &sc->sc_unalign_buffer) != 0) { 354 MAXPHYS, VM_SLEEP | VM_INSTANTFIT, &sc->sc_unalign_buffer) != 0) {
361 aprint_error_dev(self, "can't alloc align buffer\n"); 355 aprint_error_dev(self, "can't alloc align buffer\n");
362 return; 356 return;
363 } 357 }
364 358
365 /* resume shared structures and tell backend that we are ready */ 359 /* resume shared structures and tell backend that we are ready */
366 if (xbd_xenbus_resume(self, PMF_Q_NONE) == false) { 360 if (xbd_xenbus_resume(self, PMF_Q_NONE) == false) {
367 uvm_km_free(kernel_map, (vaddr_t)ring, PAGE_SIZE, 361 uvm_km_free(kernel_map, (vaddr_t)ring, PAGE_SIZE,
368 UVM_KMF_WIRED); 362 UVM_KMF_WIRED);
369 return; 363 return;
370 } 364 }
371 365
372 if (!pmf_device_register(self, xbd_xenbus_suspend, xbd_xenbus_resume)) 366 if (!pmf_device_register(self, xbd_xenbus_suspend, xbd_xenbus_resume))
373 aprint_error_dev(self, "couldn't establish power handler\n"); 367 aprint_error_dev(self, "couldn't establish power handler\n");
374} 368}
375 369
376static int 370static int
377xbd_xenbus_detach(device_t dev, int flags) 371xbd_xenbus_detach(device_t dev, int flags)
378{ 372{
379 struct xbd_xenbus_softc *sc = device_private(dev); 373 struct xbd_xenbus_softc *sc = device_private(dev);
380 int bmaj, cmaj, i, mn, rc; 374 int bmaj, cmaj, i, mn, rc;
381 375
382 DPRINTF(("%s: xbd_detach\n", device_xname(dev))); 376 DPRINTF(("%s: xbd_detach\n", device_xname(dev)));
383 377
384 rc = disk_begindetach(&sc->sc_dksc.sc_dkdev, NULL, dev, flags); 378 rc = disk_begindetach(&sc->sc_dksc.sc_dkdev, NULL, dev, flags);
385 if (rc != 0) 379 if (rc != 0)
386 return rc; 380 return rc;
387 381
388 mutex_enter(&sc->sc_lock); 382 mutex_enter(&sc->sc_lock);
389 if (sc->sc_shutdown == BLKIF_SHUTDOWN_RUN) { 383 if (sc->sc_shutdown == BLKIF_SHUTDOWN_RUN) {
390 sc->sc_shutdown = BLKIF_SHUTDOWN_LOCAL; 384 sc->sc_shutdown = BLKIF_SHUTDOWN_LOCAL;
391 385
392 /* wait for requests to complete */ 386 /* wait for requests to complete */
393 while (sc->sc_backend_status == BLKIF_STATE_CONNECTED && 387 while (sc->sc_backend_status == BLKIF_STATE_CONNECTED &&
394 disk_isbusy(&sc->sc_dksc.sc_dkdev)) { 388 disk_isbusy(&sc->sc_dksc.sc_dkdev)) {
395 cv_timedwait(&sc->sc_detach_cv, &sc->sc_lock, hz/2); 389 cv_timedwait(&sc->sc_detach_cv, &sc->sc_lock, hz/2);
396 } 390 }
397 mutex_exit(&sc->sc_lock); 391 mutex_exit(&sc->sc_lock);
398 392
399 /* Trigger state transition with backend */ 393 /* Trigger state transition with backend */
400 xenbus_switch_state(sc->sc_xbusd, NULL, XenbusStateClosing); 394 xenbus_switch_state(sc->sc_xbusd, NULL, XenbusStateClosing);
401 395
402 mutex_enter(&sc->sc_lock); 396 mutex_enter(&sc->sc_lock);
403 } 397 }
404 if ((flags & DETACH_FORCE) == 0) { 398 if ((flags & DETACH_FORCE) == 0) {
405 /* xbd_xenbus_detach already in progress */ 399 /* xbd_xenbus_detach already in progress */
406 cv_broadcast(&sc->sc_detach_cv); 400 cv_broadcast(&sc->sc_detach_cv);
407 mutex_exit(&sc->sc_lock); 401 mutex_exit(&sc->sc_lock);
408 return EALREADY; 402 return EALREADY;
409 } 403 }
410 mutex_exit(&sc->sc_lock); 404 mutex_exit(&sc->sc_lock);
411 while (xenbus_read_driver_state(sc->sc_xbusd->xbusd_otherend) 405 while (xenbus_read_driver_state(sc->sc_xbusd->xbusd_otherend)
412 != XenbusStateClosed) { 406 != XenbusStateClosed) {
413 mutex_enter(&sc->sc_lock); 407 mutex_enter(&sc->sc_lock);
414 cv_timedwait(&sc->sc_detach_cv, &sc->sc_lock, hz/2); 408 cv_timedwait(&sc->sc_detach_cv, &sc->sc_lock, hz/2);
415 mutex_exit(&sc->sc_lock); 409 mutex_exit(&sc->sc_lock);
416 } 410 }
417 411
418 /* locate the major number */ 412 /* locate the major number */
419 bmaj = bdevsw_lookup_major(&xbd_bdevsw); 413 bmaj = bdevsw_lookup_major(&xbd_bdevsw);
420 cmaj = cdevsw_lookup_major(&xbd_cdevsw); 414 cmaj = cdevsw_lookup_major(&xbd_cdevsw);
421 415
422 /* Nuke the vnodes for any open instances. */ 416 /* Nuke the vnodes for any open instances. */
423 for (i = 0; i < MAXPARTITIONS; i++) { 417 for (i = 0; i < MAXPARTITIONS; i++) {
424 mn = DISKMINOR(device_unit(dev), i); 418 mn = DISKMINOR(device_unit(dev), i);
425 vdevgone(bmaj, mn, mn, VBLK); 419 vdevgone(bmaj, mn, mn, VBLK);
426 vdevgone(cmaj, mn, mn, VCHR); 420 vdevgone(cmaj, mn, mn, VCHR);
427 } 421 }
428 422
429 if (sc->sc_backend_status == BLKIF_STATE_CONNECTED) { 423 if (sc->sc_backend_status == BLKIF_STATE_CONNECTED) {
430 /* Delete all of our wedges. */ 424 /* Delete all of our wedges. */
431 dkwedge_delall(&sc->sc_dksc.sc_dkdev); 425 dkwedge_delall(&sc->sc_dksc.sc_dkdev);
432 426
433 /* Kill off any queued buffers. */ 427 /* Kill off any queued buffers. */
434 dk_drain(&sc->sc_dksc); 428 dk_drain(&sc->sc_dksc);
435 bufq_free(sc->sc_dksc.sc_bufq); 429 bufq_free(sc->sc_dksc.sc_bufq);
436 430
437 /* detach disk */ 431 /* detach disk */
438 disk_detach(&sc->sc_dksc.sc_dkdev); 432 disk_detach(&sc->sc_dksc.sc_dkdev);
439 disk_destroy(&sc->sc_dksc.sc_dkdev); 433 disk_destroy(&sc->sc_dksc.sc_dkdev);
440 dk_detach(&sc->sc_dksc); 434 dk_detach(&sc->sc_dksc);
441 } 435 }
442 436
443 hypervisor_mask_event(sc->sc_evtchn); 437 hypervisor_mask_event(sc->sc_evtchn);
444 xen_intr_disestablish(sc->sc_ih); 438 xen_intr_disestablish(sc->sc_ih);
445 439
446 mutex_enter(&sc->sc_lock); 440 mutex_enter(&sc->sc_lock);
447 while (xengnt_status(sc->sc_ring_gntref)) 441 while (xengnt_status(sc->sc_ring_gntref))
448 cv_timedwait(&sc->sc_detach_cv, &sc->sc_lock, hz/2); 442 cv_timedwait(&sc->sc_detach_cv, &sc->sc_lock, hz/2);
449 mutex_exit(&sc->sc_lock); 443 mutex_exit(&sc->sc_lock);
450 444
451 xengnt_revoke_access(sc->sc_ring_gntref); 445 xengnt_revoke_access(sc->sc_ring_gntref);
452 uvm_km_free(kernel_map, (vaddr_t)sc->sc_ring.sring, 446 uvm_km_free(kernel_map, (vaddr_t)sc->sc_ring.sring,
453 PAGE_SIZE, UVM_KMF_WIRED); 447 PAGE_SIZE, UVM_KMF_WIRED);
454 448
455 for (i = 0; i < XBD_RING_SIZE; i++) { 449 for (i = 0; i < XBD_RING_SIZE; i++) {
456 if (sc->sc_reqs[i].req_dmamap != NULL) { 450 if (sc->sc_reqs[i].req_dmamap != NULL) {
457 bus_dmamap_destroy(sc->sc_xbusd->xbusd_dmat, 451 bus_dmamap_destroy(sc->sc_xbusd->xbusd_dmat,
458 sc->sc_reqs[i].req_dmamap); 452 sc->sc_reqs[i].req_dmamap);
459 sc->sc_reqs[i].req_dmamap = NULL; 453 sc->sc_reqs[i].req_dmamap = NULL;
460 } 454 }
461 } 455 }
462 456
463 if (sc->sc_unalign_buffer != 0) { 457 if (sc->sc_unalign_buffer != 0) {
464 uvm_km_kmem_free(kmem_va_arena, sc->sc_unalign_buffer, MAXPHYS); 458 uvm_km_kmem_free(kmem_va_arena, sc->sc_unalign_buffer, MAXPHYS);
465 sc->sc_unalign_buffer = 0; 459 sc->sc_unalign_buffer = 0;
466 } 460 }
467 461
468 mutex_destroy(&sc->sc_lock); 462 mutex_destroy(&sc->sc_lock);
469 463
470 evcnt_detach(&sc->sc_cnt_map_unalign); 464 evcnt_detach(&sc->sc_cnt_map_unalign);
471 evcnt_detach(&sc->sc_cnt_unalign_busy); 465 evcnt_detach(&sc->sc_cnt_unalign_busy);
472 evcnt_detach(&sc->sc_cnt_queue_full); 466 evcnt_detach(&sc->sc_cnt_queue_full);
473 evcnt_detach(&sc->sc_cnt_indirect); 467 evcnt_detach(&sc->sc_cnt_indirect);
474 468
475 pmf_device_deregister(dev); 469 pmf_device_deregister(dev);
476 470
477 return 0; 471 return 0;
478} 472}
479 473
480static bool 474static bool
481xbd_xenbus_suspend(device_t dev, const pmf_qual_t *qual) { 475xbd_xenbus_suspend(device_t dev, const pmf_qual_t *qual) {
482 476
483 struct xbd_xenbus_softc *sc; 477 struct xbd_xenbus_softc *sc;
484 478
485 sc = device_private(dev); 479 sc = device_private(dev);
486 480
487 mutex_enter(&sc->sc_lock); 481 mutex_enter(&sc->sc_lock);
488 /* wait for requests to complete, then suspend device */ 482 /* wait for requests to complete, then suspend device */
489 while (sc->sc_backend_status == BLKIF_STATE_CONNECTED && 483 while (sc->sc_backend_status == BLKIF_STATE_CONNECTED &&
490 disk_isbusy(&sc->sc_dksc.sc_dkdev)) { 484 disk_isbusy(&sc->sc_dksc.sc_dkdev)) {
491 cv_timedwait(&sc->sc_suspend_cv, &sc->sc_lock, hz/2); 485 cv_timedwait(&sc->sc_suspend_cv, &sc->sc_lock, hz/2);
492 } 486 }
493 487
494 hypervisor_mask_event(sc->sc_evtchn); 488 hypervisor_mask_event(sc->sc_evtchn);
495 sc->sc_backend_status = BLKIF_STATE_SUSPENDED; 489 sc->sc_backend_status = BLKIF_STATE_SUSPENDED;
496 xen_intr_disestablish(sc->sc_ih); 490 xen_intr_disestablish(sc->sc_ih);
497 491
498 mutex_exit(&sc->sc_lock); 492 mutex_exit(&sc->sc_lock);
499 493
500 xenbus_device_suspend(sc->sc_xbusd); 494 xenbus_device_suspend(sc->sc_xbusd);
501 aprint_verbose_dev(dev, "removed event channel %d\n", sc->sc_evtchn); 495 aprint_verbose_dev(dev, "removed event channel %d\n", sc->sc_evtchn);
502 496
503 return true; 497 return true;
504} 498}
505 499
506static bool 500static bool
507xbd_xenbus_resume(device_t dev, const pmf_qual_t *qual) 501xbd_xenbus_resume(device_t dev, const pmf_qual_t *qual)
508{ 502{
509 struct xbd_xenbus_softc *sc; 503 struct xbd_xenbus_softc *sc;
510 struct xenbus_transaction *xbt; 504 struct xenbus_transaction *xbt;
511 int error; 505 int error;
512 blkif_sring_t *ring; 506 blkif_sring_t *ring;
513 paddr_t ma; 507 paddr_t ma;
514 const char *errmsg; 508 const char *errmsg;
515 509
516 sc = device_private(dev); 510 sc = device_private(dev);
517 511
518 if (sc->sc_backend_status == BLKIF_STATE_SUSPENDED) { 512 if (sc->sc_backend_status == BLKIF_STATE_SUSPENDED) {
519 /* 513 /*
520 * Device was suspended, so ensure that access associated to 514 * Device was suspended, so ensure that access associated to
521 * the block I/O ring is revoked. 515 * the block I/O ring is revoked.
522 */ 516 */
523 xengnt_revoke_access(sc->sc_ring_gntref); 517 xengnt_revoke_access(sc->sc_ring_gntref);
524 } 518 }
525 sc->sc_ring_gntref = GRANT_INVALID_REF; 519 sc->sc_ring_gntref = GRANT_INVALID_REF;
526 520
527 /* Initialize ring */ 521 /* Initialize ring */
528 ring = sc->sc_ring.sring; 522 ring = sc->sc_ring.sring;
529 memset(ring, 0, PAGE_SIZE); 523 memset(ring, 0, PAGE_SIZE);
530 SHARED_RING_INIT(ring); 524 SHARED_RING_INIT(ring);
531 FRONT_RING_INIT(&sc->sc_ring, ring, PAGE_SIZE); 525 FRONT_RING_INIT(&sc->sc_ring, ring, PAGE_SIZE);
532 526
533 /* 527 /*
534 * get MA address of the ring, and use it to set up the grant entry 528 * get MA address of the ring, and use it to set up the grant entry
535 * for the block device 529 * for the block device
536 */ 530 */
537 (void)pmap_extract_ma(pmap_kernel(), (vaddr_t)ring, &ma); 531 (void)pmap_extract_ma(pmap_kernel(), (vaddr_t)ring, &ma);
538 error = xenbus_grant_ring(sc->sc_xbusd, ma, &sc->sc_ring_gntref); 532 error = xenbus_grant_ring(sc->sc_xbusd, ma, &sc->sc_ring_gntref);
539 if (error) 533 if (error)
540 goto abort_resume; 534 goto abort_resume;
541 535
542 if (sc->sc_features & BLKIF_FEATURE_INDIRECT) { 536 if (sc->sc_features & BLKIF_FEATURE_INDIRECT) {
543 for (int i = 0; i < XBD_RING_SIZE; i++) { 537 for (int i = 0; i < XBD_RING_SIZE; i++) {
544 vaddr_t va = (vaddr_t)sc->sc_indirect[i].in_addr; 538 vaddr_t va = (vaddr_t)sc->sc_indirect[i].in_addr;
545 KASSERT(va != 0); 539 KASSERT(va != 0);
546 KASSERT((va & PAGE_MASK) == 0); 540 KASSERT((va & PAGE_MASK) == 0);
547 (void)pmap_extract_ma(pmap_kernel(), va, &ma); 541 (void)pmap_extract_ma(pmap_kernel(), va, &ma);
548 if (xengnt_grant_access( 542 if (xengnt_grant_access(
549 sc->sc_xbusd->xbusd_otherend_id, 543 sc->sc_xbusd->xbusd_otherend_id,
550 ma, true, &sc->sc_indirect[i].in_gntref)) { 544 ma, true, &sc->sc_indirect[i].in_gntref)) {
551 aprint_error_dev(dev, 545 aprint_error_dev(dev,
552 "indirect page grant failed\n"); 546 "indirect page grant failed\n");
553 goto abort_resume; 547 goto abort_resume;
554 } 548 }
555 } 549 }
556 } 550 }
557 551
558 error = xenbus_alloc_evtchn(sc->sc_xbusd, &sc->sc_evtchn); 552 error = xenbus_alloc_evtchn(sc->sc_xbusd, &sc->sc_evtchn);
559 if (error) 553 if (error)
560 goto abort_resume; 554 goto abort_resume;
561 555
562 aprint_verbose_dev(dev, "using event channel %d\n", 556 aprint_verbose_dev(dev, "using event channel %d\n",
563 sc->sc_evtchn); 557 sc->sc_evtchn);
564 sc->sc_ih = xen_intr_establish_xname(-1, &xen_pic, sc->sc_evtchn, 558 sc->sc_ih = xen_intr_establish_xname(-1, &xen_pic, sc->sc_evtchn,
565 IST_LEVEL, IPL_BIO, &xbd_handler, sc, true, device_xname(dev)); 559 IST_LEVEL, IPL_BIO, &xbd_handler, sc, true, device_xname(dev));
566 KASSERT(sc->sc_ih != NULL); 560 KASSERT(sc->sc_ih != NULL);
567 561
568again: 562again:
569 xbt = xenbus_transaction_start(); 563 xbt = xenbus_transaction_start();
570 if (xbt == NULL) 564 if (xbt == NULL)
571 return false; 565 return false;
572 error = xenbus_printf(xbt, sc->sc_xbusd->xbusd_path, 566 error = xenbus_printf(xbt, sc->sc_xbusd->xbusd_path,
573 "ring-ref","%u", sc->sc_ring_gntref); 567 "ring-ref","%u", sc->sc_ring_gntref);
574 if (error) { 568 if (error) {
575 errmsg = "writing ring-ref"; 569 errmsg = "writing ring-ref";
576 goto abort_transaction; 570 goto abort_transaction;
577 } 571 }
578 error = xenbus_printf(xbt, sc->sc_xbusd->xbusd_path, 572 error = xenbus_printf(xbt, sc->sc_xbusd->xbusd_path,
579 "event-channel", "%u", sc->sc_evtchn); 573 "event-channel", "%u", sc->sc_evtchn);
580 if (error) { 574 if (error) {
581 errmsg = "writing event channel"; 575 errmsg = "writing event channel";
582 goto abort_transaction; 576 goto abort_transaction;
583 } 577 }
584 error = xenbus_printf(xbt, sc->sc_xbusd->xbusd_path, 578 error = xenbus_printf(xbt, sc->sc_xbusd->xbusd_path,
585 "protocol", "%s", XEN_IO_PROTO_ABI_NATIVE); 579 "protocol", "%s", XEN_IO_PROTO_ABI_NATIVE);
586 if (error) { 580 if (error) {
587 errmsg = "writing protocol"; 581 errmsg = "writing protocol";
588 goto abort_transaction; 582 goto abort_transaction;
589 } 583 }
590 error = xenbus_transaction_end(xbt, 0); 584 error = xenbus_transaction_end(xbt, 0);
591 if (error == EAGAIN) 585 if (error == EAGAIN)
592 goto again; 586 goto again;
593 if (error != 0) { 587 if (error != 0) {
594 xenbus_dev_fatal(sc->sc_xbusd, error, 588 xenbus_dev_fatal(sc->sc_xbusd, error,
595 "completing transaction"); 589 "completing transaction");
596 return false; 590 return false;
597 } 591 }
598 592
599 xenbus_switch_state(sc->sc_xbusd, NULL, XenbusStateInitialised); 593 xenbus_switch_state(sc->sc_xbusd, NULL, XenbusStateInitialised);
600 594
601 if (sc->sc_backend_status == BLKIF_STATE_SUSPENDED) { 595 if (sc->sc_backend_status == BLKIF_STATE_SUSPENDED) {
602 /* 596 /*
603 * device was suspended, softc structures are 597 * device was suspended, softc structures are
604 * already initialized - we use a shortcut 598 * already initialized - we use a shortcut
605 */ 599 */
606 sc->sc_backend_status = BLKIF_STATE_CONNECTED; 600 sc->sc_backend_status = BLKIF_STATE_CONNECTED;
607 xenbus_device_resume(sc->sc_xbusd); 601 xenbus_device_resume(sc->sc_xbusd);
608 hypervisor_unmask_event(sc->sc_evtchn); 602 hypervisor_unmask_event(sc->sc_evtchn);
609 xenbus_switch_state(sc->sc_xbusd, NULL, XenbusStateConnected); 603 xenbus_switch_state(sc->sc_xbusd, NULL, XenbusStateConnected);
610 } 604 }
611 605
612 return true; 606 return true;
613 607
614abort_resume: 608abort_resume:
615 xenbus_dev_fatal(sc->sc_xbusd, error, "resuming device"); 609 xenbus_dev_fatal(sc->sc_xbusd, error, "resuming device");
616 return false; 610 return false;
617 611
618abort_transaction: 612abort_transaction:
619 xenbus_transaction_end(xbt, 1); 613 xenbus_transaction_end(xbt, 1);
620 xenbus_dev_fatal(sc->sc_xbusd, error, "%s", errmsg); 614 xenbus_dev_fatal(sc->sc_xbusd, error, "%s", errmsg);
621 return false; 615 return false;
622} 616}
623 617
624static void 618static void
625xbd_backend_changed(void *arg, XenbusState new_state) 619xbd_backend_changed(void *arg, XenbusState new_state)
626{ 620{
627 struct xbd_xenbus_softc *sc = device_private((device_t)arg); 621 struct xbd_xenbus_softc *sc = device_private((device_t)arg);
628 struct disk_geom *dg; 622 struct disk_geom *dg;
629 623
630 char buf[64]; 624 char buf[64];
631 DPRINTF(("%s: new backend state %d\n", 625 DPRINTF(("%s: new backend state %d\n",
632 device_xname(sc->sc_dksc.sc_dev), new_state)); 626 device_xname(sc->sc_dksc.sc_dev), new_state));
633 627
634 switch (new_state) { 628 switch (new_state) {
635 case XenbusStateUnknown: 629 case XenbusStateUnknown:
636 case XenbusStateInitialising: 630 case XenbusStateInitialising:
637 case XenbusStateInitWait: 631 case XenbusStateInitWait:
638 case XenbusStateInitialised: 632 case XenbusStateInitialised:
639 break; 633 break;
640 case XenbusStateClosing: 634 case XenbusStateClosing:
641 mutex_enter(&sc->sc_lock); 635 mutex_enter(&sc->sc_lock);
642 if (sc->sc_shutdown == BLKIF_SHUTDOWN_RUN) 636 if (sc->sc_shutdown == BLKIF_SHUTDOWN_RUN)
643 sc->sc_shutdown = BLKIF_SHUTDOWN_REMOTE; 637 sc->sc_shutdown = BLKIF_SHUTDOWN_REMOTE;
644 /* wait for requests to complete */ 638 /* wait for requests to complete */
645 while (sc->sc_backend_status == BLKIF_STATE_CONNECTED && 639 while (sc->sc_backend_status == BLKIF_STATE_CONNECTED &&
646 disk_isbusy(&sc->sc_dksc.sc_dkdev)) { 640 disk_isbusy(&sc->sc_dksc.sc_dkdev)) {
647 cv_timedwait(&sc->sc_detach_cv, &sc->sc_lock, hz/2); 641 cv_timedwait(&sc->sc_detach_cv, &sc->sc_lock, hz/2);
648 } 642 }
649 mutex_exit(&sc->sc_lock); 643 mutex_exit(&sc->sc_lock);
650 xenbus_switch_state(sc->sc_xbusd, NULL, XenbusStateClosed); 644 xenbus_switch_state(sc->sc_xbusd, NULL, XenbusStateClosed);
651 break; 645 break;
652 case XenbusStateConnected: 646 case XenbusStateConnected:
653 /* 647 /*
654 * note that xbd_backend_changed() can only be called by 648 * note that xbd_backend_changed() can only be called by
655 * the xenbus thread. 649 * the xenbus thread.
656 */ 650 */
657 651
658 if (sc->sc_backend_status == BLKIF_STATE_CONNECTED || 652 if (sc->sc_backend_status == BLKIF_STATE_CONNECTED ||
659 sc->sc_backend_status == BLKIF_STATE_SUSPENDED) 653 sc->sc_backend_status == BLKIF_STATE_SUSPENDED)
660 /* already connected */ 654 /* already connected */
661 return; 655 return;
662 656
663 xbd_connect(sc); 657 xbd_connect(sc);
664 sc->sc_shutdown = BLKIF_SHUTDOWN_RUN; 658 sc->sc_shutdown = BLKIF_SHUTDOWN_RUN;
665 sc->sc_xbdsize = 659 sc->sc_xbdsize =
666 sc->sc_sectors * (uint64_t)sc->sc_secsize / DEV_BSIZE; 660 sc->sc_sectors * (uint64_t)sc->sc_secsize / DEV_BSIZE;
667 dg = &sc->sc_dksc.sc_dkdev.dk_geom; 661 dg = &sc->sc_dksc.sc_dkdev.dk_geom;
668 memset(dg, 0, sizeof(*dg));  662 memset(dg, 0, sizeof(*dg));
669 663
670 dg->dg_secperunit = sc->sc_xbdsize; 664 dg->dg_secperunit = sc->sc_xbdsize;
671 dg->dg_secsize = DEV_BSIZE; 665 dg->dg_secsize = DEV_BSIZE;
672 dg->dg_ntracks = 1; 666 dg->dg_ntracks = 1;
673 // XXX: Ok to hard-code DEV_BSIZE? 667 // XXX: Ok to hard-code DEV_BSIZE?
674 dg->dg_nsectors = 1024 * (1024 / dg->dg_secsize); 668 dg->dg_nsectors = 1024 * (1024 / dg->dg_secsize);
675 dg->dg_ncylinders = dg->dg_secperunit / dg->dg_nsectors; 669 dg->dg_ncylinders = dg->dg_secperunit / dg->dg_nsectors;
676 670
677 bufq_alloc(&sc->sc_dksc.sc_bufq, "fcfs", 0); 671 bufq_alloc(&sc->sc_dksc.sc_bufq, "fcfs", 0);
678 dk_attach(&sc->sc_dksc); 672 dk_attach(&sc->sc_dksc);
679 disk_attach(&sc->sc_dksc.sc_dkdev); 673 disk_attach(&sc->sc_dksc.sc_dkdev);
680 674
681 sc->sc_backend_status = BLKIF_STATE_CONNECTED; 675 sc->sc_backend_status = BLKIF_STATE_CONNECTED;
682 hypervisor_unmask_event(sc->sc_evtchn); 676 hypervisor_unmask_event(sc->sc_evtchn);
683 677
684 format_bytes(buf, sizeof(buf), sc->sc_sectors * sc->sc_secsize); 678 format_bytes(buf, sizeof(buf), sc->sc_sectors * sc->sc_secsize);
685 aprint_normal_dev(sc->sc_dksc.sc_dev, 679 aprint_normal_dev(sc->sc_dksc.sc_dev,
686 "%s, %d bytes/sect x %" PRIu64 " sectors\n", 680 "%s, %d bytes/sect x %" PRIu64 " sectors\n",
687 buf, (int)dg->dg_secsize, sc->sc_xbdsize); 681 buf, (int)dg->dg_secsize, sc->sc_xbdsize);
688 snprintb(buf, sizeof(buf), BLKIF_FEATURE_BITS, 682 snprintb(buf, sizeof(buf), BLKIF_FEATURE_BITS,
689 sc->sc_features); 683 sc->sc_features);
690 aprint_normal_dev(sc->sc_dksc.sc_dev, 684 aprint_normal_dev(sc->sc_dksc.sc_dev,
691 "backend features %s\n", buf); 685 "backend features %s\n", buf);
692 686
693 /* Discover wedges on this disk. */ 687 /* Discover wedges on this disk. */
694 dkwedge_discover(&sc->sc_dksc.sc_dkdev); 688 dkwedge_discover(&sc->sc_dksc.sc_dkdev);
695 689
696 disk_set_info(sc->sc_dksc.sc_dev, &sc->sc_dksc.sc_dkdev, NULL); 690 disk_set_info(sc->sc_dksc.sc_dev, &sc->sc_dksc.sc_dkdev, NULL);
697 691
698 /* the disk should be working now */ 692 /* the disk should be working now */
699 config_pending_decr(sc->sc_dksc.sc_dev); 693 config_pending_decr(sc->sc_dksc.sc_dev);
700 break; 694 break;
701 default: 695 default:
702 panic("bad backend state %d", new_state); 696 panic("bad backend state %d", new_state);
703 } 697 }
704} 698}
705 699
706static void 700static void
707xbd_connect(struct xbd_xenbus_softc *sc) 701xbd_connect(struct xbd_xenbus_softc *sc)
708{ 702{
709 int err; 703 int err;
710 unsigned long long sectors; 704 unsigned long long sectors;
711 705
712 err = xenbus_read_ul(NULL, 706 err = xenbus_read_ul(NULL,
713 sc->sc_xbusd->xbusd_path, "virtual-device", &sc->sc_handle, 10); 707 sc->sc_xbusd->xbusd_path, "virtual-device", &sc->sc_handle, 10);
714 if (err) 708 if (err)
715 panic("%s: can't read number from %s/virtual-device\n",  709 panic("%s: can't read number from %s/virtual-device\n",
716 device_xname(sc->sc_dksc.sc_dev), 710 device_xname(sc->sc_dksc.sc_dev),
717 sc->sc_xbusd->xbusd_otherend); 711 sc->sc_xbusd->xbusd_otherend);
718 err = xenbus_read_ull(NULL, 712 err = xenbus_read_ull(NULL,
719 sc->sc_xbusd->xbusd_otherend, "sectors", &sectors, 10); 713 sc->sc_xbusd->xbusd_otherend, "sectors", &sectors, 10);
720 if (err) 714 if (err)
721 panic("%s: can't read number from %s/sectors\n",  715 panic("%s: can't read number from %s/sectors\n",
722 device_xname(sc->sc_dksc.sc_dev), 716 device_xname(sc->sc_dksc.sc_dev),
723 sc->sc_xbusd->xbusd_otherend); 717 sc->sc_xbusd->xbusd_otherend);
724 sc->sc_sectors = sectors; 718 sc->sc_sectors = sectors;
725 719
726 err = xenbus_read_ul(NULL, 720 err = xenbus_read_ul(NULL,
727 sc->sc_xbusd->xbusd_otherend, "info", &sc->sc_info, 10); 721 sc->sc_xbusd->xbusd_otherend, "info", &sc->sc_info, 10);
728 if (err) 722 if (err)
729 panic("%s: can't read number from %s/info\n",  723 panic("%s: can't read number from %s/info\n",
730 device_xname(sc->sc_dksc.sc_dev), 724 device_xname(sc->sc_dksc.sc_dev),
731 sc->sc_xbusd->xbusd_otherend); 725 sc->sc_xbusd->xbusd_otherend);
732 err = xenbus_read_ul(NULL, 726 err = xenbus_read_ul(NULL,
733 sc->sc_xbusd->xbusd_otherend, "sector-size", &sc->sc_secsize, 10); 727 sc->sc_xbusd->xbusd_otherend, "sector-size", &sc->sc_secsize, 10);
734 if (err) 728 if (err)
735 panic("%s: can't read number from %s/sector-size\n",  729 panic("%s: can't read number from %s/sector-size\n",
736 device_xname(sc->sc_dksc.sc_dev), 730 device_xname(sc->sc_dksc.sc_dev),
737 sc->sc_xbusd->xbusd_otherend); 731 sc->sc_xbusd->xbusd_otherend);
738 732
739 xenbus_switch_state(sc->sc_xbusd, NULL, XenbusStateConnected); 733 xenbus_switch_state(sc->sc_xbusd, NULL, XenbusStateConnected);
740} 734}
741 735
742static void 736static void
743xbd_features(struct xbd_xenbus_softc *sc) 737xbd_features(struct xbd_xenbus_softc *sc)
744{ 738{
745 int err; 739 int err;
746 u_long val; 740 u_long val;
747 741
748 err = xenbus_read_ul(NULL, sc->sc_xbusd->xbusd_otherend, 742 err = xenbus_read_ul(NULL, sc->sc_xbusd->xbusd_otherend,
749 "feature-flush-cache", &val, 10); 743 "feature-flush-cache", &val, 10);
750 if (err) 744 if (err)
751 val = 0; 745 val = 0;
752 if (val > 0) 746 if (val > 0)
753 sc->sc_features |= BLKIF_FEATURE_CACHE_FLUSH; 747 sc->sc_features |= BLKIF_FEATURE_CACHE_FLUSH;
754 748
755 err = xenbus_read_ul(NULL, sc->sc_xbusd->xbusd_otherend, 749 err = xenbus_read_ul(NULL, sc->sc_xbusd->xbusd_otherend,
756 "feature-barrier", &val, 10); 750 "feature-barrier", &val, 10);
757 if (err) 751 if (err)
758 val = 0; 752 val = 0;
759 if (val > 0) 753 if (val > 0)
760 sc->sc_features |= BLKIF_FEATURE_BARRIER; 754 sc->sc_features |= BLKIF_FEATURE_BARRIER;
761 755
762 err = xenbus_read_ul(NULL, sc->sc_xbusd->xbusd_otherend, 756 err = xenbus_read_ul(NULL, sc->sc_xbusd->xbusd_otherend,
763 "feature-persistent", &val, 10); 757 "feature-persistent", &val, 10);
764 if (err) 758 if (err)
765 val = 0; 759 val = 0;
766 if (val > 0) 760 if (val > 0)
767 sc->sc_features |= BLKIF_FEATURE_PERSISTENT; 761 sc->sc_features |= BLKIF_FEATURE_PERSISTENT;
768 762
769 err = xenbus_read_ul(NULL, sc->sc_xbusd->xbusd_otherend, 763 err = xenbus_read_ul(NULL, sc->sc_xbusd->xbusd_otherend,
770 "feature-max-indirect-segments", &val, 10); 764 "feature-max-indirect-segments", &val, 10);
771 if (err) 765 if (err)
772 val = 0; 766 val = 0;
773 if (val > (MAXPHYS >> PAGE_SHIFT)) { 767 if (val > (MAXPHYS >> PAGE_SHIFT)) {
774 /* We can use indirect segments, the limit is big enough */ 768 /* We can use indirect segments, the limit is big enough */
775 sc->sc_features |= BLKIF_FEATURE_INDIRECT; 769 sc->sc_features |= BLKIF_FEATURE_INDIRECT;
776 } 770 }
777} 771}
778 772
779static int 773static int
780xbd_handler(void *arg) 774xbd_handler(void *arg)
781{ 775{
782 struct xbd_xenbus_softc *sc = arg; 776 struct xbd_xenbus_softc *sc = arg;
783 struct buf *bp; 777 struct buf *bp;
784 RING_IDX resp_prod, i; 778 RING_IDX resp_prod, i;
785 int more_to_do; 779 int more_to_do;
786 int seg; 780 int seg;
787 grant_ref_t gntref; 781 grant_ref_t gntref;
788 782
789 DPRINTF(("xbd_handler(%s)\n", device_xname(sc->sc_dksc.sc_dev))); 783 DPRINTF(("xbd_handler(%s)\n", device_xname(sc->sc_dksc.sc_dev)));
790 784
791 if (__predict_false(sc->sc_backend_status != BLKIF_STATE_CONNECTED)) 785 if (__predict_false(sc->sc_backend_status != BLKIF_STATE_CONNECTED))
792 return 0; 786 return 0;
793 787
794 mutex_enter(&sc->sc_lock); 788 mutex_enter(&sc->sc_lock);
795again: 789again:
796 resp_prod = sc->sc_ring.sring->rsp_prod; 790 resp_prod = sc->sc_ring.sring->rsp_prod;
797 xen_rmb(); /* ensure we see replies up to resp_prod */ 791 xen_rmb(); /* ensure we see replies up to resp_prod */
798 for (i = sc->sc_ring.rsp_cons; i != resp_prod; i++) { 792 for (i = sc->sc_ring.rsp_cons; i != resp_prod; i++) {
799 blkif_response_t *rep = RING_GET_RESPONSE(&sc->sc_ring, i); 793 blkif_response_t *rep = RING_GET_RESPONSE(&sc->sc_ring, i);
800 struct xbd_req *xbdreq = &sc->sc_reqs[rep->id]; 794 struct xbd_req *xbdreq = &sc->sc_reqs[rep->id];
801 795
802 if (rep->operation == BLKIF_OP_FLUSH_DISKCACHE) { 796 if (rep->operation == BLKIF_OP_FLUSH_DISKCACHE) {
803 KASSERT(xbdreq->req_bp == NULL); 797 KASSERT(xbdreq->req_bp == NULL);
804 xbdreq->req_sync.s_error = rep->status; 798 xbdreq->req_sync.s_error = rep->status;
805 xbdreq->req_sync.s_done = 1; 799 xbdreq->req_sync.s_done = 1;
806 cv_broadcast(&sc->sc_cache_flush_cv); 800 cv_broadcast(&sc->sc_cache_flush_cv);
807 /* caller will free the req */ 801 /* caller will free the req */
808 continue; 802 continue;
809 } 803 }
810 804
811 if (rep->operation != BLKIF_OP_READ && 805 if (rep->operation != BLKIF_OP_READ &&
812 rep->operation != BLKIF_OP_WRITE) { 806 rep->operation != BLKIF_OP_WRITE) {
813 aprint_error_dev(sc->sc_dksc.sc_dev, 807 aprint_error_dev(sc->sc_dksc.sc_dev,
814 "bad operation %d from backend\n", rep->operation); 808 "bad operation %d from backend\n", rep->operation);
815 continue; 809 continue;
816 } 810 }
817 811
818 bp = xbdreq->req_bp; 812 bp = xbdreq->req_bp;
819 KASSERT(bp != NULL && bp->b_data != NULL); 813 KASSERT(bp != NULL && bp->b_data != NULL);
820 DPRINTF(("%s(%p): b_bcount = %ld\n", __func__, 814 DPRINTF(("%s(%p): b_bcount = %ld\n", __func__,
821 bp, (long)bp->b_bcount)); 815 bp, (long)bp->b_bcount));
822 816
823 if (bp->b_error != 0 || rep->status != BLKIF_RSP_OKAY) { 817 if (bp->b_error != 0 || rep->status != BLKIF_RSP_OKAY) {
824 bp->b_error = EIO; 818 bp->b_error = EIO;
825 bp->b_resid = bp->b_bcount; 819 bp->b_resid = bp->b_bcount;
826 } 820 }
827 821
828 if (xbdreq->req_parent) { 822 if (xbdreq->req_parent) {
829 struct xbd_req *req_parent = xbdreq->req_parent; 823 struct xbd_req *req_parent = xbdreq->req_parent;
830 824
831 /* Unhook and recycle child */ 825 /* Unhook and recycle child */
832 xbdreq->req_parent = NULL; 826 xbdreq->req_parent = NULL;
833 req_parent->req_child = NULL; 827 req_parent->req_child = NULL;
834 SLIST_INSERT_HEAD(&sc->sc_xbdreq_head, xbdreq, 828 SLIST_INSERT_HEAD(&sc->sc_xbdreq_head, xbdreq,
835 req_next); 829 req_next);
836 830
837 if (!req_parent->req_parent_done) { 831 if (!req_parent->req_parent_done) {
838 /* Finished before parent, nothig else to do */ 832 /* Finished before parent, nothig else to do */
839 continue; 833 continue;
840 } 834 }
841 835
842 /* Must do the cleanup now */ 836 /* Must do the cleanup now */
843 xbdreq = req_parent; 837 xbdreq = req_parent;
844 } 838 }
845 if (xbdreq->req_child) { 839 if (xbdreq->req_child) {
846 /* Finished before child, child will cleanup */ 840 /* Finished before child, child will cleanup */
847 xbdreq->req_parent_done = true; 841 xbdreq->req_parent_done = true;
848 continue; 842 continue;
849 } 843 }
850 844
851 if (bp->b_error == 0) 845 if (bp->b_error == 0)
852 bp->b_resid = 0; 846 bp->b_resid = 0;
853 847
854 for (seg = 0; seg < xbdreq->req_dmamap->dm_nsegs; seg++) { 848 for (seg = 0; seg < xbdreq->req_dmamap->dm_nsegs; seg++) {
855 /* 849 /*
856 * We are not allowing persistent mappings, so 850 * We are not allowing persistent mappings, so
857 * expect the backend to release the grant 851 * expect the backend to release the grant
858 * immediately. 852 * immediately.
859 */ 853 */
860 if (xbdreq->req_indirect) { 854 if (xbdreq->req_indirect) {
861 gntref = 855 gntref =
862 xbdreq->req_indirect->in_addr[seg].gref; 856 xbdreq->req_indirect->in_addr[seg].gref;
863 } else 857 } else
864 gntref = xbdreq->req_gntref[seg]; 858 gntref = xbdreq->req_gntref[seg];
865 KASSERT(xengnt_status(gntref) == 0); 859 KASSERT(xengnt_status(gntref) == 0);
866 xengnt_revoke_access(gntref); 860 xengnt_revoke_access(gntref);
867 } 861 }
868 862
869 bus_dmamap_unload(sc->sc_xbusd->xbusd_dmat, xbdreq->req_dmamap); 863 bus_dmamap_unload(sc->sc_xbusd->xbusd_dmat, xbdreq->req_dmamap);
870 864
871 if (__predict_false(bp->b_data != xbdreq->req_data)) 865 if (__predict_false(bp->b_data != xbdreq->req_data))
872 xbd_unmap_align(sc, xbdreq, true); 866 xbd_unmap_align(sc, xbdreq, true);
873 xbdreq->req_bp = xbdreq->req_data = NULL; 867 xbdreq->req_bp = xbdreq->req_data = NULL;
874 868
875 dk_done(&sc->sc_dksc, bp); 869 dk_done(&sc->sc_dksc, bp);
876 870
877 if (xbdreq->req_indirect) { 871 if (xbdreq->req_indirect) {
878 /* No persistent mappings, so check that 872 /* No persistent mappings, so check that
879 * backend unmapped the indirect segment grant too. 873 * backend unmapped the indirect segment grant too.
880 */ 874 */
881 KASSERT(xengnt_status(xbdreq->req_indirect->in_gntref) 875 KASSERT(xengnt_status(xbdreq->req_indirect->in_gntref)
882 == 0); 876 == 0);
883 SLIST_INSERT_HEAD(&sc->sc_indirect_head, 877 SLIST_INSERT_HEAD(&sc->sc_indirect_head,
884 xbdreq->req_indirect, in_next); 878 xbdreq->req_indirect, in_next);
885 xbdreq->req_indirect = NULL; 879 xbdreq->req_indirect = NULL;
886 } 880 }
887 SLIST_INSERT_HEAD(&sc->sc_xbdreq_head, xbdreq, req_next); 881 SLIST_INSERT_HEAD(&sc->sc_xbdreq_head, xbdreq, req_next);
888 } 882 }
889 883
890 xen_rmb(); 884 xen_rmb();
891 sc->sc_ring.rsp_cons = i; 885 sc->sc_ring.rsp_cons = i;
892 886
893 RING_FINAL_CHECK_FOR_RESPONSES(&sc->sc_ring, more_to_do); 887 RING_FINAL_CHECK_FOR_RESPONSES(&sc->sc_ring, more_to_do);
894 if (more_to_do) 888 if (more_to_do)
895 goto again; 889 goto again;
896 890
897 cv_signal(&sc->sc_req_cv); 891 cv_signal(&sc->sc_req_cv);
898 mutex_exit(&sc->sc_lock); 892 mutex_exit(&sc->sc_lock);
899 893
900 dk_start(&sc->sc_dksc, NULL); 894 dk_start(&sc->sc_dksc, NULL);
901 895
902 return 1; 896 return 1;
903} 897}
904 898
905static void 899static void
906xbdminphys(struct buf *bp) 900xbdminphys(struct buf *bp)
907{ 901{
908 if (bp->b_bcount > XBD_XFER_LIMIT) { 902 if (bp->b_bcount > XBD_XFER_LIMIT) {
909 bp->b_bcount = XBD_XFER_LIMIT; 903 bp->b_bcount = XBD_XFER_LIMIT;
910 } 904 }
911 minphys(bp); 905 minphys(bp);
912} 906}
913 907
914static void 908static void
915xbd_iosize(device_t dev, int *maxxfer) 909xbd_iosize(device_t dev, int *maxxfer)
916{ 910{
917 /* 911 /*
918 * Always restrict dumps to XBD_MAX_XFER to avoid indirect segments, 912 * Always restrict dumps to XBD_MAX_XFER to avoid indirect segments,
919 * so that it uses as little memory as possible.  913 * so that it uses as little memory as possible.
920 */ 914 */
921 if (*maxxfer > XBD_MAX_XFER) 915 if (*maxxfer > XBD_MAX_XFER)
922 *maxxfer = XBD_MAX_XFER; 916 *maxxfer = XBD_MAX_XFER;
923} 917}
924 918
925int 919int
926xbdopen(dev_t dev, int flags, int fmt, struct lwp *l) 920xbdopen(dev_t dev, int flags, int fmt, struct lwp *l)
927{ 921{
928 struct xbd_xenbus_softc *sc; 922 struct xbd_xenbus_softc *sc;
929 923
930 sc = device_lookup_private(&xbd_cd, DISKUNIT(dev)); 924 sc = device_lookup_private(&xbd_cd, DISKUNIT(dev));
931 if (sc == NULL) 925 if (sc == NULL)
932 return (ENXIO); 926 return (ENXIO);
933 if ((flags & FWRITE) && (sc->sc_info & VDISK_READONLY)) 927 if ((flags & FWRITE) && (sc->sc_info & VDISK_READONLY))
934 return EROFS; 928 return EROFS;
935 929
936 DPRINTF(("xbdopen(0x%04x, %d)\n", dev, flags)); 930 DPRINTF(("xbdopen(%" PRIx64 ", %d)\n", dev, flags));
937 return dk_open(&sc->sc_dksc, dev, flags, fmt, l); 931 return dk_open(&sc->sc_dksc, dev, flags, fmt, l);
938} 932}
939 933
940int 934int
941xbdclose(dev_t dev, int flags, int fmt, struct lwp *l) 935xbdclose(dev_t dev, int flags, int fmt, struct lwp *l)
942{ 936{
943 struct xbd_xenbus_softc *sc; 937 struct xbd_xenbus_softc *sc;
944 938
945 sc = device_lookup_private(&xbd_cd, DISKUNIT(dev)); 939 sc = device_lookup_private(&xbd_cd, DISKUNIT(dev));
946 940
947 DPRINTF(("xbdclose(%d, %d)\n", dev, flags)); 941 DPRINTF(("xbdclose(%" PRIx64 ", %d)\n", dev, flags));
948 return dk_close(&sc->sc_dksc, dev, flags, fmt, l); 942 return dk_close(&sc->sc_dksc, dev, flags, fmt, l);
949} 943}
950 944
951void 945void
952xbdstrategy(struct buf *bp) 946xbdstrategy(struct buf *bp)
953{ 947{
954 struct xbd_xenbus_softc *sc; 948 struct xbd_xenbus_softc *sc;
955 949
956 sc = device_lookup_private(&xbd_cd, DISKUNIT(bp->b_dev)); 950 sc = device_lookup_private(&xbd_cd, DISKUNIT(bp->b_dev));
957 951
958 DPRINTF(("xbdstrategy(%p): b_bcount = %ld\n", bp, 952 DPRINTF(("xbdstrategy(%p): b_bcount = %ld\n", bp,
959 (long)bp->b_bcount)); 953 (long)bp->b_bcount));
960 954
961 if (sc == NULL || sc->sc_shutdown != BLKIF_SHUTDOWN_RUN) { 955 if (sc == NULL || sc->sc_shutdown != BLKIF_SHUTDOWN_RUN) {
962 bp->b_error = EIO; 956 bp->b_error = EIO;
963 biodone(bp); 957 biodone(bp);
964 return; 958 return;
965 } 959 }
966 if (__predict_false((sc->sc_info & VDISK_READONLY) && 960 if (__predict_false((sc->sc_info & VDISK_READONLY) &&
967 (bp->b_flags & B_READ) == 0)) { 961 (bp->b_flags & B_READ) == 0)) {
968 bp->b_error = EROFS; 962 bp->b_error = EROFS;
969 biodone(bp); 963 biodone(bp);
970 return; 964 return;
971 } 965 }
972 966
973 dk_strategy(&sc->sc_dksc, bp); 967 dk_strategy(&sc->sc_dksc, bp);
974 return; 968 return;
975} 969}
976 970
977int 971int
978xbdsize(dev_t dev) 972xbdsize(dev_t dev)
979{ 973{
980 struct xbd_xenbus_softc *sc; 974 struct xbd_xenbus_softc *sc;
981 975
982 DPRINTF(("xbdsize(%d)\n", dev)); 976 DPRINTF(("xbdsize(%" PRIx64 ")\n", dev));
983 977
984 sc = device_lookup_private(&xbd_cd, DISKUNIT(dev)); 978 sc = device_lookup_private(&xbd_cd, DISKUNIT(dev));
985 if (sc == NULL || sc->sc_shutdown != BLKIF_SHUTDOWN_RUN) 979 if (sc == NULL || sc->sc_shutdown != BLKIF_SHUTDOWN_RUN)
986 return -1; 980 return -1;
987 return dk_size(&sc->sc_dksc, dev); 981 return dk_size(&sc->sc_dksc, dev);
988} 982}
989 983
990int 984int
991xbdread(dev_t dev, struct uio *uio, int flags) 985xbdread(dev_t dev, struct uio *uio, int flags)
992{ 986{
993 struct xbd_xenbus_softc *sc =  987 struct xbd_xenbus_softc *sc =
994 device_lookup_private(&xbd_cd, DISKUNIT(dev)); 988 device_lookup_private(&xbd_cd, DISKUNIT(dev));
995 struct dk_softc *dksc = &sc->sc_dksc; 989 struct dk_softc *dksc = &sc->sc_dksc;
996 990
997 if (!DK_ATTACHED(dksc)) 991 if (!DK_ATTACHED(dksc))
998 return ENXIO; 992 return ENXIO;
999 return physio(xbdstrategy, NULL, dev, B_READ, xbdminphys, uio); 993 return physio(xbdstrategy, NULL, dev, B_READ, xbdminphys, uio);
1000} 994}
1001 995
1002int 996int
1003xbdwrite(dev_t dev, struct uio *uio, int flags) 997xbdwrite(dev_t dev, struct uio *uio, int flags)
1004{ 998{
1005 struct xbd_xenbus_softc *sc = 999 struct xbd_xenbus_softc *sc =
1006 device_lookup_private(&xbd_cd, DISKUNIT(dev)); 1000 device_lookup_private(&xbd_cd, DISKUNIT(dev));
1007 struct dk_softc *dksc = &sc->sc_dksc; 1001 struct dk_softc *dksc = &sc->sc_dksc;
1008 1002
1009 if (!DK_ATTACHED(dksc)) 1003 if (!DK_ATTACHED(dksc))
1010 return ENXIO; 1004 return ENXIO;
1011 if (__predict_false(sc->sc_info & VDISK_READONLY)) 1005 if (__predict_false(sc->sc_info & VDISK_READONLY))
1012 return EROFS; 1006 return EROFS;
1013 return physio(xbdstrategy, NULL, dev, B_WRITE, xbdminphys, uio); 1007 return physio(xbdstrategy, NULL, dev, B_WRITE, xbdminphys, uio);
1014} 1008}
1015 1009
1016int 1010int
1017xbdioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) 1011xbdioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
1018{ 1012{
1019 struct xbd_xenbus_softc *sc = 1013 struct xbd_xenbus_softc *sc =
1020 device_lookup_private(&xbd_cd, DISKUNIT(dev)); 1014 device_lookup_private(&xbd_cd, DISKUNIT(dev));
1021 struct dk_softc *dksc; 1015 struct dk_softc *dksc;
1022 int error; 1016 int error;
1023 struct xbd_req *xbdreq; 1017 struct xbd_req *xbdreq;
1024 blkif_request_t *req; 1018 blkif_request_t *req;
1025 int notify; 1019 int notify;
1026 1020
1027 DPRINTF(("xbdioctl(%d, %08lx, %p, %d, %p)\n", 1021 DPRINTF(("xbdioctl(%" PRIx64 ", %08lx, %p, %d, %p)\n",
1028 dev, cmd, data, flag, l)); 1022 dev, cmd, data, flag, l));
1029 dksc = &sc->sc_dksc; 1023 dksc = &sc->sc_dksc;
1030 1024
1031 switch (cmd) { 1025 switch (cmd) {
1032 case DIOCGCACHE: 1026 case DIOCGCACHE:
1033 { 1027 {
1034 /* Assume there is write cache if cache-flush is supported */ 1028 /* Assume there is write cache if cache-flush is supported */
1035 int *bitsp = (int *)data; 1029 int *bitsp = (int *)data;
1036 *bitsp = 0; 1030 *bitsp = 0;
1037 if (sc->sc_features & BLKIF_FEATURE_CACHE_FLUSH) 1031 if (sc->sc_features & BLKIF_FEATURE_CACHE_FLUSH)
1038 *bitsp |= DKCACHE_WRITE; 1032 *bitsp |= DKCACHE_WRITE;
1039 error = 0; 1033 error = 0;
1040 break; 1034 break;
1041 } 1035 }
1042 case DIOCCACHESYNC: 1036 case DIOCCACHESYNC:
1043 if ((sc->sc_features & BLKIF_FEATURE_CACHE_FLUSH) == 0) 1037 if ((sc->sc_features & BLKIF_FEATURE_CACHE_FLUSH) == 0)
1044 return EOPNOTSUPP; 1038 return EOPNOTSUPP;
1045 1039
1046 mutex_enter(&sc->sc_lock); 1040 mutex_enter(&sc->sc_lock);
1047 while ((xbdreq = SLIST_FIRST(&sc->sc_xbdreq_head)) == NULL) 1041 while ((xbdreq = SLIST_FIRST(&sc->sc_xbdreq_head)) == NULL)
1048 cv_wait(&sc->sc_req_cv, &sc->sc_lock); 1042 cv_wait(&sc->sc_req_cv, &sc->sc_lock);
1049 1043
1050 SLIST_REMOVE_HEAD(&sc->sc_xbdreq_head, req_next); 1044 SLIST_REMOVE_HEAD(&sc->sc_xbdreq_head, req_next);
1051 req = RING_GET_REQUEST(&sc->sc_ring, 1045 req = RING_GET_REQUEST(&sc->sc_ring,
1052 sc->sc_ring.req_prod_pvt); 1046 sc->sc_ring.req_prod_pvt);
1053 req->id = xbdreq->req_id; 1047 req->id = xbdreq->req_id;
1054 req->operation = BLKIF_OP_FLUSH_DISKCACHE; 1048 req->operation = BLKIF_OP_FLUSH_DISKCACHE;
1055 req->handle = sc->sc_handle; 1049 req->handle = sc->sc_handle;
1056 xbdreq->req_sync.s_done = 0; 1050 xbdreq->req_sync.s_done = 0;
1057 sc->sc_ring.req_prod_pvt++; 1051 sc->sc_ring.req_prod_pvt++;
1058 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&sc->sc_ring, notify); 1052 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&sc->sc_ring, notify);
1059 if (notify) 1053 if (notify)
1060 hypervisor_notify_via_evtchn(sc->sc_evtchn); 1054 hypervisor_notify_via_evtchn(sc->sc_evtchn);
1061 /* request sent, now wait for completion */ 1055 /* request sent, now wait for completion */
1062 while (xbdreq->req_sync.s_done == 0) 1056 while (xbdreq->req_sync.s_done == 0)
1063 cv_wait(&sc->sc_cache_flush_cv, &sc->sc_lock); 1057 cv_wait(&sc->sc_cache_flush_cv, &sc->sc_lock);
1064 1058
1065 if (xbdreq->req_sync.s_error == BLKIF_RSP_EOPNOTSUPP) 1059 if (xbdreq->req_sync.s_error == BLKIF_RSP_EOPNOTSUPP)
1066 error = EOPNOTSUPP; 1060 error = EOPNOTSUPP;
1067 else if (xbdreq->req_sync.s_error == BLKIF_RSP_OKAY) 1061 else if (xbdreq->req_sync.s_error == BLKIF_RSP_OKAY)
1068 error = 0; 1062 error = 0;
1069 else 1063 else
1070 error = EIO; 1064 error = EIO;
1071 SLIST_INSERT_HEAD(&sc->sc_xbdreq_head, xbdreq, req_next); 1065 SLIST_INSERT_HEAD(&sc->sc_xbdreq_head, xbdreq, req_next);
1072 cv_signal(&sc->sc_req_cv); 1066 cv_signal(&sc->sc_req_cv);
1073 mutex_exit(&sc->sc_lock); 1067 mutex_exit(&sc->sc_lock);
1074 1068
1075 /* Restart I/O if it was waiting for req */ 1069 /* Restart I/O if it was waiting for req */
1076 dk_start(&sc->sc_dksc, NULL); 1070 dk_start(&sc->sc_dksc, NULL);
1077 break; 1071 break;
1078 1072
1079 default: 1073 default:
1080 error = dk_ioctl(dksc, dev, cmd, data, flag, l); 1074 error = dk_ioctl(dksc, dev, cmd, data, flag, l);
1081 break; 1075 break;
1082 } 1076 }
1083 1077
1084 return error; 1078 return error;
1085} 1079}
1086 1080
1087int 1081int
1088xbddump(dev_t dev, daddr_t blkno, void *va, size_t size) 1082xbddump(dev_t dev, daddr_t blkno, void *va, size_t size)
1089{ 1083{
1090 struct xbd_xenbus_softc *sc; 1084 struct xbd_xenbus_softc *sc;
1091 1085
1092 sc = device_lookup_private(&xbd_cd, DISKUNIT(dev)); 1086 sc = device_lookup_private(&xbd_cd, DISKUNIT(dev));
1093 if (sc == NULL) 1087 if (sc == NULL)
1094 return (ENXIO); 1088 return (ENXIO);
1095 1089
1096 DPRINTF(("xbddump(%d, %" PRId64 ", %p, %lu)\n", dev, blkno, va, 1090 DPRINTF(("xbddump(%" PRIx64 ", %" PRId64 ", %p, %lu)\n", dev, blkno, va,
1097 (unsigned long)size)); 1091 (unsigned long)size));
1098 return dk_dump(&sc->sc_dksc, dev, blkno, va, size, 0); 1092 return dk_dump(&sc->sc_dksc, dev, blkno, va, size, 0);
1099} 1093}
1100 1094
1101static int 1095static int
1102xbd_diskstart(device_t self, struct buf *bp) 1096xbd_diskstart(device_t self, struct buf *bp)
1103{ 1097{
1104 struct xbd_xenbus_softc *sc = device_private(self); 1098 struct xbd_xenbus_softc *sc = device_private(self);
1105 struct xbd_req *xbdreq; 1099 struct xbd_req *xbdreq;
1106 int error = 0; 1100 int error = 0;
1107 int notify; 1101 int notify;
1108 1102
1109 KASSERT(bp->b_bcount <= MAXPHYS); 1103 KASSERT(bp->b_bcount <= MAXPHYS);
1110 1104
1111 DPRINTF(("xbd_diskstart(%p): b_bcount = %ld\n", 1105 DPRINTF(("xbd_diskstart(%p): b_bcount = %ld\n",
1112 bp, (long)bp->b_bcount)); 1106 bp, (long)bp->b_bcount));
1113 1107
1114 mutex_enter(&sc->sc_lock); 1108 mutex_enter(&sc->sc_lock);
1115 1109
1116 if (sc->sc_shutdown != BLKIF_SHUTDOWN_RUN) { 1110 if (sc->sc_shutdown != BLKIF_SHUTDOWN_RUN) {
1117 error = EIO; 1111 error = EIO;
1118 goto out; 1112 goto out;
1119 } 1113 }
1120 1114
1121 if (bp->b_rawblkno < 0 || bp->b_rawblkno > sc->sc_xbdsize) { 1115 if (bp->b_rawblkno < 0 || bp->b_rawblkno > sc->sc_xbdsize) {
1122 /* invalid block number */ 1116 /* invalid block number */
1123 error = EINVAL; 1117 error = EINVAL;
1124 goto out; 1118 goto out;
1125 } 1119 }
1126 1120
1127 if (__predict_false( 1121 if (__predict_false(
1128 sc->sc_backend_status == BLKIF_STATE_SUSPENDED)) { 1122 sc->sc_backend_status == BLKIF_STATE_SUSPENDED)) {
1129 /* device is suspended, do not consume buffer */ 1123 /* device is suspended, do not consume buffer */
1130 DPRINTF(("%s: (xbd_diskstart) device suspended\n", 1124 DPRINTF(("%s: (xbd_diskstart) device suspended\n",
1131 sc->sc_dksc.sc_xname)); 1125 sc->sc_dksc.sc_xname));
1132 error = EAGAIN; 1126 error = EAGAIN;
1133 goto out; 1127 goto out;
1134 } 1128 }
1135 1129
1136 xbdreq = SLIST_FIRST(&sc->sc_xbdreq_head); 1130 xbdreq = SLIST_FIRST(&sc->sc_xbdreq_head);
1137 if (__predict_false(xbdreq == NULL)) { 1131 if (__predict_false(xbdreq == NULL)) {
1138 sc->sc_cnt_queue_full.ev_count++; 1132 sc->sc_cnt_queue_full.ev_count++;
1139 DPRINTF(("xbd_diskstart: no req\n")); 1133 DPRINTF(("xbd_diskstart: no req\n"));
1140 error = EAGAIN; 1134 error = EAGAIN;
1141 goto out; 1135 goto out;
1142 } 1136 }
1143 1137
1144 if ((sc->sc_features & BLKIF_FEATURE_INDIRECT) == 0 1138 if ((sc->sc_features & BLKIF_FEATURE_INDIRECT) == 0
1145 && bp->b_bcount > XBD_MAX_CHUNK) { 1139 && bp->b_bcount > XBD_MAX_CHUNK) {
1146 if (!SLIST_NEXT(xbdreq, req_next)) { 1140 if (!SLIST_NEXT(xbdreq, req_next)) {
1147 DPRINTF(("%s: need extra req\n", __func__)); 1141 DPRINTF(("%s: need extra req\n", __func__));
1148 error = EAGAIN; 1142 error = EAGAIN;
1149 goto out; 1143 goto out;
1150 } 1144 }
1151 } 1145 }
1152 1146
1153 bp->b_resid = bp->b_bcount; 1147 bp->b_resid = bp->b_bcount;
1154 xbdreq->req_bp = bp; 1148 xbdreq->req_bp = bp;
1155 xbdreq->req_data = bp->b_data; 1149 xbdreq->req_data = bp->b_data;
1156 if (__predict_false((vaddr_t)bp->b_data & (XEN_BSIZE - 1))) { 1150 if (__predict_false((vaddr_t)bp->b_data & (XEN_BSIZE - 1))) {
1157 if (__predict_false(xbd_map_align(sc, xbdreq) != 0)) { 1151 if (__predict_false(xbd_map_align(sc, xbdreq) != 0)) {
1158 DPRINTF(("xbd_diskstart: no align\n")); 1152 DPRINTF(("xbd_diskstart: no align\n"));
1159 error = EAGAIN; 1153 error = EAGAIN;
1160 goto out; 1154 goto out;
1161 } 1155 }
1162 } 1156 }
1163 1157
1164 if (__predict_false(bus_dmamap_load(sc->sc_xbusd->xbusd_dmat, 1158 if (__predict_false(bus_dmamap_load(sc->sc_xbusd->xbusd_dmat,
1165 xbdreq->req_dmamap, xbdreq->req_data, bp->b_bcount, NULL, 1159 xbdreq->req_dmamap, xbdreq->req_data, bp->b_bcount, NULL,
1166 BUS_DMA_NOWAIT) != 0)) { 1160 BUS_DMA_NOWAIT) != 0)) {
1167 printf("%s: %s: bus_dmamap_load failed\n", 1161 printf("%s: %s: bus_dmamap_load failed\n",
1168 device_xname(sc->sc_dksc.sc_dev), __func__); 1162 device_xname(sc->sc_dksc.sc_dev), __func__);
1169 if (__predict_false(bp->b_data != xbdreq->req_data)) 1163 if (__predict_false(bp->b_data != xbdreq->req_data))
1170 xbd_unmap_align(sc, xbdreq, false); 1164 xbd_unmap_align(sc, xbdreq, false);
1171 error = EINVAL; 1165 error = EINVAL;
1172 goto out; 1166 goto out;
1173 } 1167 }
1174 1168
1175 for (int seg = 0; seg < xbdreq->req_dmamap->dm_nsegs; seg++) { 1169 for (int seg = 0; seg < xbdreq->req_dmamap->dm_nsegs; seg++) {
1176 KASSERT(seg < __arraycount(xbdreq->req_gntref)); 1170 KASSERT(seg < __arraycount(xbdreq->req_gntref));
1177 1171
1178 paddr_t ma = xbdreq->req_dmamap->dm_segs[seg].ds_addr; 1172 paddr_t ma = xbdreq->req_dmamap->dm_segs[seg].ds_addr;
1179 if (__predict_false(xengnt_grant_access( 1173 if (__predict_false(xengnt_grant_access(
1180 sc->sc_xbusd->xbusd_otherend_id, 1174 sc->sc_xbusd->xbusd_otherend_id,
1181 (ma & ~PAGE_MASK), (bp->b_flags & B_READ) == 0, 1175 (ma & ~PAGE_MASK), (bp->b_flags & B_READ) == 0,
1182 &xbdreq->req_gntref[seg]))) { 1176 &xbdreq->req_gntref[seg]))) {
1183 printf("%s: %s: xengnt_grant_access failed\n", 1177 printf("%s: %s: xengnt_grant_access failed\n",
1184 device_xname(sc->sc_dksc.sc_dev), __func__); 1178 device_xname(sc->sc_dksc.sc_dev), __func__);
1185 if (seg > 0) { 1179 if (seg > 0) {
1186 for (; --seg >= 0; ) { 1180 for (; --seg >= 0; ) {
1187 xengnt_revoke_access( 1181 xengnt_revoke_access(
1188 xbdreq->req_gntref[seg]); 1182 xbdreq->req_gntref[seg]);
1189 } 1183 }
1190 } 1184 }
1191 bus_dmamap_unload(sc->sc_xbusd->xbusd_dmat, 1185 bus_dmamap_unload(sc->sc_xbusd->xbusd_dmat,
1192 xbdreq->req_dmamap); 1186 xbdreq->req_dmamap);
1193 if (__predict_false(bp->b_data != xbdreq->req_data)) 1187 if (__predict_false(bp->b_data != xbdreq->req_data))
1194 xbd_unmap_align(sc, xbdreq, false); 1188 xbd_unmap_align(sc, xbdreq, false);
1195 error = EAGAIN; 1189 error = EAGAIN;
1196 goto out; 1190 goto out;
1197 } 1191 }
1198 } 1192 }
1199 1193
1200 KASSERT(xbdreq->req_parent == NULL); 1194 KASSERT(xbdreq->req_parent == NULL);
1201 KASSERT(xbdreq->req_child == NULL); 1195 KASSERT(xbdreq->req_child == NULL);
1202 1196
1203 /* We are now committed to the transfer */ 1197 /* We are now committed to the transfer */
1204 SLIST_REMOVE_HEAD(&sc->sc_xbdreq_head, req_next); 1198 SLIST_REMOVE_HEAD(&sc->sc_xbdreq_head, req_next);
1205 1199
1206 if ((sc->sc_features & BLKIF_FEATURE_INDIRECT) != 0 && 1200 if ((sc->sc_features & BLKIF_FEATURE_INDIRECT) != 0 &&
1207 bp->b_bcount > XBD_MAX_CHUNK) { 1201 bp->b_bcount > XBD_MAX_CHUNK) {
1208 xbd_diskstart_submit_indirect(sc, xbdreq, bp); 1202 xbd_diskstart_submit_indirect(sc, xbdreq, bp);
1209 goto push; 1203 goto push;
1210 } 1204 }
1211 1205
1212 xbd_diskstart_submit(sc, xbdreq->req_id, 1206 xbd_diskstart_submit(sc, xbdreq->req_id,
1213 bp, 0, xbdreq->req_dmamap, xbdreq->req_gntref); 1207 bp, 0, xbdreq->req_dmamap, xbdreq->req_gntref);
1214 1208
1215 if (bp->b_bcount > XBD_MAX_CHUNK) { 1209 if (bp->b_bcount > XBD_MAX_CHUNK) {
1216 struct xbd_req *xbdreq2 = SLIST_FIRST(&sc->sc_xbdreq_head); 1210 struct xbd_req *xbdreq2 = SLIST_FIRST(&sc->sc_xbdreq_head);
1217 KASSERT(xbdreq2 != NULL); /* Checked earlier */ 1211 KASSERT(xbdreq2 != NULL); /* Checked earlier */
1218 SLIST_REMOVE_HEAD(&sc->sc_xbdreq_head, req_next); 1212 SLIST_REMOVE_HEAD(&sc->sc_xbdreq_head, req_next);
1219 xbdreq->req_child = xbdreq2; 1213 xbdreq->req_child = xbdreq2;
1220 xbdreq->req_parent_done = false; 1214 xbdreq->req_parent_done = false;
1221 xbdreq2->req_parent = xbdreq; 1215 xbdreq2->req_parent = xbdreq;
1222 xbdreq2->req_bp = bp; 1216 xbdreq2->req_bp = bp;
1223 xbdreq2->req_data = NULL; 1217 xbdreq2->req_data = NULL;
1224 xbd_diskstart_submit(sc, xbdreq2->req_id, 1218 xbd_diskstart_submit(sc, xbdreq2->req_id,
1225 bp, XBD_MAX_CHUNK, xbdreq->req_dmamap, 1219 bp, XBD_MAX_CHUNK, xbdreq->req_dmamap,
1226 xbdreq->req_gntref); 1220 xbdreq->req_gntref);
1227 } 1221 }
1228 1222
1229push: 1223push:
1230 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&sc->sc_ring, notify); 1224 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&sc->sc_ring, notify);
1231 if (notify) 1225 if (notify)
1232 hypervisor_notify_via_evtchn(sc->sc_evtchn); 1226 hypervisor_notify_via_evtchn(sc->sc_evtchn);
1233out: 1227out:
1234 mutex_exit(&sc->sc_lock); 1228 mutex_exit(&sc->sc_lock);
1235 return error; 1229 return error;
1236} 1230}
1237 1231
1238static void 1232static void
1239xbd_diskstart_submit(struct xbd_xenbus_softc *sc, 1233xbd_diskstart_submit(struct xbd_xenbus_softc *sc,
1240 int req_id, struct buf *bp, int start, bus_dmamap_t dmamap, 1234 int req_id, struct buf *bp, int start, bus_dmamap_t dmamap,
1241 grant_ref_t *gntref) 1235 grant_ref_t *gntref)
1242{ 1236{
1243 blkif_request_t *req; 1237 blkif_request_t *req;
1244 paddr_t ma; 1238 paddr_t ma;
1245 int nsects, nbytes, dmaseg, first_sect, size, segidx = 0; 1239 int nsects, nbytes, dmaseg, first_sect, size, segidx = 0;
1246 struct blkif_request_segment *reqseg; 1240 struct blkif_request_segment *reqseg;
1247 1241
1248 KASSERT(mutex_owned(&sc->sc_lock)); 1242 KASSERT(mutex_owned(&sc->sc_lock));
1249 1243
1250 req = RING_GET_REQUEST(&sc->sc_ring, sc->sc_ring.req_prod_pvt); 1244 req = RING_GET_REQUEST(&sc->sc_ring, sc->sc_ring.req_prod_pvt);
1251 req->id = req_id; 1245 req->id = req_id;
1252 req->operation = 1246 req->operation =
1253 bp->b_flags & B_READ ? BLKIF_OP_READ : BLKIF_OP_WRITE; 1247 bp->b_flags & B_READ ? BLKIF_OP_READ : BLKIF_OP_WRITE;
1254 req->sector_number = bp->b_rawblkno + (start >> XEN_BSHIFT); 1248 req->sector_number = bp->b_rawblkno + (start >> XEN_BSHIFT);
1255 req->handle = sc->sc_handle; 1249 req->handle = sc->sc_handle;
1256 1250
1257 size = uimin(bp->b_bcount - start, XBD_MAX_CHUNK);  1251 size = uimin(bp->b_bcount - start, XBD_MAX_CHUNK);
1258 for (dmaseg = 0; dmaseg < dmamap->dm_nsegs && size > 0; dmaseg++) { 1252 for (dmaseg = 0; dmaseg < dmamap->dm_nsegs && size > 0; dmaseg++) {
1259 bus_dma_segment_t *ds = &dmamap->dm_segs[dmaseg]; 1253 bus_dma_segment_t *ds = &dmamap->dm_segs[dmaseg];
1260 1254
1261 ma = ds->ds_addr; 1255 ma = ds->ds_addr;
1262 nbytes = imin(ds->ds_len, size); 1256 nbytes = imin(ds->ds_len, size);
1263 1257
1264 if (start > 0) { 1258 if (start > 0) {
1265 if (start >= nbytes) { 1259 if (start >= nbytes) {
1266 start -= nbytes; 1260 start -= nbytes;
1267 continue; 1261 continue;
1268 } 1262 }
1269 ma += start; 1263 ma += start;
1270 nbytes -= start; 1264 nbytes -= start;
1271 start = 0; 1265 start = 0;
1272 } 1266 }
1273 size -= nbytes; 1267 size -= nbytes;
1274 1268
1275 KASSERT(((ma & PAGE_MASK) & (XEN_BSIZE - 1)) == 0); 1269 KASSERT(((ma & PAGE_MASK) & (XEN_BSIZE - 1)) == 0);
1276 KASSERT((nbytes & (XEN_BSIZE - 1)) == 0); 1270 KASSERT((nbytes & (XEN_BSIZE - 1)) == 0);
1277 KASSERT((size & (XEN_BSIZE - 1)) == 0); 1271 KASSERT((size & (XEN_BSIZE - 1)) == 0);
1278 first_sect = (ma & PAGE_MASK) >> XEN_BSHIFT; 1272 first_sect = (ma & PAGE_MASK) >> XEN_BSHIFT;
1279 nsects = nbytes >> XEN_BSHIFT; 1273 nsects = nbytes >> XEN_BSHIFT;
1280 1274
1281 reqseg = &req->seg[segidx++]; 1275 reqseg = &req->seg[segidx++];
1282 reqseg->first_sect = first_sect; 1276 reqseg->first_sect = first_sect;
1283 reqseg->last_sect = first_sect + nsects - 1; 1277 reqseg->last_sect = first_sect + nsects - 1;
1284 KASSERT(reqseg->first_sect <= reqseg->last_sect); 1278 KASSERT(reqseg->first_sect <= reqseg->last_sect);
1285 KASSERT(reqseg->last_sect < (PAGE_SIZE / XEN_BSIZE)); 1279 KASSERT(reqseg->last_sect < (PAGE_SIZE / XEN_BSIZE));
1286 1280
1287 reqseg->gref = gntref[dmaseg]; 1281 reqseg->gref = gntref[dmaseg];
1288 } 1282 }
1289 req->nr_segments = segidx; 1283 req->nr_segments = segidx;
1290 sc->sc_ring.req_prod_pvt++; 1284 sc->sc_ring.req_prod_pvt++;
1291} 1285}
1292 1286
1293static void 1287static void
1294xbd_diskstart_submit_indirect(struct xbd_xenbus_softc *sc, 1288xbd_diskstart_submit_indirect(struct xbd_xenbus_softc *sc,
1295 struct xbd_req *xbdreq, struct buf *bp) 1289 struct xbd_req *xbdreq, struct buf *bp)
1296{ 1290{
1297 blkif_request_indirect_t *req; 1291 blkif_request_indirect_t *req;
1298 paddr_t ma; 1292 paddr_t ma;
1299 int nsects, nbytes, dmaseg, first_sect; 1293 int nsects, nbytes, dmaseg, first_sect;
1300 struct blkif_request_segment *reqseg; 1294 struct blkif_request_segment *reqseg;
1301 1295
1302 KASSERT(mutex_owned(&sc->sc_lock)); 1296 KASSERT(mutex_owned(&sc->sc_lock));
1303 1297
1304 req = (blkif_request_indirect_t *)RING_GET_REQUEST(&sc->sc_ring, 1298 req = (blkif_request_indirect_t *)RING_GET_REQUEST(&sc->sc_ring,
1305 sc->sc_ring.req_prod_pvt); 1299 sc->sc_ring.req_prod_pvt);
1306 req->id = xbdreq->req_id; 1300 req->id = xbdreq->req_id;
1307 req->operation = BLKIF_OP_INDIRECT; 1301 req->operation = BLKIF_OP_INDIRECT;
1308 req->indirect_op = 1302 req->indirect_op =
1309 bp->b_flags & B_READ ? BLKIF_OP_READ : BLKIF_OP_WRITE; 1303 bp->b_flags & B_READ ? BLKIF_OP_READ : BLKIF_OP_WRITE;
1310 req->sector_number = bp->b_rawblkno; 1304 req->sector_number = bp->b_rawblkno;
1311 req->handle = sc->sc_handle; 1305 req->handle = sc->sc_handle;
1312 1306
1313 xbdreq->req_indirect = SLIST_FIRST(&sc->sc_indirect_head); 1307 xbdreq->req_indirect = SLIST_FIRST(&sc->sc_indirect_head);
1314 KASSERT(xbdreq->req_indirect != NULL); /* always as many as reqs */ 1308 KASSERT(xbdreq->req_indirect != NULL); /* always as many as reqs */
1315 SLIST_REMOVE_HEAD(&sc->sc_indirect_head, in_next); 1309 SLIST_REMOVE_HEAD(&sc->sc_indirect_head, in_next);
1316 req->indirect_grefs[0] = xbdreq->req_indirect->in_gntref; 1310 req->indirect_grefs[0] = xbdreq->req_indirect->in_gntref;
1317 1311
1318 reqseg = xbdreq->req_indirect->in_addr; 1312 reqseg = xbdreq->req_indirect->in_addr;
1319 for (dmaseg = 0; dmaseg < xbdreq->req_dmamap->dm_nsegs; dmaseg++) { 1313 for (dmaseg = 0; dmaseg < xbdreq->req_dmamap->dm_nsegs; dmaseg++) {
1320 bus_dma_segment_t *ds = &xbdreq->req_dmamap->dm_segs[dmaseg]; 1314 bus_dma_segment_t *ds = &xbdreq->req_dmamap->dm_segs[dmaseg];
1321 1315
1322 ma = ds->ds_addr; 1316 ma = ds->ds_addr;
1323 nbytes = ds->ds_len; 1317 nbytes = ds->ds_len;
1324 1318
1325 first_sect = (ma & PAGE_MASK) >> XEN_BSHIFT; 1319 first_sect = (ma & PAGE_MASK) >> XEN_BSHIFT;
1326 nsects = nbytes >> XEN_BSHIFT; 1320 nsects = nbytes >> XEN_BSHIFT;
1327 1321
1328 reqseg->first_sect = first_sect; 1322 reqseg->first_sect = first_sect;
1329 reqseg->last_sect = first_sect + nsects - 1; 1323 reqseg->last_sect = first_sect + nsects - 1;
1330 reqseg->gref = xbdreq->req_gntref[dmaseg]; 1324 reqseg->gref = xbdreq->req_gntref[dmaseg];
1331 1325
1332 KASSERT(reqseg->first_sect <= reqseg->last_sect); 1326 KASSERT(reqseg->first_sect <= reqseg->last_sect);
1333 KASSERT(reqseg->last_sect < (PAGE_SIZE / XEN_BSIZE)); 1327 KASSERT(reqseg->last_sect < (PAGE_SIZE / XEN_BSIZE));
1334 1328
1335 reqseg++; 1329 reqseg++;
1336 } 1330 }
1337 req->nr_segments = dmaseg; 1331 req->nr_segments = dmaseg;
1338 sc->sc_ring.req_prod_pvt++; 1332 sc->sc_ring.req_prod_pvt++;
1339 1333
1340 sc->sc_cnt_indirect.ev_count++; 1334 sc->sc_cnt_indirect.ev_count++;
1341} 1335}
1342 1336
1343static int 1337static int
1344xbd_map_align(struct xbd_xenbus_softc *sc, struct xbd_req *req) 1338xbd_map_align(struct xbd_xenbus_softc *sc, struct xbd_req *req)
1345{ 1339{
1346 /* 1340 /*
1347 * Only can get here if this is physio() request, block I/O 1341 * Only can get here if this is physio() request, block I/O
1348 * uses DEV_BSIZE-aligned buffers. 1342 * uses DEV_BSIZE-aligned buffers.
1349 */ 1343 */
1350 KASSERT((req->req_bp->b_flags & B_PHYS) != 0); 1344 KASSERT((req->req_bp->b_flags & B_PHYS) != 0);
1351 1345
1352 sc->sc_cnt_map_unalign.ev_count++; 1346 sc->sc_cnt_map_unalign.ev_count++;
1353 1347
1354 if (sc->sc_unalign_used) { 1348 if (sc->sc_unalign_used) {
1355 sc->sc_cnt_unalign_busy.ev_count++; 1349 sc->sc_cnt_unalign_busy.ev_count++;
1356 return EAGAIN; 1350 return EAGAIN;
1357 } 1351 }
1358 sc->sc_unalign_used = req; 1352 sc->sc_unalign_used = req;
1359 1353
1360 KASSERT(req->req_bp->b_bcount <= MAXPHYS); 1354 KASSERT(req->req_bp->b_bcount <= MAXPHYS);
1361 req->req_data = (void *)sc->sc_unalign_buffer; 1355 req->req_data = (void *)sc->sc_unalign_buffer;
1362 if ((req->req_bp->b_flags & B_READ) == 0) 1356 if ((req->req_bp->b_flags & B_READ) == 0)
1363 memcpy(req->req_data, req->req_bp->b_data, 1357 memcpy(req->req_data, req->req_bp->b_data,
1364 req->req_bp->b_bcount); 1358 req->req_bp->b_bcount);
1365 return 0; 1359 return 0;
1366} 1360}
1367 1361
1368static void 1362static void
1369xbd_unmap_align(struct xbd_xenbus_softc *sc, struct xbd_req *req, bool sync) 1363xbd_unmap_align(struct xbd_xenbus_softc *sc, struct xbd_req *req, bool sync)
1370{ 1364{
1371 KASSERT(sc->sc_unalign_used == req); 1365 KASSERT(sc->sc_unalign_used == req);
1372 if (sync && req->req_bp->b_flags & B_READ) 1366 if (sync && req->req_bp->b_flags & B_READ)
1373 memcpy(req->req_bp->b_data, req->req_data, 1367 memcpy(req->req_bp->b_data, req->req_data,
1374 req->req_bp->b_bcount); 1368 req->req_bp->b_bcount);
1375 sc->sc_unalign_used = NULL; 1369 sc->sc_unalign_used = NULL;
1376} 1370}