summaryrefslogtreecommitdiffstats
path: root/sys/dev/aac/aac_disk.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/aac/aac_disk.c')
-rw-r--r--sys/dev/aac/aac_disk.c413
1 files changed, 213 insertions, 200 deletions
diff --git a/sys/dev/aac/aac_disk.c b/sys/dev/aac/aac_disk.c
index a5a70da..3917fa1 100644
--- a/sys/dev/aac/aac_disk.c
+++ b/sys/dev/aac/aac_disk.c
@@ -71,21 +71,21 @@ static d_dump_t aac_disk_dump;
#define AAC_DISK_CDEV_MAJOR 151
static struct cdevsw aac_disk_cdevsw = {
- /* open */ aac_disk_open,
- /* close */ aac_disk_close,
- /* read */ physread,
- /* write */ physwrite,
- /* ioctl */ noioctl,
- /* poll */ nopoll,
- /* mmap */ nommap,
- /* strategy */ aac_disk_strategy,
- /* name */ "aacd",
- /* maj */ AAC_DISK_CDEV_MAJOR,
- /* dump */ aac_disk_dump,
- /* psize */ nopsize,
- /* flags */ D_DISK,
+ /* open */ aac_disk_open,
+ /* close */ aac_disk_close,
+ /* read */ physread,
+ /* write */ physwrite,
+ /* ioctl */ noioctl,
+ /* poll */ nopoll,
+ /* mmap */ nommap,
+ /* strategy */ aac_disk_strategy,
+ /* name */ "aacd",
+ /* maj */ AAC_DISK_CDEV_MAJOR,
+ /* dump */ aac_disk_dump,
+ /* psize */ nopsize,
+ /* flags */ D_DISK,
#if __FreeBSD_version < 500005
- /* bmaj */ -1
+ /* bmaj */ -1
#endif
};
@@ -96,16 +96,16 @@ static int disks_registered = 0;
#endif
static device_method_t aac_disk_methods[] = {
- DEVMETHOD(device_probe, aac_disk_probe),
- DEVMETHOD(device_attach, aac_disk_attach),
- DEVMETHOD(device_detach, aac_disk_detach),
- { 0, 0 }
+ DEVMETHOD(device_probe, aac_disk_probe),
+ DEVMETHOD(device_attach, aac_disk_attach),
+ DEVMETHOD(device_detach, aac_disk_detach),
+ { 0, 0 }
};
static driver_t aac_disk_driver = {
- "aacd",
- aac_disk_methods,
- sizeof(struct aac_disk)
+ "aacd",
+ aac_disk_methods,
+ sizeof(struct aac_disk)
};
DRIVER_MODULE(aacd, aac, aac_disk_driver, aac_disk_devclass, 0, 0);
@@ -120,7 +120,7 @@ SYSCTL_UINT(_hw_aac, OID_AUTO, iosize_max, CTLFLAG_RD, &aac_iosize_max, 0,
#define AAC_MAXIO 65536
-/******************************************************************************
+/*
* Handle open from generic layer.
*
* This is called by the diskslice code on first open in order to get the
@@ -129,84 +129,90 @@ SYSCTL_UINT(_hw_aac, OID_AUTO, iosize_max, CTLFLAG_RD, &aac_iosize_max, 0,
static int
aac_disk_open(dev_t dev, int flags, int fmt, struct proc *p)
{
- struct aac_disk *sc = (struct aac_disk *)dev->si_drv1;
- struct disklabel *label;
+ struct aac_disk *sc;
+ struct disklabel *label;
+
+ debug_called(4);
- debug_called(4);
+ sc = (struct aac_disk *)dev->si_drv1;
- if (sc == NULL)
- return (ENXIO);
-
- /* check that the controller is up and running */
- if (sc->ad_controller->aac_state & AAC_STATE_SUSPEND)
- return(ENXIO);
-
- /* build synthetic label */
- label = &sc->ad_disk.d_label;
- bzero(label, sizeof(*label));
- label->d_type = DTYPE_ESDI;
- label->d_secsize = AAC_BLOCK_SIZE;
- label->d_nsectors = sc->ad_sectors;
- label->d_ntracks = sc->ad_heads;
- label->d_ncylinders = sc->ad_cylinders;
- label->d_secpercyl = sc->ad_sectors * sc->ad_heads;
- label->d_secperunit = sc->ad_size;
-
- sc->ad_flags |= AAC_DISK_OPEN;
- return (0);
+ if (sc == NULL)
+ return (ENXIO);
+
+ /* check that the controller is up and running */
+ if (sc->ad_controller->aac_state & AAC_STATE_SUSPEND)
+ return(ENXIO);
+
+ /* build synthetic label */
+ label = &sc->ad_disk.d_label;
+ bzero(label, sizeof(*label));
+ label->d_type = DTYPE_ESDI;
+ label->d_secsize = AAC_BLOCK_SIZE;
+ label->d_nsectors = sc->ad_sectors;
+ label->d_ntracks = sc->ad_heads;
+ label->d_ncylinders = sc->ad_cylinders;
+ label->d_secpercyl = sc->ad_sectors * sc->ad_heads;
+ label->d_secperunit = sc->ad_size;
+
+ sc->ad_flags |= AAC_DISK_OPEN;
+ return (0);
}
-/******************************************************************************
+/*
* Handle last close of the disk device.
*/
static int
aac_disk_close(dev_t dev, int flags, int fmt, struct proc *p)
{
- struct aac_disk *sc = (struct aac_disk *)dev->si_drv1;
+ struct aac_disk *sc;
- debug_called(4);
+ debug_called(4);
+
+ sc = (struct aac_disk *)dev->si_drv1;
- if (sc == NULL)
- return (ENXIO);
+ if (sc == NULL)
+ return (ENXIO);
- sc->ad_flags &= ~AAC_DISK_OPEN;
- return (0);
+ sc->ad_flags &= ~AAC_DISK_OPEN;
+ return (0);
}
-/******************************************************************************
+/*
* Handle an I/O request.
*/
static void
aac_disk_strategy(struct bio *bp)
{
- struct aac_disk *sc = (struct aac_disk *)bp->bio_dev->si_drv1;
+ struct aac_disk *sc;
- debug_called(4);
+ debug_called(4);
- /* bogus disk? */
- if (sc == NULL) {
- bp->bio_flags |= BIO_ERROR;
- bp->bio_error = EINVAL;
- biodone(bp);
- return;
- }
+ sc = (struct aac_disk *)bp->bio_dev->si_drv1;
- /* do-nothing operation? */
- if (bp->bio_bcount == 0) {
- bp->bio_resid = bp->bio_bcount;
- biodone(bp);
- return;
- }
+ /* bogus disk? */
+ if (sc == NULL) {
+ bp->bio_flags |= BIO_ERROR;
+ bp->bio_error = EINVAL;
+ biodone(bp);
+ return;
+ }
+
+ /* do-nothing operation? */
+ if (bp->bio_bcount == 0) {
+ bp->bio_resid = bp->bio_bcount;
+ biodone(bp);
+ return;
+ }
- /* perform accounting */
- devstat_start_transaction(&sc->ad_stats);
+ /* perform accounting */
+ devstat_start_transaction(&sc->ad_stats);
- /* pass the bio to the controller - it can work out who we are */
- aac_submit_bio(bp);
- return;
+ /* pass the bio to the controller - it can work out who we are */
+ aac_submit_bio(bp);
+ return;
}
-/******************************************************************************
+/*
* Dump memory out to an array
*
* This queues blocks of memory of size AAC_MAXIO to the controller and waits
@@ -215,186 +221,193 @@ aac_disk_strategy(struct bio *bp)
static int
aac_disk_dump(dev_t dev)
{
- struct aac_disk *ad = dev->si_drv1;
- struct aac_softc *sc;
- vm_offset_t addr = 0;
- long blkcnt;
- unsigned int count, blkno, secsize;
- int dumppages = AAC_MAXIO / PAGE_SIZE;
- int i, error;
+ struct aac_disk *ad;
+ struct aac_softc *sc;
+ vm_offset_t addr;
+ long blkcnt;
+ unsigned int count, blkno, secsize;
+ int dumppages;
+ int i, error;
- if ((error = disk_dumpcheck(dev, &count, &blkno, &secsize)))
- return (error);
+ ad = dev->si_drv1;
+ addr = 0;
+ dumppages = AAC_MAXIO / PAGE_SIZE;
- if (ad == NULL)
- return (ENXIO);
+ if ((error = disk_dumpcheck(dev, &count, &blkno, &secsize)))
+ return (error);
- sc= ad->ad_controller;
+ if (ad == NULL)
+ return (ENXIO);
- blkcnt = howmany(PAGE_SIZE, secsize);
+ sc= ad->ad_controller;
- while (count > 0) {
- caddr_t va = NULL;
+ blkcnt = howmany(PAGE_SIZE, secsize);
- if ((count / blkcnt) < dumppages)
- dumppages = count / blkcnt;
+ while (count > 0) {
+ caddr_t va = NULL;
- for (i = 0; i < dumppages; ++i) {
- vm_offset_t a = addr + (i * PAGE_SIZE);
- if (is_physical_memory(a)) {
- va = pmap_kenter_temporary(trunc_page(a), i);
- } else {
- va = pmap_kenter_temporary(trunc_page(0), i);
- }
- }
+ if ((count / blkcnt) < dumppages)
+ dumppages = count / blkcnt;
+
+ for (i = 0; i < dumppages; ++i) {
+ vm_offset_t a = addr + (i * PAGE_SIZE);
+ if (is_physical_memory(a)) {
+ va = pmap_kenter_temporary(trunc_page(a), i);
+ } else {
+ va = pmap_kenter_temporary(trunc_page(0), i);
+ }
+ }
retry:
- /*
- * Queue the block to the controller. If the queue is full, EBUSY
- * will be returned.
- */
- error = aac_dump_enqueue(ad, blkno, va, dumppages);
- if (error && (error != EBUSY))
- return (error);
-
- if (!error) {
- if (dumpstatus(addr, (long)(count * DEV_BSIZE)) < 0)
- return (EINTR);
-
- blkno += blkcnt * dumppages;
- count -= blkcnt * dumppages;
- addr += PAGE_SIZE * dumppages;
- if (count > 0)
- continue;
+ /*
+ * Queue the block to the controller. If the queue is full,
+ * EBUSY will be returned.
+ */
+ error = aac_dump_enqueue(ad, blkno, va, dumppages);
+ if (error && (error != EBUSY))
+ return (error);
+
+ if (!error) {
+ if (dumpstatus(addr, (long)(count * DEV_BSIZE)) < 0)
+ return (EINTR);
+
+ blkno += blkcnt * dumppages;
+ count -= blkcnt * dumppages;
+ addr += PAGE_SIZE * dumppages;
+ if (count > 0)
+ continue;
+ }
+
+ /*
+ * Either the queue was full on the last attemp, or we have no
+ * more data to dump. Let the queue drain out and retry the
+ * block if the queue was full.
+ */
+ aac_dump_complete(sc);
+
+ if (error == EBUSY)
+ goto retry;
}
- /*
- * Either the queue was full on the last attemp, or we have no more
- * data to dump. Let the queue drain out and retry the block if
- * the queue was full.
- */
- aac_dump_complete(sc);
-
- if (error == EBUSY)
- goto retry;
- }
-
- return (0);
+ return (0);
}
-/******************************************************************************
+/*
* Handle completion of an I/O request.
*/
void
aac_biodone(struct bio *bp)
{
- struct aac_disk *sc = (struct aac_disk *)bp->bio_dev->si_drv1;
+ struct aac_disk *sc;
+ int blkno;
- debug_called(4);
+ debug_called(4);
- devstat_end_transaction_bio(&sc->ad_stats, bp);
- if (bp->bio_flags & BIO_ERROR) {
- /*
- * XXX For some reason, the disklabel seems to get zero'd out. This
- * will cause diskerr to panic unless we pass in -1 as the blkno.
- */
- int blkno = (sc->ad_label.d_nsectors) ? 0 : -1;
+ sc = (struct aac_disk *)bp->bio_dev->si_drv1;
+
+ devstat_end_transaction_bio(&sc->ad_stats, bp);
+ if (bp->bio_flags & BIO_ERROR) {
+ blkno = (sc->ad_label.d_nsectors) ? 0 : -1;
#if __FreeBSD_version > 500005
- diskerr(bp, (char *)bp->bio_driver1, blkno, &sc->ad_label);
+ diskerr(bp, (char *)bp->bio_driver1, blkno, &sc->ad_label);
#else
- diskerr(bp, (char *)bp->bio_driver1, 0, blkno, &sc->ad_label);
+ diskerr(bp, (char *)bp->bio_driver1, 0, blkno, &sc->ad_label);
#endif
- }
- biodone(bp);
+ }
+ biodone(bp);
}
-/******************************************************************************
+/*
* Stub only.
*/
static int
aac_disk_probe(device_t dev)
{
- debug_called(2);
+ debug_called(2);
- return (0);
+ return (0);
}
-/******************************************************************************
+/*
* Attach a unit to the controller.
*/
static int
aac_disk_attach(device_t dev)
{
- struct aac_disk *sc = (struct aac_disk *)device_get_softc(dev);
-
- debug_called(1);
-
- /* initialise our softc */
- sc->ad_controller =
- (struct aac_softc *)device_get_softc(device_get_parent(dev));
- sc->ad_container = device_get_ivars(dev);
- sc->ad_dev = dev;
-
- /*
- * require that extended translation be enabled - other drivers read the
- * disk!
- */
- sc->ad_size = sc->ad_container->co_mntobj.Capacity;
- if (sc->ad_size >= (2 * 1024 * 1024)) { /* 2GB */
- sc->ad_heads = 255;
- sc->ad_sectors = 63;
- } else if (sc->ad_size >= (1 * 1024 * 1024)) { /* 1GB */
- sc->ad_heads = 128;
- sc->ad_sectors = 32;
- } else {
- sc->ad_heads = 64;
- sc->ad_sectors = 32;
- }
- sc->ad_cylinders = (sc->ad_size / (sc->ad_heads * sc->ad_sectors));
-
- device_printf(dev, "%uMB (%u sectors)\n",
- sc->ad_size / ((1024 * 1024) / AAC_BLOCK_SIZE), sc->ad_size);
-
- devstat_add_entry(&sc->ad_stats, "aacd", device_get_unit(dev),
- AAC_BLOCK_SIZE, DEVSTAT_NO_ORDERED_TAGS,
- DEVSTAT_TYPE_STORARRAY | DEVSTAT_TYPE_IF_OTHER,
- DEVSTAT_PRIORITY_ARRAY);
-
- /* attach a generic disk device to ourselves */
- sc->ad_dev_t = disk_create(device_get_unit(dev), &sc->ad_disk, 0,
- &aac_disk_cdevsw, &aac_disk_disk_cdevsw);
- sc->ad_dev_t->si_drv1 = sc;
+ struct aac_disk *sc;
+
+ debug_called(1);
+
+ sc = (struct aac_disk *)device_get_softc(dev);
+
+ /* initialise our softc */
+ sc->ad_controller =
+ (struct aac_softc *)device_get_softc(device_get_parent(dev));
+ sc->ad_container = device_get_ivars(dev);
+ sc->ad_dev = dev;
+
+ /*
+ * require that extended translation be enabled - other drivers read the
+ * disk!
+ */
+ sc->ad_size = sc->ad_container->co_mntobj.Capacity;
+ if (sc->ad_size >= (2 * 1024 * 1024)) { /* 2GB */
+ sc->ad_heads = 255;
+ sc->ad_sectors = 63;
+ } else if (sc->ad_size >= (1 * 1024 * 1024)) { /* 1GB */
+ sc->ad_heads = 128;
+ sc->ad_sectors = 32;
+ } else {
+ sc->ad_heads = 64;
+ sc->ad_sectors = 32;
+ }
+ sc->ad_cylinders = (sc->ad_size / (sc->ad_heads * sc->ad_sectors));
+
+ device_printf(dev, "%uMB (%u sectors)\n",
+ sc->ad_size / ((1024 * 1024) / AAC_BLOCK_SIZE),
+ sc->ad_size);
+
+ devstat_add_entry(&sc->ad_stats, "aacd", device_get_unit(dev),
+ AAC_BLOCK_SIZE, DEVSTAT_NO_ORDERED_TAGS,
+ DEVSTAT_TYPE_STORARRAY | DEVSTAT_TYPE_IF_OTHER,
+ DEVSTAT_PRIORITY_ARRAY);
+
+ /* attach a generic disk device to ourselves */
+ sc->ad_dev_t = disk_create(device_get_unit(dev), &sc->ad_disk, 0,
+ &aac_disk_cdevsw, &aac_disk_disk_cdevsw);
+ sc->ad_dev_t->si_drv1 = sc;
#ifdef FREEBSD_4
- disks_registered++;
+ disks_registered++;
#endif
- sc->ad_dev_t->si_iosize_max = aac_iosize_max;
- sc->unit = device_get_unit(dev);
+ sc->ad_dev_t->si_iosize_max = aac_iosize_max;
+ sc->unit = device_get_unit(dev);
- return (0);
+ return (0);
}
-/******************************************************************************
+/*
* Disconnect ourselves from the system.
*/
static int
aac_disk_detach(device_t dev)
{
- struct aac_disk *sc = (struct aac_disk *)device_get_softc(dev);
+ struct aac_disk *sc;
- debug_called(2);
+ debug_called(2);
- if (sc->ad_flags & AAC_DISK_OPEN)
- return(EBUSY);
+ sc = (struct aac_disk *)device_get_softc(dev);
- devstat_remove_entry(&sc->ad_stats);
- disk_destroy(sc->ad_dev_t);
+ if (sc->ad_flags & AAC_DISK_OPEN)
+ return(EBUSY);
+
+ devstat_remove_entry(&sc->ad_stats);
+ disk_destroy(sc->ad_dev_t);
#ifdef FREEBSD_4
- if (--disks_registered == 0)
- cdevsw_remove(&aac_disk_cdevsw);
+ if (--disks_registered == 0)
+ cdevsw_remove(&aac_disk_cdevsw);
#endif
- return(0);
+ return(0);
}
-
OpenPOWER on IntegriCloud