summaryrefslogtreecommitdiffstats
path: root/sys/dev/amr/amr_disk.c
diff options
context:
space:
mode:
authormsmith <msmith@FreeBSD.org>2000-04-01 00:35:15 +0000
committermsmith <msmith@FreeBSD.org>2000-04-01 00:35:15 +0000
commitf64f3341e29b7db0ce82d24048194a7a135cb2a5 (patch)
treeef10b943193262336e2b225f694f7786b37db403 /sys/dev/amr/amr_disk.c
parent66b7eaeb75e1664bb1de7c364a673b357bcdf5f4 (diff)
downloadFreeBSD-src-f64f3341e29b7db0ce82d24048194a7a135cb2a5.zip
FreeBSD-src-f64f3341e29b7db0ce82d24048194a7a135cb2a5.tar.gz
Update to latest working version.
- Add periodic status monitoring routine. Currently just detects lost commands, further functionality pending data from AMI. Add some new commands states; WEDGED (never coming back) and LATE (for when a command that wasmarked as WEDGED comes bacj, - Remove a number of redundant efforts to poll the card for completed commands. This is what interrupt handlers are for. - Limit the maximum number of outstanding I/O transactions. It seems that some controllers report more than they can really handle, and exceding this limit can cause the controller to lock up. - Don't use 'wait' mode for anything where the controller might not be able to generate interrupts. (Keep the 'wait' mode though sa it will become useful when we start taking userspace commands. - Use a similar atomic locking trategy to the Mylex driver to prevent some reentrancy problems. - Correctly calculate the block count for non-whoile-bloch transfers (actually illegal). - Use the dsik device's si_drv1 field instead of b_driver1 in the buf struct to pass the driver identifier arond. - Rewrite amr_start and amr_done() along the lines of the Mylex driver in order to improve robustnes. - Always force the PCI busmaster bit on.
Diffstat (limited to 'sys/dev/amr/amr_disk.c')
-rw-r--r--sys/dev/amr/amr_disk.c49
1 files changed, 23 insertions, 26 deletions
diff --git a/sys/dev/amr/amr_disk.c b/sys/dev/amr/amr_disk.c
index e9c0567..6ce523d 100644
--- a/sys/dev/amr/amr_disk.c
+++ b/sys/dev/amr/amr_disk.c
@@ -105,19 +105,10 @@ static driver_t amrd_driver = {
DRIVER_MODULE(amrd, amr, amrd_driver, amrd_devclass, 0, 0);
-static __inline struct amrd_softc *
-amrd_getsoftc(dev_t dev)
-{
- int unit;
-
- unit = dkunit(dev);
- return ((struct amrd_softc *)devclass_get_softc(amrd_devclass, unit));
-}
-
static int
amrd_open(dev_t dev, int flags, int fmt, struct proc *p)
{
- struct amrd_softc *sc = amrd_getsoftc(dev);
+ struct amrd_softc *sc = (struct amrd_softc *)dev->si_drv1;
struct disklabel *label;
debug("called");
@@ -146,7 +137,7 @@ amrd_open(dev_t dev, int flags, int fmt, struct proc *p)
static int
amrd_close(dev_t dev, int flags, int fmt, struct proc *p)
{
- struct amrd_softc *sc = amrd_getsoftc(dev);
+ struct amrd_softc *sc = (struct amrd_softc *)dev->si_drv1;
debug("called");
@@ -159,7 +150,7 @@ amrd_close(dev_t dev, int flags, int fmt, struct proc *p)
static int
amrd_ioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
{
- struct amrd_softc *sc = amrd_getsoftc(dev);
+ struct amrd_softc *sc = (struct amrd_softc *)dev->si_drv1;
int error;
debug("called");
@@ -183,9 +174,10 @@ amrd_ioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
static void
amrd_strategy(struct buf *bp)
{
- struct amrd_softc *sc = amrd_getsoftc(bp->b_dev);
+ struct amrd_softc *sc = (struct amrd_softc *)bp->b_dev->si_drv1;
- debug("called");
+ debug("called to %s %d bytes at b_blkno 0x%x b_pblkno 0x%x",
+ (bp->b_flags & B_READ) ? "read" : "write", bp->b_bcount, bp->b_blkno, bp->b_pblkno);
/* bogus disk? */
if (sc == NULL) {
@@ -205,8 +197,6 @@ amrd_strategy(struct buf *bp)
if (bp->b_bcount == 0)
goto done;
- /* pass reference to us */
- bp->b_driver1 = sc;
devstat_start_transaction(&sc->amrd_stats);
amr_submit_buf(sc->amrd_controller, bp);
return;
@@ -227,14 +217,21 @@ void
amrd_intr(void *data)
{
struct buf *bp = (struct buf *)data;
- struct amrd_softc *sc = (struct amrd_softc *)bp->b_driver1;
+ struct amrd_softc *sc = (struct amrd_softc *)bp->b_dev->si_drv1;
debug("called");
-
- if (bp->b_flags & B_ERROR)
+
+ if (bp->b_flags & B_ERROR) {
bp->b_error = EIO;
- else
+ debug("i/o error\n");
+ } else {
+#if 0
+ int i;
+ for (i = 0; i < 512; i += 16)
+ debug(" %04x %16D", i, bp->b_data + i, " ");
+#endif
bp->b_resid = 0;
+ }
devstat_end_transaction_buf(&sc->amrd_stats, bp);
biodone(bp);
@@ -291,9 +288,13 @@ amrd_attach(device_t dev)
DEVSTAT_TYPE_STORARRAY | DEVSTAT_TYPE_IF_OTHER,
DEVSTAT_PRIORITY_ARRAY);
- disk_create(sc->amrd_unit, &sc->amrd_disk, 0, &amrd_cdevsw, &amrddisk_cdevsw);
+ sc->amrd_dev_t = disk_create(sc->amrd_unit, &sc->amrd_disk, 0, &amrd_cdevsw, &amrddisk_cdevsw);
+ sc->amrd_dev_t->si_drv1 = sc;
disks_registered++;
+ /* set maximum I/O size */
+ /* dsk->si_iosize_max = ??? */;
+
return (0);
}
@@ -305,11 +306,7 @@ amrd_detach(device_t dev)
debug("called");
devstat_remove_entry(&sc->amrd_stats);
-
- /* hack to handle lack of destroy_disk() */
- if (--disks_registered == 0)
- cdevsw_remove(&amrddisk_cdevsw);
-
+ disk_destroy(sc->amrd_dev_t);
return(0);
}
OpenPOWER on IntegriCloud