4 * Copyright (c) 2009 Jared D. McNeill <jmcneill@invisible.ca>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
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
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
22 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 #include <sys/cdefs.h>
29 __KERNEL_RCSID(0, "$NetBSD$");
30 #include <sys/param.h>
31 #include <sys/types.h>
32 #include <sys/device.h>
35 #include <sys/disklabel.h>
38 #include <dev/altmem/altmemvar.h>
46 const struct altmem_memops
*sc_memops
;
51 static dev_type_open(altmemopen
);
52 static dev_type_close(altmemclose
);
53 static dev_type_read(altmemread
);
54 static dev_type_write(altmemwrite
);
55 static dev_type_ioctl(altmemioctl
);
56 static dev_type_strategy(altmemstrategy
);
57 static dev_type_size(altmemsize
);
59 static int altmem_match(device_t
, cfdata_t
, void *);
60 static void altmem_attach(device_t
, device_t
, void *);
62 const struct bdevsw altmem_bdevsw
= {
63 altmemopen
, altmemclose
, altmemstrategy
, altmemioctl
, nodump
,
66 const struct cdevsw altmem_cdevsw
= {
67 altmemopen
, altmemclose
, altmemread
, altmemwrite
, altmemioctl
,
68 nostop
, notty
, nopoll
, nommap
, nokqfilter
, D_DISK
70 static struct dkdriver altmemdkdriver
= { altmemstrategy
, minphys
};
71 extern struct cfdriver altmem_cd
;
73 CFATTACH_DECL_NEW(altmem
, sizeof(struct altmem_softc
), altmem_match
,
74 altmem_attach
, NULL
, NULL
);
77 altmem_match(device_t parent
, cfdata_t match
, void *opaque
)
83 altmem_attach(device_t parent
, device_t self
, void *opaque
)
85 struct altmem_softc
*sc
= device_private(self
);
86 struct altmem_attach_args
*aaa
= opaque
;
90 sc
->sc_cookie
= aaa
->cookie
;
91 sc
->sc_memops
= aaa
->memops
;
92 sc
->sc_size
= sc
->sc_memops
->getsize(sc
->sc_cookie
);
94 format_bytes(pbuf
, sizeof(pbuf
), sc
->sc_size
);
97 aprint_normal(": %s\n", pbuf
);
99 disk_init(&sc
->sc_dkdev
, device_xname(self
), &altmemdkdriver
);
100 disk_attach(&sc
->sc_dkdev
);
104 altmemsize(dev_t dev
)
106 struct altmem_softc
*sc
= device_lookup_private(&altmem_cd
, DISKUNIT(dev
));
109 return sc
->sc_size
>> DEV_BSHIFT
;
113 altmemopen(dev_t dev
, int flag
, int fmt
, struct lwp
*l
)
115 struct altmem_softc
*sc
= device_lookup_private(&altmem_cd
, DISKUNIT(dev
));
122 altmemclose(dev_t dev
, int flag
, int fmt
, struct lwp
*l
)
128 altmemread(dev_t dev
, struct uio
*uio
, int flags
)
130 if (device_lookup_private(&altmem_cd
, DISKUNIT(dev
)) == NULL
)
132 return physio(altmemstrategy
, NULL
, dev
, B_READ
, minphys
, uio
);
136 altmemwrite(dev_t dev
, struct uio
*uio
, int flags
)
138 if (device_lookup_private(&altmem_cd
, DISKUNIT(dev
)) == NULL
)
140 return physio(altmemstrategy
, NULL
, dev
, B_WRITE
, minphys
, uio
);
144 altmemstrategy(struct buf
*bp
)
146 struct altmem_softc
*sc
= device_lookup_private(&altmem_cd
, DISKUNIT(bp
->b_dev
));
153 if (bp
->b_bcount
== 0) {
158 sc
->sc_memops
->strategy(sc
->sc_cookie
, bp
);
163 altmemioctl(dev_t dev
, u_long cmd
, void *data
, int flag
, struct lwp
*l
)
165 struct altmem_softc
*sc
= device_lookup_private(&altmem_cd
, DISKUNIT(dev
));
166 struct dkwedge_info
*dkw
;
171 strlcpy(dkw
->dkw_devname
, device_xname(sc
->sc_dev
),
172 sizeof(dkw
->dkw_devname
));
173 strlcpy(dkw
->dkw_wname
, "altmem", sizeof(dkw
->dkw_wname
));
174 dkw
->dkw_parent
[0] = '\0';
176 dkw
->dkw_size
= sc
->sc_size
>> DEV_BSHIFT
;
177 strcpy(dkw
->dkw_ptype
, DKW_PTYPE_UNUSED
);