| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: wd.c,v 1.374 2009/05/15 23:49:28 dyoung Exp $ */ | | 1 | /* $NetBSD: wd.c,v 1.375 2009/05/19 19:56:10 dyoung Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. | | 4 | * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. |
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 | * 3. All advertising materials mentioning features or use of this software | | 14 | * 3. All advertising materials mentioning features or use of this software |
| @@ -49,27 +49,27 @@ | | | @@ -49,27 +49,27 @@ |
49 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 49 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
50 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 50 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
51 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 51 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
52 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 52 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
53 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 53 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
54 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 54 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
55 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 55 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
56 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 56 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
57 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 57 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
58 | * POSSIBILITY OF SUCH DAMAGE. | | 58 | * POSSIBILITY OF SUCH DAMAGE. |
59 | */ | | 59 | */ |
60 | | | 60 | |
61 | #include <sys/cdefs.h> | | 61 | #include <sys/cdefs.h> |
62 | __KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.374 2009/05/15 23:49:28 dyoung Exp $"); | | 62 | __KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.375 2009/05/19 19:56:10 dyoung Exp $"); |
63 | | | 63 | |
64 | #include "opt_ata.h" | | 64 | #include "opt_ata.h" |
65 | | | 65 | |
66 | #include "rnd.h" | | 66 | #include "rnd.h" |
67 | | | 67 | |
68 | #include <sys/param.h> | | 68 | #include <sys/param.h> |
69 | #include <sys/systm.h> | | 69 | #include <sys/systm.h> |
70 | #include <sys/kernel.h> | | 70 | #include <sys/kernel.h> |
71 | #include <sys/conf.h> | | 71 | #include <sys/conf.h> |
72 | #include <sys/file.h> | | 72 | #include <sys/file.h> |
73 | #include <sys/stat.h> | | 73 | #include <sys/stat.h> |
74 | #include <sys/ioctl.h> | | 74 | #include <sys/ioctl.h> |
75 | #include <sys/buf.h> | | 75 | #include <sys/buf.h> |
| @@ -119,36 +119,35 @@ __KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.374 | | | @@ -119,36 +119,35 @@ __KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.374 |
119 | #define DEBUG_PROBE 0x10 | | 119 | #define DEBUG_PROBE 0x10 |
120 | #ifdef ATADEBUG | | 120 | #ifdef ATADEBUG |
121 | int wdcdebug_wd_mask = 0x0; | | 121 | int wdcdebug_wd_mask = 0x0; |
122 | #define ATADEBUG_PRINT(args, level) \ | | 122 | #define ATADEBUG_PRINT(args, level) \ |
123 | if (wdcdebug_wd_mask & (level)) \ | | 123 | if (wdcdebug_wd_mask & (level)) \ |
124 | printf args | | 124 | printf args |
125 | #else | | 125 | #else |
126 | #define ATADEBUG_PRINT(args, level) | | 126 | #define ATADEBUG_PRINT(args, level) |
127 | #endif | | 127 | #endif |
128 | | | 128 | |
129 | int wdprobe(device_t, cfdata_t, void *); | | 129 | int wdprobe(device_t, cfdata_t, void *); |
130 | void wdattach(device_t, device_t, void *); | | 130 | void wdattach(device_t, device_t, void *); |
131 | int wddetach(device_t, int); | | 131 | int wddetach(device_t, int); |
132 | int wdactivate(device_t, enum devact); | | | |
133 | int wdprint(void *, char *); | | 132 | int wdprint(void *, char *); |
134 | void wdperror(const struct wd_softc *); | | 133 | void wdperror(const struct wd_softc *); |
135 | | | 134 | |
136 | static void wdlastclose(struct wd_softc *); | | 135 | static void wdlastclose(struct wd_softc *); |
137 | static bool wd_suspend(device_t PMF_FN_PROTO); | | 136 | static bool wd_suspend(device_t PMF_FN_PROTO); |
138 | static int wd_standby(struct wd_softc *, int); | | 137 | static int wd_standby(struct wd_softc *, int); |
139 | | | 138 | |
140 | CFATTACH_DECL3_NEW(wd, sizeof(struct wd_softc), | | 139 | CFATTACH_DECL3_NEW(wd, sizeof(struct wd_softc), |
141 | wdprobe, wdattach, wddetach, wdactivate, NULL, NULL, DVF_DETACH_SHUTDOWN); | | 140 | wdprobe, wdattach, wddetach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN); |
142 | | | 141 | |
143 | extern struct cfdriver wd_cd; | | 142 | extern struct cfdriver wd_cd; |
144 | | | 143 | |
145 | dev_type_open(wdopen); | | 144 | dev_type_open(wdopen); |
146 | dev_type_close(wdclose); | | 145 | dev_type_close(wdclose); |
147 | dev_type_read(wdread); | | 146 | dev_type_read(wdread); |
148 | dev_type_write(wdwrite); | | 147 | dev_type_write(wdwrite); |
149 | dev_type_ioctl(wdioctl); | | 148 | dev_type_ioctl(wdioctl); |
150 | dev_type_strategy(wdstrategy); | | 149 | dev_type_strategy(wdstrategy); |
151 | dev_type_dump(wddump); | | 150 | dev_type_dump(wddump); |
152 | dev_type_size(wdsize); | | 151 | dev_type_size(wdsize); |
153 | | | 152 | |
154 | const struct bdevsw wd_bdevsw = { | | 153 | const struct bdevsw wd_bdevsw = { |
| @@ -425,45 +424,26 @@ wdattach(device_t parent, device_t self, | | | @@ -425,45 +424,26 @@ wdattach(device_t parent, device_t self, |
425 | } | | 424 | } |
426 | | | 425 | |
427 | static bool | | 426 | static bool |
428 | wd_suspend(device_t dv PMF_FN_ARGS) | | 427 | wd_suspend(device_t dv PMF_FN_ARGS) |
429 | { | | 428 | { |
430 | struct wd_softc *sc = device_private(dv); | | 429 | struct wd_softc *sc = device_private(dv); |
431 | | | 430 | |
432 | wd_flushcache(sc, AT_WAIT); | | 431 | wd_flushcache(sc, AT_WAIT); |
433 | wd_standby(sc, AT_WAIT); | | 432 | wd_standby(sc, AT_WAIT); |
434 | return true; | | 433 | return true; |
435 | } | | 434 | } |
436 | | | 435 | |
437 | int | | 436 | int |
438 | wdactivate(device_t self, enum devact act) | | | |
439 | { | | | |
440 | int rv = 0; | | | |
441 | | | | |
442 | switch (act) { | | | |
443 | case DVACT_ACTIVATE: | | | |
444 | rv = EOPNOTSUPP; | | | |
445 | break; | | | |
446 | | | | |
447 | case DVACT_DEACTIVATE: | | | |
448 | /* | | | |
449 | * Nothing to do; we key off the device's DVF_ACTIVATE. | | | |
450 | */ | | | |
451 | break; | | | |
452 | } | | | |
453 | return (rv); | | | |
454 | } | | | |
455 | | | | |
456 | int | | | |
457 | wddetach(device_t self, int flags) | | 437 | wddetach(device_t self, int flags) |
458 | { | | 438 | { |
459 | struct wd_softc *sc = device_private(self); | | 439 | struct wd_softc *sc = device_private(self); |
460 | int bmaj, cmaj, i, mn, rc, s; | | 440 | int bmaj, cmaj, i, mn, rc, s; |
461 | | | 441 | |
462 | rc = 0; | | 442 | rc = 0; |
463 | mutex_enter(&sc->sc_dk.dk_openlock); | | 443 | mutex_enter(&sc->sc_dk.dk_openlock); |
464 | if (sc->sc_dk.dk_openmask == 0) | | 444 | if (sc->sc_dk.dk_openmask == 0) |
465 | ; /* nothing to do */ | | 445 | ; /* nothing to do */ |
466 | else if ((flags & DETACH_FORCE) == 0) | | 446 | else if ((flags & DETACH_FORCE) == 0) |
467 | rc = EBUSY; | | 447 | rc = EBUSY; |
468 | else | | 448 | else |
469 | wdlastclose(sc); | | 449 | wdlastclose(sc); |
| @@ -538,28 +518,30 @@ wdstrategy(struct buf *bp) | | | @@ -538,28 +518,30 @@ wdstrategy(struct buf *bp) |
538 | int s; | | 518 | int s; |
539 | | | 519 | |
540 | ATADEBUG_PRINT(("wdstrategy (%s)\n", device_xname(wd->sc_dev)), | | 520 | ATADEBUG_PRINT(("wdstrategy (%s)\n", device_xname(wd->sc_dev)), |
541 | DEBUG_XFERS); | | 521 | DEBUG_XFERS); |
542 | | | 522 | |
543 | /* Valid request? */ | | 523 | /* Valid request? */ |
544 | if (bp->b_blkno < 0 || | | 524 | if (bp->b_blkno < 0 || |
545 | (bp->b_bcount % lp->d_secsize) != 0 || | | 525 | (bp->b_bcount % lp->d_secsize) != 0 || |
546 | (bp->b_bcount / lp->d_secsize) >= (1 << NBBY)) { | | 526 | (bp->b_bcount / lp->d_secsize) >= (1 << NBBY)) { |
547 | bp->b_error = EINVAL; | | 527 | bp->b_error = EINVAL; |
548 | goto done; | | 528 | goto done; |
549 | } | | 529 | } |
550 | | | 530 | |
551 | /* If device invalidated (e.g. media change, door open), error. */ | | 531 | /* If device invalidated (e.g. media change, door open, |
552 | if ((wd->sc_flags & WDF_LOADED) == 0) { | | 532 | * device suspension), then error. |
| | | 533 | */ |
| | | 534 | if ((wd->sc_flags & WDF_LOADED) == 0 || !device_is_active(wd->sc_dev)) { |
553 | bp->b_error = EIO; | | 535 | bp->b_error = EIO; |
554 | goto done; | | 536 | goto done; |
555 | } | | 537 | } |
556 | | | 538 | |
557 | /* If it's a null transfer, return immediately. */ | | 539 | /* If it's a null transfer, return immediately. */ |
558 | if (bp->b_bcount == 0) | | 540 | if (bp->b_bcount == 0) |
559 | goto done; | | 541 | goto done; |
560 | | | 542 | |
561 | /* | | 543 | /* |
562 | * Do bounds checking, adjust transfer. if error, process. | | 544 | * Do bounds checking, adjust transfer. if error, process. |
563 | * If end of partition, just return. | | 545 | * If end of partition, just return. |
564 | */ | | 546 | */ |
565 | if (WDPART(bp->b_dev) == RAW_PART) { | | 547 | if (WDPART(bp->b_dev) == RAW_PART) { |