summaryrefslogtreecommitdiff
path: root/sys/scsi/sd.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/scsi/sd.c')
-rw-r--r--sys/scsi/sd.c81
1 files changed, 52 insertions, 29 deletions
diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c
index 474ae5d0281..f67911b16ab 100644
--- a/sys/scsi/sd.c
+++ b/sys/scsi/sd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: sd.c,v 1.83 1995/12/07 21:54:24 thorpej Exp $ */
+/* $NetBSD: sd.c,v 1.84 1996/01/07 22:04:02 thorpej Exp $ */
/*
* Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
@@ -77,7 +77,7 @@
struct sd_softc {
struct device sc_dev;
- struct dkdevice sc_dk;
+ struct disk sc_dk;
int flags;
#define SDF_LOCKED 0x01
@@ -107,6 +107,7 @@ void sdgetdisklabel __P((struct sd_softc *));
int sd_get_parms __P((struct sd_softc *, int));
void sdstrategy __P((struct buf *));
void sdstart __P((struct sd_softc *));
+int sddone __P((struct scsi_xfer *));
void sdminphys __P((struct buf *));
struct dkdriver sddkdriver = { sdstrategy };
@@ -115,7 +116,7 @@ struct scsi_device sd_switch = {
NULL, /* Use default error handler */
sdstart, /* have a queue, served by this */
NULL, /* have no async handler */
- NULL, /* Use default 'done' routine */
+ sddone, /* deal with stats at interrupt time */
};
struct scsi_inquiry_pattern sd_patterns[] = {
@@ -170,17 +171,24 @@ sdattach(parent, self, aux)
sc_link->openings = SDOUTSTANDING;
/*
- * Note if this device is ancient. This is used in sdminphys().
+ * Initialize and attach the disk structure.
*/
- if ((sa->sa_inqbuf->version & SID_ANSII) == 0)
- sd->flags |= SDF_ANCIENT;
+ sd->sc_dk.dk_driver = &sddkdriver;
+ sd->sc_dk.dk_name = sd->sc_dev.dv_xname;
+ disk_attach(&sd->sc_dk);
sd->sc_dk.dk_driver = &sddkdriver;
#if !defined(i386) || defined(NEWCONFIG)
- dk_establish(&sd->sc_dk, &sd->sc_dev);
+ dk_establish(&sd->sc_dk, &sd->sc_dev); /* XXX */
#endif
/*
+ * Note if this device is ancient. This is used in sdminphys().
+ */
+ if ((sa->sa_inqbuf->version & SID_ANSII) == 0)
+ sd->flags |= SDF_ANCIENT;
+
+ /*
* Use the subdriver to request information regarding
* the drive. We cannot use interrupts yet, so the
* request must specify this.
@@ -307,8 +315,8 @@ sdopen(dev, flag, fmt)
/* Check that the partition exists. */
if (part != RAW_PART &&
- (part >= sd->sc_dk.dk_label.d_npartitions ||
- sd->sc_dk.dk_label.d_partitions[part].p_fstype == FS_UNUSED)) {
+ (part >= sd->sc_dk.dk_label->d_npartitions ||
+ sd->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
error = ENXIO;
goto bad;
}
@@ -399,7 +407,7 @@ sdstrategy(bp)
/*
* The transfer must be a whole number of blocks.
*/
- if ((bp->b_bcount % sd->sc_dk.dk_label.d_secsize) != 0) {
+ if ((bp->b_bcount % sd->sc_dk.dk_label->d_secsize) != 0) {
bp->b_error = EINVAL;
goto bad;
}
@@ -421,7 +429,7 @@ sdstrategy(bp)
* If end of partition, just return.
*/
if (SDPART(bp->b_dev) != RAW_PART &&
- bounds_check_with_label(bp, &sd->sc_dk.dk_label,
+ bounds_check_with_label(bp, sd->sc_dk.dk_label,
(sd->flags & (SDF_WLABEL|SDF_LABELLING)) != 0) <= 0)
goto done;
@@ -523,12 +531,12 @@ sdstart(sd)
* of the logical blocksize of the device.
*/
blkno =
- bp->b_blkno / (sd->sc_dk.dk_label.d_secsize / DEV_BSIZE);
+ bp->b_blkno / (sd->sc_dk.dk_label->d_secsize / DEV_BSIZE);
if (SDPART(bp->b_dev) != RAW_PART) {
- p = &sd->sc_dk.dk_label.d_partitions[SDPART(bp->b_dev)];
- blkno += p->p_offset;
+ p = &sd->sc_dk.dk_label->d_partitions[SDPART(bp->b_dev)];
+ blkno += p->p_offset;
}
- nblks = howmany(bp->b_bcount, sd->sc_dk.dk_label.d_secsize);
+ nblks = howmany(bp->b_bcount, sd->sc_dk.dk_label->d_secsize);
/*
* Fill out the scsi command. If the transfer will
@@ -565,6 +573,9 @@ sdstart(sd)
cmdp = (struct scsi_generic *)&cmd_big;
}
+ /* Instrumentation. */
+ disk_busy(&sd->sc_dk);
+
/*
* Call the routine that chats with the adapter.
* Note: we cannot sleep as we may be an interrupt
@@ -577,6 +588,18 @@ sdstart(sd)
}
}
+int
+sddone(xs)
+ struct scsi_xfer *xs;
+{
+ struct sd_softc *sd = xs->sc_link->device_softc;
+
+ if (xs->bp != NULL)
+ disk_unbusy(&sd->sc_dk, (xs->bp->b_bcount - xs->bp->b_resid));
+
+ return (0);
+}
+
void
sdminphys(bp)
struct buf *bp;
@@ -596,7 +619,7 @@ sdminphys(bp)
* in a 10-byte read/write actually means 0 blocks.
*/
if (sd->flags & SDF_ANCIENT) {
- max = sd->sc_dk.dk_label.d_secsize * 0xff;
+ max = sd->sc_dk.dk_label->d_secsize * 0xff;
if (bp->b_bcount > max)
bp->b_bcount = max;
@@ -648,13 +671,13 @@ sdioctl(dev, cmd, addr, flag, p)
switch (cmd) {
case DIOCGDINFO:
- *(struct disklabel *)addr = sd->sc_dk.dk_label;
+ *(struct disklabel *)addr = *(sd->sc_dk.dk_label);
return 0;
case DIOCGPART:
- ((struct partinfo *)addr)->disklab = &sd->sc_dk.dk_label;
+ ((struct partinfo *)addr)->disklab = sd->sc_dk.dk_label;
((struct partinfo *)addr)->part =
- &sd->sc_dk.dk_label.d_partitions[SDPART(dev)];
+ &sd->sc_dk.dk_label->d_partitions[SDPART(dev)];
return 0;
case DIOCWDINFO:
@@ -666,14 +689,14 @@ sdioctl(dev, cmd, addr, flag, p)
return error;
sd->flags |= SDF_LABELLING;
- error = setdisklabel(&sd->sc_dk.dk_label,
+ error = setdisklabel(sd->sc_dk.dk_label,
(struct disklabel *)addr, /*sd->sc_dk.dk_openmask : */0,
- &sd->sc_dk.dk_cpulabel);
+ sd->sc_dk.dk_cpulabel);
if (error == 0) {
if (cmd == DIOCWDINFO)
error = writedisklabel(SDLABELDEV(dev),
- sdstrategy, &sd->sc_dk.dk_label,
- &sd->sc_dk.dk_cpulabel);
+ sdstrategy, sd->sc_dk.dk_label,
+ sd->sc_dk.dk_cpulabel);
}
sd->flags &= ~SDF_LABELLING;
@@ -707,11 +730,11 @@ void
sdgetdisklabel(sd)
struct sd_softc *sd;
{
- struct disklabel *lp = &sd->sc_dk.dk_label;
+ struct disklabel *lp = sd->sc_dk.dk_label;
char *errstring;
bzero(lp, sizeof(struct disklabel));
- bzero(&sd->sc_dk.dk_cpulabel, sizeof(struct cpu_disklabel));
+ bzero(sd->sc_dk.dk_cpulabel, sizeof(struct cpu_disklabel));
lp->d_secsize = sd->params.blksize;
lp->d_ntracks = sd->params.heads;
@@ -745,7 +768,7 @@ sdgetdisklabel(sd)
* Call the generic disklabel extraction routine
*/
if (errstring = readdisklabel(MAKESDDEV(0, sd->sc_dev.dv_unit,
- RAW_PART), sdstrategy, lp, &sd->sc_dk.dk_cpulabel)) {
+ RAW_PART), sdstrategy, lp, sd->sc_dk.dk_cpulabel)) {
printf("%s: %s\n", sd->sc_dev.dv_xname, errstring);
return;
}
@@ -910,10 +933,10 @@ sdsize(dev)
return -1;
sd = sdcd.cd_devs[SDUNIT(dev)];
part = SDPART(dev);
- if (sd->sc_dk.dk_label.d_partitions[part].p_fstype != FS_SWAP)
+ if (sd->sc_dk.dk_label->d_partitions[part].p_fstype != FS_SWAP)
size = -1;
else
- size = sd->sc_dk.dk_label.d_partitions[part].p_size;
+ size = sd->sc_dk.dk_label->d_partitions[part].p_size;
if (sdclose(dev, 0, S_IFBLK) != 0)
return -1;
return size;
@@ -966,7 +989,7 @@ sddump(dev, blkno, va, size)
return ENXIO;
/* Convert to disk sectors. Request must be a multiple of size. */
- lp = &sd->sc_dk.dk_label;
+ lp = sd->sc_dk.dk_label;
sectorsize = lp->d_secsize;
if ((size % sectorsize) != 0)
return EFAULT;