| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: md.c,v 1.61 2009/10/22 20:15:45 snj Exp $ */ | | 1 | /* $NetBSD: md.c,v 1.62 2010/01/21 02:14:42 dyoung Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1995 Gordon W. Ross, Leo Weppelman. | | 4 | * Copyright (c) 1995 Gordon W. Ross, Leo Weppelman. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -30,27 +30,27 @@ | | | @@ -30,27 +30,27 @@ |
30 | * See md.h for notes on the config types. | | 30 | * See md.h for notes on the config types. |
31 | * | | 31 | * |
32 | * Note that this driver provides the same functionality | | 32 | * Note that this driver provides the same functionality |
33 | * as the MFS filesystem hack, but this is better because | | 33 | * as the MFS filesystem hack, but this is better because |
34 | * you can use this for any filesystem type you'd like! | | 34 | * you can use this for any filesystem type you'd like! |
35 | * | | 35 | * |
36 | * Credit for most of the kmem ramdisk code goes to: | | 36 | * Credit for most of the kmem ramdisk code goes to: |
37 | * Leo Weppelman (atari) and Phil Nelson (pc532) | | 37 | * Leo Weppelman (atari) and Phil Nelson (pc532) |
38 | * Credit for the ideas behind the "user space memory" code goes | | 38 | * Credit for the ideas behind the "user space memory" code goes |
39 | * to the authors of the MFS implementation. | | 39 | * to the authors of the MFS implementation. |
40 | */ | | 40 | */ |
41 | | | 41 | |
42 | #include <sys/cdefs.h> | | 42 | #include <sys/cdefs.h> |
43 | __KERNEL_RCSID(0, "$NetBSD: md.c,v 1.61 2009/10/22 20:15:45 snj Exp $"); | | 43 | __KERNEL_RCSID(0, "$NetBSD: md.c,v 1.62 2010/01/21 02:14:42 dyoung Exp $"); |
44 | | | 44 | |
45 | #include "opt_md.h" | | 45 | #include "opt_md.h" |
46 | #include "opt_tftproot.h" | | 46 | #include "opt_tftproot.h" |
47 | | | 47 | |
48 | #include <sys/param.h> | | 48 | #include <sys/param.h> |
49 | #include <sys/kernel.h> | | 49 | #include <sys/kernel.h> |
50 | #include <sys/malloc.h> | | 50 | #include <sys/malloc.h> |
51 | #include <sys/systm.h> | | 51 | #include <sys/systm.h> |
52 | #include <sys/buf.h> | | 52 | #include <sys/buf.h> |
53 | #include <sys/bufq.h> | | 53 | #include <sys/bufq.h> |
54 | #include <sys/device.h> | | 54 | #include <sys/device.h> |
55 | #include <sys/disk.h> | | 55 | #include <sys/disk.h> |
56 | #include <sys/stat.h> | | 56 | #include <sys/stat.h> |
| @@ -314,59 +314,59 @@ mdclose(dev_t dev, int flag, int fmt, st | | | @@ -314,59 +314,59 @@ mdclose(dev_t dev, int flag, int fmt, st |
314 | dk->dk_openmask = dk->dk_copenmask | dk->dk_bopenmask; | | 314 | dk->dk_openmask = dk->dk_copenmask | dk->dk_bopenmask; |
315 | | | 315 | |
316 | mutex_exit(&dk->dk_openlock); | | 316 | mutex_exit(&dk->dk_openlock); |
317 | return 0; | | 317 | return 0; |
318 | } | | 318 | } |
319 | | | 319 | |
320 | static int | | 320 | static int |
321 | mdread(dev_t dev, struct uio *uio, int flags) | | 321 | mdread(dev_t dev, struct uio *uio, int flags) |
322 | { | | 322 | { |
323 | struct md_softc *sc; | | 323 | struct md_softc *sc; |
324 | | | 324 | |
325 | sc = device_lookup_private(&md_cd, MD_UNIT(dev)); | | 325 | sc = device_lookup_private(&md_cd, MD_UNIT(dev)); |
326 | | | 326 | |
327 | if (sc->sc_type == MD_UNCONFIGURED) | | 327 | if (sc == NULL || sc->sc_type == MD_UNCONFIGURED) |
328 | return ENXIO; | | 328 | return ENXIO; |
329 | | | 329 | |
330 | return (physio(mdstrategy, NULL, dev, B_READ, minphys, uio)); | | 330 | return (physio(mdstrategy, NULL, dev, B_READ, minphys, uio)); |
331 | } | | 331 | } |
332 | | | 332 | |
333 | static int | | 333 | static int |
334 | mdwrite(dev_t dev, struct uio *uio, int flags) | | 334 | mdwrite(dev_t dev, struct uio *uio, int flags) |
335 | { | | 335 | { |
336 | struct md_softc *sc; | | 336 | struct md_softc *sc; |
337 | | | 337 | |
338 | sc = device_lookup_private(&md_cd, MD_UNIT(dev)); | | 338 | sc = device_lookup_private(&md_cd, MD_UNIT(dev)); |
339 | | | 339 | |
340 | if (sc->sc_type == MD_UNCONFIGURED) | | 340 | if (sc == NULL || sc->sc_type == MD_UNCONFIGURED) |
341 | return ENXIO; | | 341 | return ENXIO; |
342 | | | 342 | |
343 | return (physio(mdstrategy, NULL, dev, B_WRITE, minphys, uio)); | | 343 | return (physio(mdstrategy, NULL, dev, B_WRITE, minphys, uio)); |
344 | } | | 344 | } |
345 | | | 345 | |
346 | /* | | 346 | /* |
347 | * Handle I/O requests, either directly, or | | 347 | * Handle I/O requests, either directly, or |
348 | * by passing them to the server process. | | 348 | * by passing them to the server process. |
349 | */ | | 349 | */ |
350 | static void | | 350 | static void |
351 | mdstrategy(struct buf *bp) | | 351 | mdstrategy(struct buf *bp) |
352 | { | | 352 | { |
353 | struct md_softc *sc; | | 353 | struct md_softc *sc; |
354 | void * addr; | | 354 | void * addr; |
355 | size_t off, xfer; | | 355 | size_t off, xfer; |
356 | | | 356 | |
357 | sc = device_lookup_private(&md_cd, MD_UNIT(bp->b_dev)); | | 357 | sc = device_lookup_private(&md_cd, MD_UNIT(bp->b_dev)); |
358 | | | 358 | |
359 | if (sc->sc_type == MD_UNCONFIGURED) { | | 359 | if (sc == NULL || sc->sc_type == MD_UNCONFIGURED) { |
360 | bp->b_error = ENXIO; | | 360 | bp->b_error = ENXIO; |
361 | goto done; | | 361 | goto done; |
362 | } | | 362 | } |
363 | | | 363 | |
364 | switch (sc->sc_type) { | | 364 | switch (sc->sc_type) { |
365 | #if MEMORY_DISK_SERVER | | 365 | #if MEMORY_DISK_SERVER |
366 | case MD_UMEM_SERVER: | | 366 | case MD_UMEM_SERVER: |
367 | /* Just add this job to the server's queue. */ | | 367 | /* Just add this job to the server's queue. */ |
368 | bufq_put(sc->sc_buflist, bp); | | 368 | bufq_put(sc->sc_buflist, bp); |
369 | wakeup((void *)sc); | | 369 | wakeup((void *)sc); |
370 | /* see md_server_loop() */ | | 370 | /* see md_server_loop() */ |
371 | /* no biodone in this case */ | | 371 | /* no biodone in this case */ |
372 | return; | | 372 | return; |
| @@ -399,27 +399,28 @@ mdstrategy(struct buf *bp) | | | @@ -399,27 +399,28 @@ mdstrategy(struct buf *bp) |
399 | bp->b_error = EIO; | | 399 | bp->b_error = EIO; |
400 | break; | | 400 | break; |
401 | } | | 401 | } |
402 | done: | | 402 | done: |
403 | biodone(bp); | | 403 | biodone(bp); |
404 | } | | 404 | } |
405 | | | 405 | |
406 | static int | | 406 | static int |
407 | mdioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) | | 407 | mdioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) |
408 | { | | 408 | { |
409 | struct md_softc *sc; | | 409 | struct md_softc *sc; |
410 | struct md_conf *umd; | | 410 | struct md_conf *umd; |
411 | | | 411 | |
412 | sc = device_lookup_private(&md_cd, MD_UNIT(dev)); | | 412 | if ((sc = device_lookup_private(&md_cd, MD_UNIT(dev))) == NULL) |
| | | 413 | return ENXIO; |
413 | | | 414 | |
414 | /* If this is not the raw partition, punt! */ | | 415 | /* If this is not the raw partition, punt! */ |
415 | if (DISKPART(dev) != RAW_PART) | | 416 | if (DISKPART(dev) != RAW_PART) |
416 | return ENOTTY; | | 417 | return ENOTTY; |
417 | | | 418 | |
418 | umd = (struct md_conf *)data; | | 419 | umd = (struct md_conf *)data; |
419 | switch (cmd) { | | 420 | switch (cmd) { |
420 | case MD_GETCONF: | | 421 | case MD_GETCONF: |
421 | *umd = sc->sc_md; | | 422 | *umd = sc->sc_md; |
422 | return 0; | | 423 | return 0; |
423 | | | 424 | |
424 | case MD_SETCONF: | | 425 | case MD_SETCONF: |
425 | /* Can only set it once. */ | | 426 | /* Can only set it once. */ |