Deleted Added
full compact
blkfront.c (183375) blkfront.c (185605)
1/*-
2 * All rights reserved.
3 *
4 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
5 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
6 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
8 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

--- 6 unchanged lines hidden (view full) ---

15 *
16 */
17
18/*
19 * XenoBSD block device driver
20 */
21
22#include <sys/cdefs.h>
1/*-
2 * All rights reserved.
3 *
4 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
5 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
6 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
8 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

--- 6 unchanged lines hidden (view full) ---

15 *
16 */
17
18/*
19 * XenoBSD block device driver
20 */
21
22#include <sys/cdefs.h>
23__FBSDID("$FreeBSD: head/sys/dev/xen/blkfront/blkfront.c 183375 2008-09-26 05:29:39Z kmacy $");
23__FBSDID("$FreeBSD: head/sys/dev/xen/blkfront/blkfront.c 185605 2008-12-04 07:59:05Z kmacy $");
24
25#include <sys/param.h>
26#include <sys/systm.h>
27#include <sys/malloc.h>
28#include <sys/kernel.h>
29#include <vm/vm.h>
30#include <vm/pmap.h>
31

--- 6 unchanged lines hidden (view full) ---

38#include <sys/rman.h>
39#include <machine/resource.h>
40#include <machine/intr_machdep.h>
41#include <machine/vmparam.h>
42
43#include <machine/xen/hypervisor.h>
44#include <machine/xen/xen-os.h>
45#include <machine/xen/xen_intr.h>
24
25#include <sys/param.h>
26#include <sys/systm.h>
27#include <sys/malloc.h>
28#include <sys/kernel.h>
29#include <vm/vm.h>
30#include <vm/pmap.h>
31

--- 6 unchanged lines hidden (view full) ---

38#include <sys/rman.h>
39#include <machine/resource.h>
40#include <machine/intr_machdep.h>
41#include <machine/vmparam.h>
42
43#include <machine/xen/hypervisor.h>
44#include <machine/xen/xen-os.h>
45#include <machine/xen/xen_intr.h>
46#include <machine/xen/xenbus.h>
47#include <machine/xen/evtchn.h>
48#include <xen/interface/grant_table.h>
46#include <machine/xen/evtchn.h>
47#include <xen/interface/grant_table.h>
48#include <xen/interface/io/protocols.h>
49#include <xen/xenbus/xenbusvar.h>
49
50#include <geom/geom_disk.h>
51#include <machine/xen/xenfunc.h>
52#include <xen/gnttab.h>
53
54#include <dev/xen/blkfront/block.h>
55
50
51#include <geom/geom_disk.h>
52#include <machine/xen/xenfunc.h>
53#include <xen/gnttab.h>
54
55#include <dev/xen/blkfront/block.h>
56
57#include "xenbus_if.h"
58
56#define ASSERT(S) KASSERT(S, (#S))
57/* prototypes */
58struct xb_softc;
59static void xb_startio(struct xb_softc *sc);
59#define ASSERT(S) KASSERT(S, (#S))
60/* prototypes */
61struct xb_softc;
62static void xb_startio(struct xb_softc *sc);
60static void connect(struct blkfront_info *);
61static void blkfront_closing(struct xenbus_device *);
62static int blkfront_remove(struct xenbus_device *);
63static int talk_to_backend(struct xenbus_device *, struct blkfront_info *);
64static int setup_blkring(struct xenbus_device *, struct blkfront_info *);
63static void connect(device_t, struct blkfront_info *);
64static void blkfront_closing(device_t);
65static int blkfront_detach(device_t);
66static int talk_to_backend(device_t, struct blkfront_info *);
67static int setup_blkring(device_t, struct blkfront_info *);
65static void blkif_int(void *);
66#if 0
67static void blkif_restart_queue(void *arg);
68#endif
69static void blkif_recover(struct blkfront_info *);
70static void blkif_completion(struct blk_shadow *);
71static void blkif_free(struct blkfront_info *, int);
72

--- 58 unchanged lines hidden (view full) ---

131
132static vm_paddr_t
133pfn_to_mfn(vm_paddr_t pfn)
134{
135 return (phystomach(pfn << PAGE_SHIFT) >> PAGE_SHIFT);
136}
137
138
68static void blkif_int(void *);
69#if 0
70static void blkif_restart_queue(void *arg);
71#endif
72static void blkif_recover(struct blkfront_info *);
73static void blkif_completion(struct blk_shadow *);
74static void blkif_free(struct blkfront_info *, int);
75

--- 58 unchanged lines hidden (view full) ---

