1*6a602769Sragge /* $NetBSD: hp.c,v 1.54 2017/05/22 17:13:09 ragge Exp $ */
265c1cb99Sragge /*
3435182d4Sragge * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
465c1cb99Sragge * All rights reserved.
565c1cb99Sragge *
665c1cb99Sragge * Redistribution and use in source and binary forms, with or without
765c1cb99Sragge * modification, are permitted provided that the following conditions
865c1cb99Sragge * are met:
965c1cb99Sragge * 1. Redistributions of source code must retain the above copyright
1065c1cb99Sragge * notice, this list of conditions and the following disclaimer.
1165c1cb99Sragge * 2. Redistributions in binary form must reproduce the above copyright
1265c1cb99Sragge * notice, this list of conditions and the following disclaimer in the
1365c1cb99Sragge * documentation and/or other materials provided with the distribution.
1465c1cb99Sragge *
1565c1cb99Sragge * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1665c1cb99Sragge * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1765c1cb99Sragge * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1865c1cb99Sragge * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1965c1cb99Sragge * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2065c1cb99Sragge * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2165c1cb99Sragge * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2265c1cb99Sragge * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2365c1cb99Sragge * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2465c1cb99Sragge * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2565c1cb99Sragge */
2665c1cb99Sragge
27435182d4Sragge /*
28435182d4Sragge * Simple device driver routine for massbuss disks.
29435182d4Sragge * TODO:
30435182d4Sragge * Fix support for Standard DEC BAD144 bad block forwarding.
31435182d4Sragge * Be able to to handle soft/hard transfer errors.
32435182d4Sragge * Handle non-data transfer interrupts.
33435182d4Sragge * Autoconfiguration of disk drives 'on the fly'.
34435182d4Sragge * Handle disk media changes.
35435182d4Sragge * Dual-port operations should be supported.
36435182d4Sragge */
373b4fb6d0Slukem
383b4fb6d0Slukem #include <sys/cdefs.h>
39*6a602769Sragge __KERNEL_RCSID(0, "$NetBSD: hp.c,v 1.54 2017/05/22 17:13:09 ragge Exp $");
403b4fb6d0Slukem
419d9a70a5Smycroft #include <sys/param.h>
42a24af7a7Sragge #include <sys/systm.h>
4306386a01Smatt #include <sys/bus.h>
4406386a01Smatt #include <sys/cpu.h>
45435182d4Sragge #include <sys/device.h>
46435182d4Sragge #include <sys/disklabel.h>
47435182d4Sragge #include <sys/disk.h>
48435182d4Sragge #include <sys/dkio.h>
49435182d4Sragge #include <sys/buf.h>
5005f25dccSyamt #include <sys/bufq.h>
51435182d4Sragge #include <sys/stat.h>
52435182d4Sragge #include <sys/ioccom.h>
539d9a70a5Smycroft #include <sys/fcntl.h>
54db7db145Sragge #include <sys/conf.h>
55e0cc03a0Sjdolecek #include <sys/event.h>
5606386a01Smatt #include <sys/syslog.h>
57435182d4Sragge
589d9a70a5Smycroft #include <vax/mba/mbavar.h>
59435182d4Sragge #include <vax/mba/mbareg.h>
60435182d4Sragge #include <vax/mba/hpreg.h>
610103e26fSmycroft
62db7db145Sragge #include "ioconf.h"
639388f271Sjtk #include "locators.h"
649388f271Sjtk
65435182d4Sragge struct hp_softc {
66dfba8166Smatt device_t sc_dev;
67435182d4Sragge struct disk sc_disk;
68db7db145Sragge bus_space_tag_t sc_iot;
69db7db145Sragge bus_space_handle_t sc_ioh;
70435182d4Sragge struct mba_device sc_md; /* Common struct used by mbaqueue. */
711376f92dSragge int sc_wlabel; /* Disklabel area is writable */
7265c1cb99Sragge };
7365c1cb99Sragge
74dfba8166Smatt int hpmatch(device_t, cfdata_t, void *);
75dfba8166Smatt void hpattach(device_t, device_t, void *);
76db7db145Sragge void hpstart(struct mba_device *);
77db7db145Sragge int hpattn(struct mba_device *);
78db7db145Sragge enum xfer_action hpfinish(struct mba_device *, int, int *);
79435182d4Sragge
80dfba8166Smatt CFATTACH_DECL_NEW(hp, sizeof(struct hp_softc),
814bf871a7Sthorpej hpmatch, hpattach, NULL, NULL);
8265c1cb99Sragge
83dfba8166Smatt static dev_type_open(hpopen);
84dfba8166Smatt static dev_type_close(hpclose);
85dfba8166Smatt static dev_type_read(hpread);
86dfba8166Smatt static dev_type_write(hpwrite);
87dfba8166Smatt static dev_type_ioctl(hpioctl);
88dfba8166Smatt static dev_type_strategy(hpstrategy);
89dfba8166Smatt static dev_type_size(hppsize);
9077a6b82bSgehenna
9177a6b82bSgehenna const struct bdevsw hp_bdevsw = {
92dfba8166Smatt .d_open = hpopen,
93dfba8166Smatt .d_close = hpclose,
94dfba8166Smatt .d_strategy = hpstrategy,
95dfba8166Smatt .d_ioctl = hpioctl,
96dfba8166Smatt .d_dump = nulldump,
97dfba8166Smatt .d_psize = hppsize,
988c70ef39Sdholland .d_discard = nodiscard,
99dfba8166Smatt .d_flag = D_DISK
10077a6b82bSgehenna };
10177a6b82bSgehenna
10277a6b82bSgehenna const struct cdevsw hp_cdevsw = {
103dfba8166Smatt .d_open = hpopen,
104dfba8166Smatt .d_close = hpclose,
105dfba8166Smatt .d_read = hpread,
106dfba8166Smatt .d_write = hpwrite,
107dfba8166Smatt .d_ioctl = hpioctl,
108dfba8166Smatt .d_stop = nostop,
109dfba8166Smatt .d_tty = notty,
110dfba8166Smatt .d_poll = nopoll,
111dfba8166Smatt .d_mmap = nommap,
112dfba8166Smatt .d_kqfilter = nokqfilter,
113f9228f42Sdholland .d_discard = nodiscard,
114dfba8166Smatt .d_flag = D_DISK
11577a6b82bSgehenna };
11677a6b82bSgehenna
117db7db145Sragge #define HP_WCSR(reg, val) \
118db7db145Sragge bus_space_write_4(sc->sc_iot, sc->sc_ioh, (reg), (val))
119db7db145Sragge #define HP_RCSR(reg) \
120db7db145Sragge bus_space_read_4(sc->sc_iot, sc->sc_ioh, (reg))
121db7db145Sragge
122f32f9470Sthorpej
123435182d4Sragge /*
124435182d4Sragge * Check if this is a disk drive; done by checking type from mbaattach.
125435182d4Sragge */
126435182d4Sragge int
hpmatch(device_t parent,cfdata_t cf,void * aux)127dfba8166Smatt hpmatch(device_t parent, cfdata_t cf, void *aux)
12865c1cb99Sragge {
129dfba8166Smatt struct mba_attach_args * const ma = aux;
130435182d4Sragge
1319388f271Sjtk if (cf->cf_loc[MBACF_DRIVE] != MBACF_DRIVE_DEFAULT &&
132db7db145Sragge cf->cf_loc[MBACF_DRIVE] != ma->ma_unit)
133435182d4Sragge return 0;
134435182d4Sragge
135db7db145Sragge if (ma->ma_devtyp != MB_RP)
136435182d4Sragge return 0;
137435182d4Sragge
138435182d4Sragge return 1;
139435182d4Sragge }
14065c1cb99Sragge
14165c1cb99Sragge /*
142435182d4Sragge * Disk drive found; fake a disklabel and try to read the real one.
143435182d4Sragge * If the on-disk label can't be read; we lose.
14465c1cb99Sragge */
145435182d4Sragge void
hpattach(device_t parent,device_t self,void * aux)146dfba8166Smatt hpattach(device_t parent, device_t self, void *aux)
14765c1cb99Sragge {
148dfba8166Smatt struct hp_softc * const sc = device_private(self);
149dfba8166Smatt struct mba_softc * const ms = device_private(parent);
150dfba8166Smatt struct mba_attach_args * const ma = aux;
151435182d4Sragge struct disklabel *dl;
152d91455ceSdsl const char *msg;
15365c1cb99Sragge
154dfba8166Smatt sc->sc_dev = self;
155db7db145Sragge sc->sc_iot = ma->ma_iot;
156db7db145Sragge sc->sc_ioh = ma->ma_ioh;
157dfba8166Smatt
15865c1cb99Sragge /*
159435182d4Sragge * Init the common struct for both the adapter and its slaves.
16065c1cb99Sragge */
161aec75b1cSyamt bufq_alloc(&sc->sc_md.md_q, "disksort", BUFQ_SORT_CYLINDER);
162dfba8166Smatt sc->sc_md.md_softc = sc; /* Pointer to this softc */
163dfba8166Smatt sc->sc_md.md_mba = ms; /* Pointer to parent softc */
164435182d4Sragge sc->sc_md.md_start = hpstart; /* Disk start routine */
165435182d4Sragge sc->sc_md.md_attn = hpattn; /* Disk attention routine */
166435182d4Sragge sc->sc_md.md_finish = hpfinish; /* Disk xfer finish routine */
167435182d4Sragge
168db7db145Sragge ms->sc_md[ma->ma_unit] = &sc->sc_md; /* Per-unit backpointer */
169435182d4Sragge
170435182d4Sragge /*
171435182d4Sragge * Init and attach the disk structure.
172435182d4Sragge */
173dfba8166Smatt disk_init(&sc->sc_disk, device_xname(sc->sc_dev), NULL);
174435182d4Sragge disk_attach(&sc->sc_disk);
175435182d4Sragge
176435182d4Sragge /*
177435182d4Sragge * Fake a disklabel to be able to read in the real label.
178435182d4Sragge */
179435182d4Sragge dl = sc->sc_disk.dk_label;
180435182d4Sragge
181435182d4Sragge dl->d_secsize = DEV_BSIZE;
182435182d4Sragge dl->d_ntracks = 1;
183435182d4Sragge dl->d_nsectors = 32;
184435182d4Sragge dl->d_secpercyl = 32;
185435182d4Sragge
186435182d4Sragge /*
187435182d4Sragge * Read in label.
188435182d4Sragge */
18939cd836eSthorpej if ((msg = readdisklabel(makedev(0, device_unit(self) * 8), hpstrategy,
190435182d4Sragge dl, NULL)) != NULL)
191e37692f0Schristos printf(": %s", msg);
192e37692f0Schristos printf(": %s, size = %d sectors\n", dl->d_typename, dl->d_secperunit);
19365c1cb99Sragge }
19465c1cb99Sragge
195435182d4Sragge
196435182d4Sragge void
hpstrategy(struct buf * bp)197db7db145Sragge hpstrategy(struct buf *bp)
19865c1cb99Sragge {
199435182d4Sragge struct hp_softc *sc;
200435182d4Sragge struct buf *gp;
201fe551f0eSthorpej struct disklabel *lp;
202dfba8166Smatt int unit, s, err;
20365c1cb99Sragge
204435182d4Sragge unit = DISKUNIT(bp->b_dev);
205dfba8166Smatt sc = device_lookup_private(&hp_cd, unit);
206fe551f0eSthorpej lp = sc->sc_disk.dk_label;
20765c1cb99Sragge
208e43fecb2Sthorpej err = bounds_check_with_label(&sc->sc_disk, bp, sc->sc_wlabel);
209aec10dd8Sbouyer if (err <= 0)
210435182d4Sragge goto done;
211fe551f0eSthorpej
212fe551f0eSthorpej bp->b_rawblkno =
213fe551f0eSthorpej bp->b_blkno + lp->d_partitions[DISKPART(bp->b_dev)].p_offset;
214fe551f0eSthorpej bp->b_cylinder = bp->b_rawblkno / lp->d_secpercyl;
215fe551f0eSthorpej
216435182d4Sragge s = splbio();
217435182d4Sragge
21870de9736Syamt gp = bufq_peek(sc->sc_md.md_q);
21970de9736Syamt bufq_put(sc->sc_md.md_q, bp);
220435182d4Sragge if (gp == 0)
221435182d4Sragge mbaqueue(&sc->sc_md);
222435182d4Sragge
223435182d4Sragge splx(s);
224435182d4Sragge return;
225435182d4Sragge
226435182d4Sragge done:
227435182d4Sragge bp->b_resid = bp->b_bcount;
22865c1cb99Sragge biodone(bp);
22965c1cb99Sragge }
23065c1cb99Sragge
23165c1cb99Sragge /*
232435182d4Sragge * Start transfer on given disk. Called from mbastart().
23365c1cb99Sragge */
234435182d4Sragge void
hpstart(struct mba_device * md)235db7db145Sragge hpstart(struct mba_device *md)
23665c1cb99Sragge {
237dfba8166Smatt struct hp_softc * const sc = md->md_softc;
238dfba8166Smatt struct disklabel * const lp = sc->sc_disk.dk_label;
23970de9736Syamt struct buf *bp = bufq_peek(md->md_q);
240435182d4Sragge unsigned bn, cn, sn, tn;
24165c1cb99Sragge
24265c1cb99Sragge /*
243435182d4Sragge * Collect statistics.
24465c1cb99Sragge */
245435182d4Sragge disk_busy(&sc->sc_disk);
24606d42ba2She iostat_seek(sc->sc_disk.dk_stats);
247435182d4Sragge
248fe551f0eSthorpej bn = bp->b_rawblkno;
249435182d4Sragge if (bn) {
250435182d4Sragge cn = bn / lp->d_secpercyl;
251435182d4Sragge sn = bn % lp->d_secpercyl;
252435182d4Sragge tn = sn / lp->d_nsectors;
253435182d4Sragge sn = sn % lp->d_nsectors;
254435182d4Sragge } else
255435182d4Sragge cn = sn = tn = 0;
256435182d4Sragge
257db7db145Sragge HP_WCSR(HP_DC, cn);
258db7db145Sragge HP_WCSR(HP_DA, (tn << 8) | sn);
259435182d4Sragge if (bp->b_flags & B_READ)
260db7db145Sragge HP_WCSR(HP_CS1, HPCS_READ);
261435182d4Sragge else
262db7db145Sragge HP_WCSR(HP_CS1, HPCS_WRITE);
263435182d4Sragge }
264435182d4Sragge
265435182d4Sragge int
hpopen(dev_t dev,int flag,int fmt,struct lwp * l)26695e1ffb1Schristos hpopen(dev_t dev, int flag, int fmt, struct lwp *l)
267435182d4Sragge {
268435182d4Sragge struct hp_softc *sc;
269dfba8166Smatt int part = DISKPART(dev);
270435182d4Sragge
271dfba8166Smatt sc = device_lookup_private(&hp_cd, DISKUNIT(dev));
272dfba8166Smatt if (sc == NULL)
273435182d4Sragge return ENXIO;
274435182d4Sragge
2752aa22f8fSragge if (part >= sc->sc_disk.dk_label->d_npartitions)
276435182d4Sragge return ENXIO;
277435182d4Sragge
278435182d4Sragge switch (fmt) {
279435182d4Sragge case S_IFCHR:
280435182d4Sragge sc->sc_disk.dk_copenmask |= (1 << part);
281435182d4Sragge break;
282435182d4Sragge
283435182d4Sragge case S_IFBLK:
284435182d4Sragge sc->sc_disk.dk_bopenmask |= (1 << part);
285435182d4Sragge break;
286435182d4Sragge }
287435182d4Sragge sc->sc_disk.dk_openmask =
288435182d4Sragge sc->sc_disk.dk_copenmask | sc->sc_disk.dk_bopenmask;
289435182d4Sragge
290435182d4Sragge return 0;
291435182d4Sragge }
292435182d4Sragge
293435182d4Sragge int
hpclose(dev_t dev,int flag,int fmt,struct lwp * l)29495e1ffb1Schristos hpclose(dev_t dev, int flag, int fmt, struct lwp *l)
295435182d4Sragge {
296dfba8166Smatt struct hp_softc * const sc = device_lookup_private(&hp_cd, DISKUNIT(dev));
297dfba8166Smatt const int part = DISKPART(dev);
298435182d4Sragge
299435182d4Sragge switch (fmt) {
300435182d4Sragge case S_IFCHR:
301435182d4Sragge sc->sc_disk.dk_copenmask &= ~(1 << part);
302435182d4Sragge break;
303435182d4Sragge
304435182d4Sragge case S_IFBLK:
305435182d4Sragge sc->sc_disk.dk_bopenmask &= ~(1 << part);
306435182d4Sragge break;
307435182d4Sragge }
308435182d4Sragge sc->sc_disk.dk_openmask =
309435182d4Sragge sc->sc_disk.dk_copenmask | sc->sc_disk.dk_bopenmask;
310435182d4Sragge
311435182d4Sragge return 0;
312435182d4Sragge }
313435182d4Sragge
314435182d4Sragge int
hpioctl(dev_t dev,u_long cmd,void * addr,int flag,struct lwp * l)31553524e44Schristos hpioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l)
316435182d4Sragge {
317dfba8166Smatt struct hp_softc * const sc = device_lookup_private(&hp_cd, DISKUNIT(dev));
318dfba8166Smatt struct disklabel * const lp = sc->sc_disk.dk_label;
3192aa22f8fSragge int error;
320435182d4Sragge
321c60db2e9Schristos error = disk_ioctl(&sc->sc_disk, dev, cmd, addr, flag, l);
322c60db2e9Schristos if (error != EPASSTHROUGH)
323d1cb0983Schristos return error;
324c60db2e9Schristos
325435182d4Sragge switch (cmd) {
326435182d4Sragge case DIOCSDINFO:
327435182d4Sragge if ((flag & FWRITE) == 0)
328435182d4Sragge return EBADF;
329435182d4Sragge
330435182d4Sragge return setdisklabel(lp, (struct disklabel *)addr, 0, 0);
331435182d4Sragge
332435182d4Sragge case DIOCWDINFO:
333435182d4Sragge if ((flag & FWRITE) == 0)
3342aa22f8fSragge error = EBADF;
3352aa22f8fSragge else {
3362aa22f8fSragge sc->sc_wlabel = 1;
3372aa22f8fSragge error = writedisklabel(dev, hpstrategy, lp, 0);
3382aa22f8fSragge sc->sc_wlabel = 0;
3392aa22f8fSragge }
3402aa22f8fSragge return error;
3411376f92dSragge case DIOCWLABEL:
3421376f92dSragge if ((flag & FWRITE) == 0)
3431376f92dSragge return EBADF;
3441376f92dSragge sc->sc_wlabel = 1;
3451376f92dSragge break;
346435182d4Sragge
347435182d4Sragge default:
348435182d4Sragge return ENOTTY;
349435182d4Sragge }
3501376f92dSragge return 0;
35165c1cb99Sragge }
35265c1cb99Sragge
35365c1cb99Sragge /*
354435182d4Sragge * Called when a transfer is finished. Check if transfer went OK,
355435182d4Sragge * Return info about what-to-do-now.
35665c1cb99Sragge */
357435182d4Sragge enum xfer_action
hpfinish(struct mba_device * md,int mbasr,int * attn)358db7db145Sragge hpfinish(struct mba_device *md, int mbasr, int *attn)
359435182d4Sragge {
360dfba8166Smatt struct hp_softc * const sc = md->md_softc;
36170de9736Syamt struct buf *bp = bufq_peek(md->md_q);
362db7db145Sragge int er1, er2, bc;
363435182d4Sragge unsigned byte;
364435182d4Sragge
365db7db145Sragge er1 = HP_RCSR(HP_ER1);
366db7db145Sragge er2 = HP_RCSR(HP_ER2);
367db7db145Sragge HP_WCSR(HP_ER1, 0);
368db7db145Sragge HP_WCSR(HP_ER2, 0);
369db7db145Sragge
370435182d4Sragge hper1:
371435182d4Sragge switch (ffs(er1) - 1) {
372435182d4Sragge case -1:
373db7db145Sragge HP_WCSR(HP_ER1, 0);
374435182d4Sragge goto hper2;
375435182d4Sragge
376435182d4Sragge case HPER1_DCK: /* Corrected? data read. Just notice. */
377db7db145Sragge bc = bus_space_read_4(md->md_mba->sc_iot,
378db7db145Sragge md->md_mba->sc_ioh, MBA_BC);
379435182d4Sragge byte = ~(bc >> 16);
38020ad8911Spk diskerr(bp, hp_cd.cd_name, "soft ecc", LOG_PRINTF,
381435182d4Sragge btodb(bp->b_bcount - byte), sc->sc_disk.dk_label);
382435182d4Sragge er1 &= ~(1<<HPER1_DCK);
383435182d4Sragge break;
384435182d4Sragge
385435182d4Sragge default:
386dfba8166Smatt aprint_error_dev(sc->sc_dev, "drive error: er1 %x er2 %x\n",
387dfba8166Smatt er1, er2);
388db7db145Sragge HP_WCSR(HP_ER1, 0);
389db7db145Sragge HP_WCSR(HP_ER2, 0);
390435182d4Sragge goto hper2;
39165c1cb99Sragge }
392435182d4Sragge goto hper1;
393435182d4Sragge
394435182d4Sragge hper2:
395435182d4Sragge mbasr &= ~(MBASR_DTBUSY|MBASR_DTCMP|MBASR_ATTN);
396435182d4Sragge if (mbasr)
397dfba8166Smatt aprint_error_dev(sc->sc_dev, "massbuss error: %x\n", mbasr);
398435182d4Sragge
39970de9736Syamt bufq_peek(md->md_q)->b_resid = 0;
40070de9736Syamt disk_unbusy(&sc->sc_disk, bufq_peek(md->md_q)->b_bcount,
401603098b9Smrg (bp->b_flags & B_READ));
402435182d4Sragge return XFER_FINISH;
403435182d4Sragge }
404435182d4Sragge
405435182d4Sragge /*
406435182d4Sragge * Non-data transfer interrupt; like volume change.
407435182d4Sragge */
408435182d4Sragge int
hpattn(struct mba_device * md)409db7db145Sragge hpattn(struct mba_device *md)
410435182d4Sragge {
411dfba8166Smatt struct hp_softc * const sc = md->md_softc;
412435182d4Sragge int er1, er2;
413435182d4Sragge
414db7db145Sragge er1 = HP_RCSR(HP_ER1);
415db7db145Sragge er2 = HP_RCSR(HP_ER2);
416435182d4Sragge
417dfba8166Smatt aprint_error_dev(sc->sc_dev, "Attention! er1 %x er2 %x\n", er1, er2);
418435182d4Sragge return 0;
419435182d4Sragge }
420435182d4Sragge
421435182d4Sragge
422435182d4Sragge int
hppsize(dev_t dev)423dfba8166Smatt hppsize(dev_t dev)
424435182d4Sragge {
425dfba8166Smatt struct hp_softc * const sc = device_lookup_private(&hp_cd, DISKUNIT(dev));
426dfba8166Smatt const int part = DISKPART(dev);
427435182d4Sragge
428dfba8166Smatt if (sc == NULL || part >= sc->sc_disk.dk_label->d_npartitions)
429435182d4Sragge return -1;
430435182d4Sragge
431dfba8166Smatt return sc->sc_disk.dk_label->d_partitions[part].p_size *
432cf016f61Sthorpej (sc->sc_disk.dk_label->d_secsize / DEV_BSIZE);
433435182d4Sragge }
434435182d4Sragge
435435182d4Sragge int
hpread(dev_t dev,struct uio * uio,int ioflag)436db7db145Sragge hpread(dev_t dev, struct uio *uio, int ioflag)
437435182d4Sragge {
438435182d4Sragge return (physio(hpstrategy, NULL, dev, B_READ, minphys, uio));
439435182d4Sragge }
440435182d4Sragge
441435182d4Sragge int
hpwrite(dev_t dev,struct uio * uio,int ioflag)442db7db145Sragge hpwrite(dev_t dev, struct uio *uio, int ioflag)
443435182d4Sragge {
444435182d4Sragge return (physio(hpstrategy, NULL, dev, B_WRITE, minphys, uio));
445435182d4Sragge }
446