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", §ors, 464 "info", "%u", &binfo, 465 "sector-size", "%lu", §or_size, 466 NULL); 467 if (err) { | 555 "sectors", "%lu", §ors, 556 "info", "%u", &binfo, 557 "sector-size", "%lu", §or_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], ©[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], ©[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 */ | |