134
135static vm_paddr_t
136pfn_to_mfn(vm_paddr_t pfn)
137{
138 return (phystomach(pfn << PAGE_SHIFT) >> PAGE_SHIFT);
139}
140
141
142/*
143 * Translate Linux major/minor to an appropriate name and unit
144 * number. For HVM guests, this allows us to use the same drive names
145 * with blkfront as the emulated drives, easing transition slightly.
146 */
147static void
148blkfront_vdevice_to_unit(int vdevice, int *unit, const char **name)
149{
150 static struct vdev_info {
151 int major;
152 int shift;
153 int base;
154 const char *name;
155 } info[] = {
156 {3, 6, 0, "ad"}, /* ide0 */
157 {22, 6, 2, "ad"}, /* ide1 */
158 {33, 6, 4, "ad"}, /* ide2 */
159 {34, 6, 6, "ad"}, /* ide3 */
160 {56, 6, 8, "ad"}, /* ide4 */
161 {57, 6, 10, "ad"}, /* ide5 */
162 {88, 6, 12, "ad"}, /* ide6 */
163 {89, 6, 14, "ad"}, /* ide7 */
164 {90, 6, 16, "ad"}, /* ide8 */
165 {91, 6, 18, "ad"}, /* ide9 */
166
167 {8, 4, 0, "da"}, /* scsi disk0 */
168 {65, 4, 16, "da"}, /* scsi disk1 */
169 {66, 4, 32, "da"}, /* scsi disk2 */
170 {67, 4, 48, "da"}, /* scsi disk3 */
171 {68, 4, 64, "da"}, /* scsi disk4 */
172 {69, 4, 80, "da"}, /* scsi disk5 */
173 {70, 4, 96, "da"}, /* scsi disk6 */
174 {71, 4, 112, "da"}, /* scsi disk7 */
175 {128, 4, 128, "da"}, /* scsi disk8 */
176 {129, 4, 144, "da"}, /* scsi disk9 */
177 {130, 4, 160, "da"}, /* scsi disk10 */
178 {131, 4, 176, "da"}, /* scsi disk11 */
179 {132, 4, 192, "da"}, /* scsi disk12 */
180 {133, 4, 208, "da"}, /* scsi disk13 */
181 {134, 4, 224, "da"}, /* scsi disk14 */
182 {135, 4, 240, "da"}, /* scsi disk15 */
183
184 {202, 4, 0, "xbd"}, /* xbd */
185
186 {0, 0, 0, NULL},
187 };
188 int major = vdevice >> 8;
189 int minor = vdevice & 0xff;
190 int i;
191
192 if (vdevice & (1 << 28)) {
193 *unit = (vdevice & ((1 << 28) - 1)) >> 8;
194 *name = "xbd";
195 }
196
197 for (i = 0; info[i].major; i++) {
198 if (info[i].major == major) {
199 *unit = info[i].base + (minor >> info[i].shift);
200 *name = info[i].name;
201 return;
202 }
203 }
204
205 *unit = minor >> 4;
206 *name = "xbd";
207}
208
139int
209int
140xlvbd_add(blkif_sector_t capacity, int unit, uint16_t vdisk_info, uint16_t sector_size,
141 struct blkfront_info *info)
210xlvbd_add(device_t dev, blkif_sector_t capacity,
211 int vdevice, uint16_t vdisk_info, uint16_t sector_size,
212 struct blkfront_info *info)
142{
143 struct xb_softc *sc;
213{
214 struct xb_softc *sc;
144 int error = 0;
145 int unitno = unit - 767;
215 int unit, error = 0;
216 const char *name;
217
218 blkfront_vdevice_to_unit(vdevice, &unit, &name);
146
147 sc = (struct xb_softc *)malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
219
220 sc = (struct xb_softc *)malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
148 sc->xb_unit = unitno;
221 sc->xb_unit = unit;
149 sc->xb_info = info;
150 info->sc = sc;
151
222 sc->xb_info = info;
223 info->sc = sc;
224
225 if (strcmp(name, "xbd"))
226 device_printf(dev, "attaching as %s%d\n", name, unit);
227
152 memset(&sc->xb_disk, 0, sizeof(sc->xb_disk));
153 sc->xb_disk = disk_alloc();
228 memset(&sc->xb_disk, 0, sizeof(sc->xb_disk));
229 sc->xb_disk = disk_alloc();
154 sc->xb_disk->d_unit = unitno;
230 sc->xb_disk->d_unit = unit;
155 sc->xb_disk->d_open = blkif_open;
156 sc->xb_disk->d_close = blkif_close;
157 sc->xb_disk->d_ioctl = blkif_ioctl;
158 sc->xb_disk->d_strategy = xb_strategy;
159 sc->xb_disk->d_name = "xbd";
160 sc->xb_disk->d_drv1 = sc;
161 sc->xb_disk->d_sectorsize = sector_size;
162

--- 58 unchanged lines hidden (view full) ---

221 /*
222 * Correctly set the bio to indicate a failed tranfer.
223 */
224 bp->bio_resid = bp->bio_bcount;
225 biodone(bp);
226 return;
227}
228
231 sc->xb_disk->d_open = blkif_open;
232 sc->xb_disk->d_close = blkif_close;
233 sc->xb_disk->d_ioctl = blkif_ioctl;
234 sc->xb_disk->d_strategy = xb_strategy;
235 sc->xb_disk->d_name = "xbd";
236 sc->xb_disk->d_drv1 = sc;
237 sc->xb_disk->d_sectorsize = sector_size;
238

--- 58 unchanged lines hidden (view full) ---

297 /*
298 * Correctly set the bio to indicate a failed tranfer.
299 */
300 bp->bio_resid = bp->bio_bcount;
301 biodone(bp);
302 return;
303}
304
305static int
306blkfront_probe(device_t dev)
307{
229
308
230/* Setup supplies the backend dir, virtual device.
309 if (!strcmp(xenbus_get_type(dev), "vbd")) {
310 device_set_desc(dev, "Virtual Block Device");
311 device_quiet(dev);
312 return (0);
313 }
231
314
232We place an event channel and shared frame entries.
233We watch backend to wait if it's ok. */
234static int blkfront_probe(struct xenbus_device *dev,
235 const struct xenbus_device_id *id)
315 return (ENXIO);
316}
317
318/*
319 * Setup supplies the backend dir, virtual device. We place an event
320 * channel and shared frame entries. We watch backend to wait if it's
321 * ok.
322 */
323static int
324blkfront_attach(device_t dev)
236{
325{
237 int err, vdevice, i;
326 int err, vdevice, i, unit;
238 struct blkfront_info *info;
327 struct blkfront_info *info;
328 const char *name;
239
240 /* FIXME: Use dynamic device id if this is not set. */
329
330 /* FIXME: Use dynamic device id if this is not set. */
241 err = xenbus_scanf(XBT_NIL, dev->nodename,
331 err = xenbus_scanf(XBT_NIL, xenbus_get_node(dev),
242 "virtual-device", "%i", &vdevice);
243 if (err != 1) {
244 xenbus_dev_fatal(dev, err, "reading virtual-device");
245 printf("couldn't find virtual device");
246 return (err);
247 }
248
332 "virtual-device", "%i", &vdevice);
333 if (err != 1) {
334 xenbus_dev_fatal(dev, err, "reading virtual-device");
335 printf("couldn't find virtual device");
336 return (err);
337 }
338
249 info = malloc(sizeof(*info), M_DEVBUF, M_NOWAIT|M_ZERO);
250 if (info == NULL) {
251 xenbus_dev_fatal(dev, ENOMEM, "allocating info structure");
252 return ENOMEM;
253 }
339 blkfront_vdevice_to_unit(vdevice, &unit, &name);
340 if (!strcmp(name, "xbd"))
341 device_set_unit(dev, unit);
342
343 info = device_get_softc(dev);
254
255 /*
256 * XXX debug only
257 */
258 for (i = 0; i < sizeof(*info); i++)
259 if (((uint8_t *)info)[i] != 0)
260 panic("non-null memory");
261
262 info->shadow_free = 0;
263 info->xbdev = dev;
264 info->vdevice = vdevice;
265 info->connected = BLKIF_STATE_DISCONNECTED;
266
267 /* work queue needed ? */
268 for (i = 0; i < BLK_RING_SIZE; i++)
269 info->shadow[i].req.id = i+1;
270 info->shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
271
272 /* Front end dir is a number, which is used as the id. */
344
345 /*
346 * XXX debug only
347 */
348 for (i = 0; i < sizeof(*info); i++)
349 if (((uint8_t *)info)[i] != 0)
350 panic("non-null memory");
351
352 info->shadow_free = 0;
353 info->xbdev = dev;
354 info->vdevice = vdevice;
355 info->connected = BLKIF_STATE_DISCONNECTED;
356
357 /* work queue needed ? */
358 for (i = 0; i < BLK_RING_SIZE; i++)
359 info->shadow[i].req.id = i+1;
360 info->shadow[BLK_RING_SIZE-1].req.id = 0x0fffffff;
361
362 /* Front end dir is a number, which is used as the id. */
273 info->handle = strtoul(strrchr(dev->nodename,'/')+1, NULL, 0);
274 dev->dev_driver_data = info;
363 info->handle = strtoul(strrchr(xenbus_get_node(dev),'/')+1, NULL, 0);
275
276 err = talk_to_backend(dev, info);
277 if (err) {
364
365 err = talk_to_backend(dev, info);
366 if (err) {
278 free(info, M_DEVBUF);
279 dev->dev_driver_data = NULL;
280 return err;
281 }
282
367 return err;
368 }
369
283 return 0;
370 return (0);
284}
285
371}
372
286
287static int blkfront_resume(struct xenbus_device *dev)
373static int
374blkfront_resume(device_t dev)
288{
375{
289 struct blkfront_info *info = dev->dev_driver_data;
376 struct blkfront_info *info = device_get_softc(dev);
290 int err;
291
292 DPRINTK("blkfront_resume: %s\n", dev->nodename);
293
294 blkif_free(info, 1);
295
296 err = talk_to_backend(dev, info);
297 if (!err)
298 blkif_recover(info);
299
300 return err;
301}
302
303/* Common code used when first setting up, and when resuming. */
377 int err;
378
379 DPRINTK("blkfront_resume: %s\n", dev->nodename);
380
381 blkif_free(info, 1);
382
383 err = talk_to_backend(dev, info);
384 if (!err)
385 blkif_recover(info);
386
387 return err;
388}
389
390/* Common code used when first setting up, and when resuming. */
304static int talk_to_backend(struct xenbus_device *dev,
305 struct blkfront_info *info)
391static int
392talk_to_backend(device_t dev, struct blkfront_info *info)
306{
307 const char *message = NULL;
308 struct xenbus_transaction xbt;
309 int err;
310
311 /* Create shared ring, alloc event channel. */
312 err = setup_blkring(dev, info);
313 if (err)
314 goto out;
315
316 again:
317 err = xenbus_transaction_start(&xbt);
318 if (err) {
319 xenbus_dev_fatal(dev, err, "starting transaction");
320 goto destroy_blkring;
321 }
322
393{
394 const char *message = NULL;
395 struct xenbus_transaction xbt;
396 int err;
397
398 /* Create shared ring, alloc event channel. */
399 err = setup_blkring(dev, info);
400 if (err)
401 goto out;
402
403 again:
404 err = xenbus_transaction_start(&xbt);
405 if (err) {
406 xenbus_dev_fatal(dev, err, "starting transaction");
407 goto destroy_blkring;
408 }
409
323 err = xenbus_printf(xbt, dev->nodename,
410 err = xenbus_printf(xbt, xenbus_get_node(dev),
324 "ring-ref","%u", info->ring_ref);
325 if (err) {
326 message = "writing ring-ref";
327 goto abort_transaction;
328 }
411 "ring-ref","%u", info->ring_ref);
412 if (err) {
413 message = "writing ring-ref";
414 goto abort_transaction;
415 }
329 err = xenbus_printf(xbt, dev->nodename,
416 err = xenbus_printf(xbt, xenbus_get_node(dev),
330 "event-channel", "%u", irq_to_evtchn_port(info->irq));
331 if (err) {
332 message = "writing event-channel";
333 goto abort_transaction;
334 }
417 "event-channel", "%u", irq_to_evtchn_port(info->irq));
418 if (err) {
419 message = "writing event-channel";
420 goto abort_transaction;
421 }
335
422 err = xenbus_printf(xbt, xenbus_get_node(dev),
423 "protocol", "%s", XEN_IO_PROTO_ABI_NATIVE);
424 if (err) {
425 message = "writing protocol";
426 goto abort_transaction;
427 }
336 err = xenbus_transaction_end(xbt, 0);
337 if (err) {
338 if (err == -EAGAIN)
339 goto again;
340 xenbus_dev_fatal(dev, err, "completing transaction");
341 goto destroy_blkring;
342 }
428 err = xenbus_transaction_end(xbt, 0);
429 if (err) {
430 if (err == -EAGAIN)
431 goto again;
432 xenbus_dev_fatal(dev, err, "completing transaction");
433 goto destroy_blkring;
434 }
343 xenbus_switch_state(dev, XenbusStateInitialised);
435 xenbus_set_state(dev, XenbusStateInitialised);
344
345 return 0;
346
347 abort_transaction:
348 xenbus_transaction_end(xbt, 1);
349 if (message)
350 xenbus_dev_fatal(dev, err, "%s", message);
351 destroy_blkring:
352 blkif_free(info, 0);
353 out:
354 return err;
355}
356
357static int
436
437 return 0;
438
439 abort_transaction:
440 xenbus_transaction_end(xbt, 1);
441 if (message)
442 xenbus_dev_fatal(dev, err, "%s", message);
443 destroy_blkring:
444 blkif_free(info, 0);
445 out:
446 return err;
447}
448
449static int
358setup_blkring(struct xenbus_device *dev, struct blkfront_info *info)
450setup_blkring(device_t dev, struct blkfront_info *info)
359{
360 blkif_sring_t *sring;
361 int err;
362
363 info->ring_ref = GRANT_INVALID_REF;
364
365 sring = (blkif_sring_t *)malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT|M_ZERO);
366 if (sring == NULL) {

--- 6 unchanged lines hidden (view full) ---

373 err = xenbus_grant_ring(dev, (vtomach(info->ring.sring) >> PAGE_SHIFT));
374 if (err < 0) {
375 free(sring, M_DEVBUF);
376 info->ring.sring = NULL;
377 goto fail;
378 }
379 info->ring_ref = err;
380
451{
452 blkif_sring_t *sring;
453 int err;
454
455 info->ring_ref = GRANT_INVALID_REF;
456
457 sring = (blkif_sring_t *)malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT|M_ZERO);
458 if (sring == NULL) {

--- 6 unchanged lines hidden (view full) ---

465 err = xenbus_grant_ring(dev, (vtomach(info->ring.sring) >> PAGE_SHIFT));
466 if (err < 0) {
467 free(sring, M_DEVBUF);
468 info->ring.sring = NULL;
469 goto fail;
470 }
471 info->ring_ref = err;
472
381 err = bind_listening_port_to_irqhandler(dev->otherend_id,
473 err = bind_listening_port_to_irqhandler(xenbus_get_otherend_id(dev),
382 "xbd", (driver_intr_t *)blkif_int, info,
383 INTR_TYPE_BIO | INTR_MPSAFE, NULL);
384 if (err <= 0) {
385 xenbus_dev_fatal(dev, err,
386 "bind_evtchn_to_irqhandler failed");
387 goto fail;
388 }
389 info->irq = err;
390
391 return 0;
392 fail:
393 blkif_free(info, 0);
394 return err;
395}
396
397
398/**
399 * Callback received when the backend's state changes.
400 */
474 "xbd", (driver_intr_t *)blkif_int, info,
475 INTR_TYPE_BIO | INTR_MPSAFE, NULL);
476 if (err <= 0) {
477 xenbus_dev_fatal(dev, err,
478 "bind_evtchn_to_irqhandler failed");
479 goto fail;
480 }
481 info->irq = err;
482
483 return 0;
484 fail:
485 blkif_free(info, 0);
486 return err;
487}
488
489
490/**
491 * Callback received when the backend's state changes.
492 */
401static void backend_changed(struct xenbus_device *dev,
402 XenbusState backend_state)
493static void
494blkfront_backend_changed(device_t dev, XenbusState backend_state)
403{
495{
404 struct blkfront_info *info = dev->dev_driver_data;
496 struct blkfront_info *info = device_get_softc(dev);
405
406 DPRINTK("blkfront:backend_changed.\n");
407
408 switch (backend_state) {
409 case XenbusStateUnknown:
410 case XenbusStateInitialising:
411 case XenbusStateInitWait:
412 case XenbusStateInitialised:
413 case XenbusStateClosed:
414 case XenbusStateReconfigured:
415 case XenbusStateReconfiguring:
416 break;
417
418 case XenbusStateConnected:
497
498 DPRINTK("blkfront:backend_changed.\n");
499
500 switch (backend_state) {
501 case XenbusStateUnknown:
502 case XenbusStateInitialising:
503 case XenbusStateInitWait:
504 case XenbusStateInitialised:
505 case XenbusStateClosed:
506 case XenbusStateReconfigured:
507 case XenbusStateReconfiguring:
508 break;
509
510 case XenbusStateConnected:
419 connect(info);
511 connect(dev, info);
420 break;
421
422 case XenbusStateClosing:
423 if (info->users > 0)
424 xenbus_dev_error(dev, -EBUSY,
425 "Device in use; refusing to close");
426 else
427 blkfront_closing(dev);

--- 14 unchanged lines hidden (view full) ---

442 }
443}
444
445/*
446** Invoked when the backend is finally 'ready' (and has told produced
447** the details about the physical device - #sectors, size, etc).
448*/
449static void
512 break;
513
514 case XenbusStateClosing:
515 if (info->users > 0)
516 xenbus_dev_error(dev, -EBUSY,
517 "Device in use; refusing to close");
518 else
519 blkfront_closing(dev);

--- 14 unchanged lines hidden (view full) ---

534 }
535}
536
537/*
538** Invoked when the backend is finally 'ready' (and has told produced
539** the details about the physical device - #sectors, size, etc).
540*/
541static void
450connect(struct blkfront_info *info)
542connect(device_t dev, struct blkfront_info *info)
451{
452 unsigned long sectors, sector_size;
453 unsigned int binfo;
454 int err;
455
456 if( (info->connected == BLKIF_STATE_CONNECTED) ||
457 (info->connected == BLKIF_STATE_SUSPENDED) )
458 return;
459
543{
544 unsigned long sectors, sector_size;
545 unsigned int binfo;
546 int err;
547
548 if( (info->connected == BLKIF_STATE_CONNECTED) ||
549 (info->connected == BLKIF_STATE_SUSPENDED) )
550 return;
551
460 DPRINTK("blkfront.c:connect:%s.\n", info->xbdev->otherend);
552 DPRINTK("blkfront.c:connect:%s.\n", xenbus_get_otherend_path(dev));
461
553
462 err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
554 err = xenbus_gather(XBT_NIL, xenbus_get_otherend_path(dev),
463 "sectors", "%lu", &sectors,
464 "info", "%u", &binfo,
465 "sector-size", "%lu", &sector_size,
466 NULL);
467 if (err) {
555 "sectors", "%lu", &sectors,
556 "info", "%u", &binfo,
557 "sector-size", "%lu", &sector_size,
558 NULL);
559 if (err) {
468 xenbus_dev_fatal(info->xbdev, err,
469 "reading backend fields at %s",
470 info->xbdev->otherend);
560 xenbus_dev_fatal(dev, err,
561 "reading backend fields at %s",
562 xenbus_get_otherend_path(dev));
471 return;
472 }
563 return;
564 }
473 err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
565 err = xenbus_gather(XBT_NIL, xenbus_get_otherend_path(dev),
474 "feature-barrier", "%lu", &info->feature_barrier,
475 NULL);
476 if (err)
477 info->feature_barrier = 0;
478
566 "feature-barrier", "%lu", &info->feature_barrier,
567 NULL);
568 if (err)
569 info->feature_barrier = 0;
570
479 xlvbd_add(sectors, info->vdevice, binfo, sector_size, info);
571 device_printf(dev, "%juMB <%s> at %s",
572 (uintmax_t) sectors / (1048576 / sector_size),
573 device_get_desc(dev),
574 xenbus_get_node(dev));
575 bus_print_child_footer(device_get_parent(dev), dev);
480
576
481 (void)xenbus_switch_state(info->xbdev, XenbusStateConnected);
577 xlvbd_add(dev, sectors, info->vdevice, binfo, sector_size, info);
482
578
579 (void)xenbus_set_state(dev, XenbusStateConnected);
580
483 /* Kick pending requests. */
484 mtx_lock(&blkif_io_lock);
485 info->connected = BLKIF_STATE_CONNECTED;
486 kick_pending_request_queues(info);
487 mtx_unlock(&blkif_io_lock);
488 info->is_ready = 1;
489
490#if 0
491 add_disk(info->gd);
492#endif
493}
494
495/**
496 * Handle the change of state of the backend to Closing. We must delete our
497 * device-layer structures now, to ensure that writes are flushed through to
498 * the backend. Once is this done, we can switch to Closed in
499 * acknowledgement.
500 */
581 /* Kick pending requests. */
582 mtx_lock(&blkif_io_lock);
583 info->connected = BLKIF_STATE_CONNECTED;
584 kick_pending_request_queues(info);
585 mtx_unlock(&blkif_io_lock);
586 info->is_ready = 1;
587
588#if 0
589 add_disk(info->gd);
590#endif
591}
592
593/**
594 * Handle the change of state of the backend to Closing. We must delete our
595 * device-layer structures now, to ensure that writes are flushed through to
596 * the backend. Once is this done, we can switch to Closed in
597 * acknowledgement.
598 */
501static void blkfront_closing(struct xenbus_device *dev)
599static void
600blkfront_closing(device_t dev)
502{
601{
503 struct blkfront_info *info = dev->dev_driver_data;
602 struct blkfront_info *info = device_get_softc(dev);
504
603
505 DPRINTK("blkfront_closing: %s removed\n", dev->nodename);
604 DPRINTK("blkfront_closing: %s removed\n", xenbus_get_node(dev));
506
507 if (info->mi) {
508 DPRINTK("Calling xlvbd_del\n");
509 xlvbd_del(info);
510 info->mi = NULL;
511 }
512
605
606 if (info->mi) {
607 DPRINTK("Calling xlvbd_del\n");
608 xlvbd_del(info);
609 info->mi = NULL;
610 }
611
513 xenbus_switch_state(dev, XenbusStateClosed);
612 xenbus_set_state(dev, XenbusStateClosed);
514}
515
516
613}
614
615
517static int blkfront_remove(struct xenbus_device *dev)
616static int
617blkfront_detach(device_t dev)
518{
618{
519 struct blkfront_info *info = dev->dev_driver_data;
619 struct blkfront_info *info = device_get_softc(dev);
520
620
521 DPRINTK("blkfront_remove: %s removed\n", dev->nodename);
621 DPRINTK("blkfront_remove: %s removed\n", xenbus_get_node(dev));
522
523 blkif_free(info, 0);
524
622
623 blkif_free(info, 0);
624
525 free(info, M_DEVBUF);
526
527 return 0;
528}
529
530
531static inline int
532GET_ID_FROM_FREELIST(struct blkfront_info *info)
533{
534 unsigned long nfree = info->shadow_free;

--- 91 unchanged lines hidden (view full) ---

626
627 if (sc == NULL)
628 return (ENXIO);
629 sc->xb_flags &= ~XB_OPEN;
630 if (--(sc->xb_info->users) == 0) {
631 /* Check whether we have been instructed to close. We will
632 have ignored this request initially, as the device was
633 still mounted. */
625 return 0;
626}
627
628
629static inline int
630GET_ID_FROM_FREELIST(struct blkfront_info *info)
631{
632 unsigned long nfree = info->shadow_free;

--- 91 unchanged lines hidden (view full) ---

724
725 if (sc == NULL)
726 return (ENXIO);
727 sc->xb_flags &= ~XB_OPEN;
728 if (--(sc->xb_info->users) == 0) {
729 /* Check whether we have been instructed to close. We will
730 have ignored this request initially, as the device was
731 still mounted. */
634 struct xenbus_device * dev = sc->xb_info->xbdev;
635 XenbusState state = xenbus_read_driver_state(dev->otherend);
732 device_t dev = sc->xb_info->xbdev;
733 XenbusState state =
734 xenbus_read_driver_state(xenbus_get_otherend_path(dev));
636
637 if (state == XenbusStateClosing)
638 blkfront_closing(dev);
639 }
640 return (0);
641}
642
643static int

--- 82 unchanged lines hidden (view full) ---

726 fsect = (buffer_ma & PAGE_MASK) >> XBD_SECTOR_SHFT;
727 lsect = fsect + (bp->bio_bcount >> XBD_SECTOR_SHFT) - 1;
728 /* install a grant reference. */
729 ref = gnttab_claim_grant_reference(&gref_head);
730 KASSERT( ref != -ENOSPC, ("grant_reference failed") );
731
732 gnttab_grant_foreign_access_ref(
733 ref,
735
736 if (state == XenbusStateClosing)
737 blkfront_closing(dev);
738 }
739 return (0);
740}
741
742static int

--- 82 unchanged lines hidden (view full) ---

825 fsect = (buffer_ma & PAGE_MASK) >> XBD_SECTOR_SHFT;
826 lsect = fsect + (bp->bio_bcount >> XBD_SECTOR_SHFT) - 1;
827 /* install a grant reference. */
828 ref = gnttab_claim_grant_reference(&gref_head);
829 KASSERT( ref != -ENOSPC, ("grant_reference failed") );
830
831 gnttab_grant_foreign_access_ref(
832 ref,
734 info->xbdev->otherend_id,
833 xenbus_get_otherend_id(info->xbdev),
735 buffer_ma >> PAGE_SHIFT,
736 ring_req->operation & 1 ); /* ??? */
737 info->shadow[id].frame[ring_req->nr_segments] =
738 buffer_ma >> PAGE_SHIFT;
739
740 ring_req->seg[ring_req->nr_segments] =
741 (struct blkif_request_segment) {
742 .gref = ref,

--- 204 unchanged lines hidden (view full) ---

947 /* We get a new request id, and must reset the shadow state. */
948 req->id = GET_ID_FROM_FREELIST(info);
949 memcpy(&info->shadow[req->id], &copy[i], sizeof(copy[i]));
950
951 /* Rewrite any grant references invalidated by suspend/resume. */
952 for (j = 0; j < req->nr_segments; j++)
953 gnttab_grant_foreign_access_ref(
954 req->seg[j].gref,
834 buffer_ma >> PAGE_SHIFT,
835 ring_req->operation & 1 ); /* ??? */
836 info->shadow[id].frame[ring_req->nr_segments] =
837 buffer_ma >> PAGE_SHIFT;
838
839 ring_req->seg[ring_req->nr_segments] =
840 (struct blkif_request_segment) {
841 .gref = ref,

--- 204 unchanged lines hidden (view full) ---

1046 /* We get a new request id, and must reset the shadow state. */
1047 req->id = GET_ID_FROM_FREELIST(info);
1048 memcpy(&info->shadow[req->id], &copy[i], sizeof(copy[i]));
1049
1050 /* Rewrite any grant references invalidated by suspend/resume. */
1051 for (j = 0; j < req->nr_segments; j++)
1052 gnttab_grant_foreign_access_ref(
1053 req->seg[j].gref,
955 info->xbdev->otherend_id,
1054 xenbus_get_otherend_id(info->xbdev),
956 pfn_to_mfn(info->shadow[req->id].frame[j]),
957 0 /* assume not readonly */);
958
959 info->shadow[req->id].req = *req;
960
961 info->ring.req_prod_pvt++;
962 }
963
964 free(copy, M_DEVBUF);
965
1055 pfn_to_mfn(info->shadow[req->id].frame[j]),
1056 0 /* assume not readonly */);
1057
1058 info->shadow[req->id].req = *req;
1059
1060 info->ring.req_prod_pvt++;
1061 }
1062
1063 free(copy, M_DEVBUF);
1064
966 xenbus_switch_state(info->xbdev, XenbusStateConnected);
1065 xenbus_set_state(info->xbdev, XenbusStateConnected);
967
968 /* Now safe for us to use the shared ring */
969 mtx_lock(&blkif_io_lock);
970 info->connected = BLKIF_STATE_CONNECTED;
971 mtx_unlock(&blkif_io_lock);
972
973 /* Send off requeued requests */
974 mtx_lock(&blkif_io_lock);
975 flush_requests(info);
976
977 /* Kick any other new requests queued since we resumed */
978 kick_pending_request_queues(info);
979 mtx_unlock(&blkif_io_lock);
980}
981
1066
1067 /* Now safe for us to use the shared ring */
1068 mtx_lock(&blkif_io_lock);
1069 info->connected = BLKIF_STATE_CONNECTED;
1070 mtx_unlock(&blkif_io_lock);
1071
1072 /* Send off requeued requests */
1073 mtx_lock(&blkif_io_lock);
1074 flush_requests(info);
1075
1076 /* Kick any other new requests queued since we resumed */
1077 kick_pending_request_queues(info);
1078 mtx_unlock(&blkif_io_lock);
1079}
1080
982static int
983blkfront_is_ready(struct xenbus_device *dev)
984{
985 struct blkfront_info *info = dev->dev_driver_data;
1081/* ** Driver registration ** */
1082static device_method_t blkfront_methods[] = {
1083 /* Device interface */
1084 DEVMETHOD(device_probe, blkfront_probe),
1085 DEVMETHOD(device_attach, blkfront_attach),
1086 DEVMETHOD(device_detach, blkfront_detach),
1087 DEVMETHOD(device_shutdown, bus_generic_shutdown),
1088 DEVMETHOD(device_suspend, bus_generic_suspend),
1089 DEVMETHOD(device_resume, blkfront_resume),
1090
1091 /* Xenbus interface */
1092 DEVMETHOD(xenbus_backend_changed, blkfront_backend_changed),
986
1093
987 return info->is_ready;
988}
1094 { 0, 0 }
1095};
989
1096
990static struct xenbus_device_id blkfront_ids[] = {
991 { "vbd" },
992 { "" }
993};
1097static driver_t blkfront_driver = {
1098 "xbd",
1099 blkfront_methods,
1100 sizeof(struct blkfront_info),
1101};
1102devclass_t blkfront_devclass;
1103
1104DRIVER_MODULE(xbd, xenbus, blkfront_driver, blkfront_devclass, 0, 0);
994
1105
995
996static struct xenbus_driver blkfront = {
997 .name = "vbd",
998 .ids = blkfront_ids,
999 .probe = blkfront_probe,
1000 .remove = blkfront_remove,
1001 .resume = blkfront_resume,
1002 .otherend_changed = backend_changed,
1003 .is_ready = blkfront_is_ready,
1004};
1005
1006
1007
1008static void
1009xenbus_init(void)
1010{
1011 xenbus_register_frontend(&blkfront);
1012}
1013
1014MTX_SYSINIT(ioreq, &blkif_io_lock, "BIO LOCK", MTX_NOWITNESS); /* XXX how does one enroll a lock? */
1106MTX_SYSINIT(ioreq, &blkif_io_lock, "BIO LOCK", MTX_NOWITNESS); /* XXX how does one enroll a lock? */
1015SYSINIT(xbdev, SI_SUB_PSEUDO, SI_ORDER_SECOND, xenbus_init, NULL);
1016
1107
1017
1018/*
1019 * Local variables:
1020 * mode: C
1021 * c-set-style: "BSD"
1022 * c-basic-offset: 8
1023 * tab-width: 4
1024 * indent-tabs-mode: t
1025 * End:
1026 */