Move lsu stuff to more logical locations, and push queueing into the lsu
driver.
This commit is contained in:
parent
5959ab8f01
commit
142ab5b1ec
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 <machine/bus.h>
|
||||
|
||||
#include <dev/lsu/lsuvar.h>
|
||||
#include <dev/lsuvar.h>
|
||||
|
||||
#include <dev/ic/cacreg.h>
|
||||
#include <dev/ic/cacvar.h>
|
||||
@ -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);
|
||||
}
|
@ -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 <sys/rnd.h>
|
||||
#endif
|
||||
|
||||
#include <dev/lsu/lsuvar.h>
|
||||
#include <dev/lsuvar.h>
|
||||
|
||||
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
|
@ -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 *);
|
@ -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
|
||||
|
@ -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 <machine/bus.h>
|
||||
|
||||
#include <dev/lsu/lsuvar.h>
|
||||
#include <dev/lsuvar.h>
|
||||
|
||||
#include <dev/pci/twereg.h>
|
||||
#include <dev/pci/twevar.h>
|
||||
|
||||
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;
|
Loading…
Reference in New Issue
Block a user