diff --git a/sys/conf/files b/sys/conf/files index a770ef89e0d4..dc9fd1b8ca91 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,4 +1,4 @@ -# $NetBSD: files,v 1.399 2000/11/05 17:17:13 onoe Exp $ +# $NetBSD: files,v 1.400 2000/11/08 19:20:33 ad Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 @@ -196,7 +196,7 @@ file dev/mii/mii_bitbang.c mii_bitbang # Logical storage unit device lsu: disk -file dev/lsu/lsu.c lsu needs-flag +file dev/lsu.c lsu needs-flag # Central clearing house for system monitoring. define sysmon_envsys @@ -235,7 +235,7 @@ device cac {unit = -1} file dev/ic/cac.c cac attach lsu at cac with lsu_cac -file dev/lsu/lsu_cac.c lsu_cac +file dev/ic/lsu_cac.c lsu_cac # AdvanSys 1200A, 1200B and ULTRA SCSI controllers device adv: scsi diff --git a/sys/dev/ic/cac.c b/sys/dev/ic/cac.c index 924621456401..d25b1d4477f5 100644 --- a/sys/dev/ic/cac.c +++ b/sys/dev/ic/cac.c @@ -1,4 +1,4 @@ -/* $NetBSD: cac.c,v 1.13 2000/10/19 14:28:46 ad Exp $ */ +/* $NetBSD: cac.c,v 1.14 2000/11/08 19:20:35 ad Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -171,6 +171,7 @@ cac_init(struct cac_softc *sc, const char *intrstr, int startfw) return (-1); } + sc->sc_nunits = cinfo.num_drvs; for (i = 0; i < cinfo.num_drvs; i++) { caca.caca_unit = i; config_found_sm(&sc->sc_dv, &caca, cac_print, cac_submatch); @@ -401,7 +402,9 @@ cac_ccb_start(struct cac_softc *sc, struct cac_ccb *ccb) static void cac_ccb_done(struct cac_softc *sc, struct cac_ccb *ccb) { + struct device *dv; const char *errdvn; + void *context; int error; error = 0; @@ -436,8 +439,10 @@ cac_ccb_done(struct cac_softc *sc, struct cac_ccb *ccb) } if (ccb->ccb_context.cc_handler != NULL) { - (*ccb->ccb_context.cc_handler)(ccb, error); + dv = ccb->ccb_context.cc_dv; + context = ccb->ccb_context.cc_context; cac_ccb_free(sc, ccb); + (*ccb->ccb_context.cc_handler)(dv, context, error); } } diff --git a/sys/dev/ic/cacvar.h b/sys/dev/ic/cacvar.h index 1caa5af85345..7101817e49a1 100644 --- a/sys/dev/ic/cacvar.h +++ b/sys/dev/ic/cacvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: cacvar.h,v 1.7 2000/10/19 14:28:47 ad Exp $ */ +/* $NetBSD: cacvar.h,v 1.8 2000/11/08 19:20:35 ad Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -74,7 +74,7 @@ struct cac_softc; struct cac_ccb; struct cac_context { - void (*cc_handler)(struct cac_ccb *, int); + void (*cc_handler)(struct device *, void *, int); struct device *cc_dv; void *cc_context; }; @@ -112,6 +112,7 @@ struct cac_softc { bus_space_handle_t sc_ioh; bus_dma_tag_t sc_dmat; bus_dmamap_t sc_dmamap; + int sc_nunits; void *sc_ih; const struct cac_linkage *sc_cl; caddr_t sc_ccbs; diff --git a/sys/dev/lsu/lsu_cac.c b/sys/dev/ic/lsu_cac.c similarity index 91% rename from sys/dev/lsu/lsu_cac.c rename to sys/dev/ic/lsu_cac.c index 491396a7e874..f8b5f0643340 100644 --- a/sys/dev/lsu/lsu_cac.c +++ b/sys/dev/ic/lsu_cac.c @@ -1,4 +1,4 @@ -/* $NetBSD: lsu_cac.c,v 1.1 2000/10/19 14:06:02 ad Exp $ */ +/* $NetBSD$ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -56,7 +56,7 @@ #include -#include +#include #include #include @@ -67,7 +67,7 @@ struct lsu_cac_softc { }; static void lsu_cac_attach(struct device *, struct device *, void *); -static void lsu_cac_done(struct cac_ccb *, int); +static void lsu_cac_done(struct device *, void *, int); static int lsu_cac_dump(struct lsu_softc *, void *, int, int); static int lsu_cac_match(struct device *, struct cfdata *, void *); static int lsu_cac_start(struct lsu_softc *, struct buf *); @@ -90,15 +90,17 @@ lsu_cac_attach(struct device *parent, struct device *self, void *aux) struct cac_attach_args *caca; struct lsu_softc *lsu; struct lsu_cac_softc *sc; + struct cac_softc *cac; const char *type; sc = (struct lsu_cac_softc *)self; lsu = &sc->sc_lsu; caca = (struct cac_attach_args *)aux; sc->sc_hwunit = caca->caca_unit; + cac = (struct cac_softc *)parent; - if (cac_cmd((struct cac_softc *)parent, CAC_CMD_GET_LOG_DRV_INFO, - &dinfo, sizeof(dinfo), sc->sc_hwunit, 0, CAC_CCB_DATA_IN, NULL)) { + if (cac_cmd(cac, CAC_CMD_GET_LOG_DRV_INFO, &dinfo, sizeof(dinfo), + sc->sc_hwunit, 0, CAC_CCB_DATA_IN, NULL)) { printf("%s: CMD_GET_LOG_DRV_INFO failed\n", self->dv_xname); return; } @@ -108,6 +110,7 @@ lsu_cac_attach(struct device *parent, struct device *self, void *aux) lsu->sc_nsectors = CAC_GET1(dinfo.nsectors); lsu->sc_secsize = CAC_GET2(dinfo.secsize); lsu->sc_maxxfer = CAC_MAX_XFER; + lsu->sc_maxqueuecnt = CAC_MAX_CCBS / cac->sc_nunits; /* XXX */ lsu->sc_secperunit = lsu->sc_ncylinders * lsu->sc_nheads * lsu->sc_nsectors; lsu->sc_start = lsu_cac_start; @@ -178,11 +181,11 @@ lsu_cac_dump(struct lsu_softc *lsu, void *data, int blkno, int blkcnt) } static void -lsu_cac_done(struct cac_ccb *ccb, int error) +lsu_cac_done(struct device *dv, void *context, int error) { struct buf *bp; - bp = ccb->ccb_context.cc_context; + bp = context; if (error) { bp->b_flags |= B_ERROR; @@ -191,5 +194,5 @@ lsu_cac_done(struct cac_ccb *ccb, int error) } else bp->b_resid = 0; - lsudone((struct lsu_softc *)ccb->ccb_context.cc_dv, bp); + lsudone((struct lsu_softc *)dv, bp); } diff --git a/sys/dev/lsu/lsu.c b/sys/dev/lsu.c similarity index 95% rename from sys/dev/lsu/lsu.c rename to sys/dev/lsu.c index 8483812615f8..0daf588e8ac4 100644 --- a/sys/dev/lsu/lsu.c +++ b/sys/dev/lsu.c @@ -1,4 +1,4 @@ -/* $NetBSD: lsu.c,v 1.1 2000/10/19 14:06:02 ad Exp $ */ +/* $NetBSD$ */ /*- * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ /* - * El-cheapo disk driver for use by RAID controllers. + * Disk driver for use by RAID controllers. */ #include "rnd.h" @@ -62,13 +62,14 @@ #include #endif -#include +#include static void lsugetdefaultlabel(struct lsu_softc *, struct disklabel *); static void lsugetdisklabel(struct lsu_softc *); static int lsulock(struct lsu_softc *); static void lsuminphys(struct buf *bp); static void lsushutdown(void *); +static void lsustart(struct lsu_softc *, struct buf *); static void lsuunlock(struct lsu_softc *); extern struct cfdriver lsu_cd; @@ -108,6 +109,7 @@ lsuattach(struct lsu_softc *sc) /* Set the `shutdownhook'. */ if (lsu_sdh == NULL) lsu_sdh = shutdownhook_establish(lsushutdown, NULL); + BUFQ_INIT(&sc->sc_bufq); } static void @@ -278,13 +280,28 @@ lsuioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) void lsustrategy(struct buf *bp) { - struct disklabel *lp; struct lsu_softc *sc; - int part, unit, rv, s; + int s; + + sc = device_lookup(&lsu_cd, DISKUNIT(bp->b_dev)); + + s = splbio(); + if (sc->sc_queuecnt == sc->sc_maxqueuecnt) { + BUFQ_INSERT_TAIL(&sc->sc_bufq, bp); + splx(s); + return; + } + splx(s); + lsustart(sc, bp); +} + +static void +lsustart(struct lsu_softc *sc, struct buf *bp) +{ + struct disklabel *lp; + int part, s, rv; - unit = DISKUNIT(bp->b_dev); part = DISKPART(bp->b_dev); - sc = device_lookup(&lsu_cd, unit); lp = sc->sc_dk.dk_label; /* @@ -331,12 +348,9 @@ lsustrategy(struct buf *bp) s = splbio(); disk_busy(&sc->sc_dk); + sc->sc_queuecnt++; splx(s); - /* - * XXX We shouldn't really allow processes to sleep at this point; - * in reality it won't matter too much. - */ if ((rv = (*sc->sc_start)(sc, bp)) != 0) { bp->b_error = rv; bp->b_flags |= B_ERROR; @@ -352,7 +366,6 @@ lsudone(struct lsu_softc *sc, struct buf *bp) { if ((bp->b_flags & B_ERROR) != 0) { - /* XXX Ha ha. */ diskerr(bp, "lsu", "error", LOG_PRINTF, 0, sc->sc_dk.dk_label); printf("\n"); } @@ -362,6 +375,12 @@ lsudone(struct lsu_softc *sc, struct buf *bp) rnd_add_uint32(&sc->sc_rnd_source, bp->b_rawblkno); #endif biodone(bp); + sc->sc_queuecnt--; + + if ((bp = BUFQ_FIRST(&sc->sc_bufq)) != NULL) { + BUFQ_REMOVE(&sc->sc_bufq, bp); + lsustart(sc, bp); + } } int diff --git a/sys/dev/lsu/lsuvar.h b/sys/dev/lsuvar.h similarity index 96% rename from sys/dev/lsu/lsuvar.h rename to sys/dev/lsuvar.h index 3950cef0f333..17332a73a156 100644 --- a/sys/dev/lsu/lsuvar.h +++ b/sys/dev/lsuvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: lsuvar.h,v 1.1 2000/10/19 14:06:02 ad Exp $ */ +/* $NetBSD$ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -42,9 +42,11 @@ struct lsu_softc { struct device sc_dv; struct disk sc_dk; + struct buf_queue sc_bufq; #if NRND > 0 rndsource_element_t sc_rnd_source; #endif + int sc_queuecnt; /* * The following are filled by hardware specific attachment code. @@ -56,6 +58,7 @@ struct lsu_softc { int sc_nsectors; /* # sectors per track */ int sc_secsize; /* sector size in bytes */ int sc_maxxfer; /* max xfer size in bytes */ + int sc_maxqueuecnt; /* maximum h/w queue count */ int (*sc_dump)(struct lsu_softc *, void *, int, int); int (*sc_flush)(struct lsu_softc *); diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci index edcaf88623ac..98bc8b441071 100644 --- a/sys/dev/pci/files.pci +++ b/sys/dev/pci/files.pci @@ -1,4 +1,4 @@ -# $NetBSD: files.pci,v 1.106 2000/11/05 06:46:03 thorpej Exp $ +# $NetBSD: files.pci,v 1.107 2000/11/08 19:20:34 ad Exp $ # # Config file and device description for machine-independent PCI code. # Included by ports that need it. Requires that the SCSI files be @@ -45,7 +45,7 @@ file dev/pci/twe.c twe defopt opt_twe.h TWE_MAX_QUEUECNT TWE_MAX_PU_QUEUECNT attach lsu at twe with lsu_twe -file dev/lsu/lsu_twe.c lsu_twe +file dev/pci/lsu_twe.c lsu_twe # Compaq RAID controllers attach cac at pci with cac_pci diff --git a/sys/dev/lsu/lsu_twe.c b/sys/dev/pci/lsu_twe.c similarity index 85% rename from sys/dev/lsu/lsu_twe.c rename to sys/dev/pci/lsu_twe.c index 257a500fc2d2..55c14e309a38 100644 --- a/sys/dev/lsu/lsu_twe.c +++ b/sys/dev/pci/lsu_twe.c @@ -1,4 +1,4 @@ -/* $NetBSD: lsu_twe.c,v 1.3 2000/10/23 11:27:52 ad Exp $ */ +/* $NetBSD$ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -57,16 +57,14 @@ #include -#include +#include #include #include struct lsu_twe_softc { struct lsu_softc sc_lsu; - struct buf_queue sc_bufq; int sc_hwunit; - int sc_queuecnt; }; static void lsu_twe_attach(struct device *, struct device *, void *); @@ -106,6 +104,8 @@ lsu_twe_attach(struct device *parent, struct device *self, void *aux) lsu->sc_maxxfer = TWE_MAX_XFER; lsu->sc_secperunit = twe->sc_dsize[twea->twea_unit]; lsu->sc_secsize = TWE_SECTOR_SIZE; + lsu->sc_maxqueuecnt = + min((twe->sc_nccbs - 1) / twe->sc_nunits, TWE_MAX_PU_QUEUECNT); lsu->sc_start = lsu_twe_start; lsu->sc_dump = lsu_twe_dump; @@ -121,7 +121,6 @@ lsu_twe_attach(struct device *parent, struct device *self, void *aux) (lsu->sc_nheads * lsu->sc_nsectors); printf("\n"); - BUFQ_INIT(&sc->sc_bufq); lsuattach(lsu); } @@ -132,11 +131,12 @@ lsu_twe_dobio(struct lsu_twe_softc *sc, int unit, void *data, int datasize, struct twe_ccb *ccb; struct twe_cmd *tc; struct twe_softc *twe; - int s, rv; + int s, rv, flags; twe = (struct twe_softc *)sc->sc_lsu.sc_dv.dv_parent; - if ((rv = twe_ccb_alloc(twe, &ccb, tx == NULL)) != 0) + flags = (dowrite ? TWE_CCB_DATA_OUT : TWE_CCB_DATA_IN); + if ((rv = twe_ccb_alloc(twe, &ccb, flags)) != 0) return (rv); ccb->ccb_data = data; @@ -149,13 +149,10 @@ lsu_twe_dobio(struct lsu_twe_softc *sc, int unit, void *data, int datasize, tc->tc_count = htole16(datasize / TWE_SECTOR_SIZE); tc->tc_args.io.lba = htole32(blkno); - if (dowrite) { - ccb->ccb_flags |= TWE_CCB_DATA_OUT; + if (dowrite) tc->tc_opcode = TWE_OP_WRITE | (tc->tc_size << 5); - } else { - ccb->ccb_flags |= TWE_CCB_DATA_IN; + else tc->tc_opcode = TWE_OP_READ | (tc->tc_size << 5); - } /* Map the data transfer. */ if ((rv = twe_ccb_map(twe, ccb)) != 0) { @@ -188,40 +185,17 @@ lsu_twe_start(struct lsu_softc *lsu, struct buf *bp) { struct twe_context tx; struct lsu_twe_softc *sc; - int s, rv; + struct twe_softc *twe; sc = (struct lsu_twe_softc *)lsu; - - s = splbio(); - if (bp != NULL) { - if (sc->sc_queuecnt == TWE_MAX_PU_QUEUECNT) { - BUFQ_INSERT_TAIL(&sc->sc_bufq, bp); - splx(s); - return (0); - } - } else { - bp = BUFQ_FIRST(&sc->sc_bufq); - BUFQ_REMOVE(&sc->sc_bufq, bp); - } - sc->sc_queuecnt++; - splx(s); + twe = (struct twe_softc *)lsu->sc_dv.dv_parent; tx.tx_handler = lsu_twe_handler; tx.tx_context = bp; tx.tx_dv = &lsu->sc_dv; - if ((rv = lsu_twe_dobio(sc, sc->sc_hwunit, bp->b_data, bp->b_bcount, - bp->b_rawblkno, (bp->b_flags & B_READ) == 0, &tx)) != 0) { - bp->b_flags |= B_ERROR; - bp->b_error = rv; - bp->b_resid = bp->b_bcount; - s = splbio(); - sc->sc_queuecnt--; - lsudone(lsu, bp); - splx(s); - } - - return (0); + return (lsu_twe_dobio(sc, sc->sc_hwunit, bp->b_data, bp->b_bcount, + bp->b_rawblkno, (bp->b_flags & B_READ) == 0, &tx)); } static void @@ -240,10 +214,6 @@ lsu_twe_handler(struct twe_ccb *ccb, int error) twe_ccb_unmap(twe, ccb); twe_ccb_free(twe, ccb); - if (--sc->sc_queuecnt < TWE_MAX_PU_QUEUECNT && - BUFQ_FIRST(&sc->sc_bufq) != NULL) - lsu_twe_start(&sc->sc_lsu, NULL); - if (error) { bp->b_flags |= B_ERROR; bp->b_error = error;