Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev Refactored sd and cd to use common disk subroutines.
details: https://anonhg.NetBSD.org/src/rev/a4dba879db71
branches: trunk
changeset: 349412:a4dba879db71
user: mlelstv <mlelstv%NetBSD.org@localhost>
date: Sat Dec 10 10:26:38 2016 +0000
description:
Refactored sd and cd to use common disk subroutines.
diffstat:
sys/dev/files.dev | 4 +-
sys/dev/scsipi/cd.c | 1433 ++++++++++++++++++-----------------------------
sys/dev/scsipi/cdvar.h | 18 +-
sys/dev/scsipi/sd.c | 1279 +++++++++++++++---------------------------
sys/dev/scsipi/sdvar.h | 12 +-
5 files changed, 1020 insertions(+), 1726 deletions(-)
diffs (truncated from 3558 to 300 lines):
diff -r ce5acc9800f6 -r a4dba879db71 sys/dev/files.dev
--- a/sys/dev/files.dev Sat Dec 10 09:51:43 2016 +0000
+++ b/sys/dev/files.dev Sat Dec 10 10:26:38 2016 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: files.dev,v 1.1 2015/08/21 02:18:18 uebayasi Exp $
+# $NetBSD: files.dev,v 1.2 2016/12/10 10:26:38 mlelstv Exp $
file dev/bio.c bio needs-flag
file dev/ccd.c ccd
@@ -6,7 +6,7 @@
file dev/cgd_crypto.c cgd
file dev/clock_subr.c kern # XXX
file dev/clockctl.c clockctl
-file dev/dksubr.c cgd | xbd | ccd | raid | dm | ld
+file dev/dksubr.c cgd | xbd | ccd | raid | dm | ld | sd | cd
file dev/dkwedge/dk.c kern # XXX
file dev/dkwedge/dkwedge_apple.c dkwedge_method_apple
file dev/dkwedge/dkwedge_bsdlabel.c dkwedge_method_bsdlabel
diff -r ce5acc9800f6 -r a4dba879db71 sys/dev/scsipi/cd.c
--- a/sys/dev/scsipi/cd.c Sat Dec 10 09:51:43 2016 +0000
+++ b/sys/dev/scsipi/cd.c Sat Dec 10 10:26:38 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cd.c,v 1.333 2016/11/20 15:37:19 mlelstv Exp $ */
+/* $NetBSD: cd.c,v 1.334 2016/12/10 10:26:38 mlelstv Exp $ */
/*-
* Copyright (c) 1998, 2001, 2003, 2004, 2005, 2008 The NetBSD Foundation,
@@ -50,7 +50,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cd.c,v 1.333 2016/11/20 15:37:19 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cd.c,v 1.334 2016/12/10 10:26:38 mlelstv Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -114,22 +114,26 @@
};
struct cdbounce {
- struct buf *obp; /* original buf */
- int doff; /* byte offset in orig. buf */
- int soff; /* byte offset in bounce buf */
- int resid; /* residual i/o in orig. buf */
- int bcount; /* actual obp bytes in bounce */
+ struct buf *obp; /* original buf */
+ struct buf *lbp; /* first buffer */
+ struct buf *rbp; /* second buffer */
+ int lerr; /* error returned for first buffer */
+ int rerr; /* error returned for second buffer */
+ int head; /* bytes skipped at the start */
+ int lcount; /* bytes copied to first buffer */
+ int rcount; /* bytes copied to second buffer */
};
static void cdstart(struct scsipi_periph *);
static void cdrestart(void *);
static void cdminphys(struct buf *);
-static void cdgetdefaultlabel(struct cd_softc *, struct cd_formatted_toc *,
- struct disklabel *);
-static void cdgetdisklabel(struct cd_softc *);
static void cddone(struct scsipi_xfer *, int);
-static void cdbounce(struct buf *);
static int cd_interpret_sense(struct scsipi_xfer *);
+static int cd_diskstart(device_t, struct buf *);
+static void cd_iosize(device_t, int *);
+static int cd_lastclose(device_t);
+static int cd_firstopen(device_t, dev_t, int, int);
+static void cd_label(device_t, struct disklabel *);
static u_long cd_size(struct cd_softc *, int);
static int cd_play(struct cd_softc *, int, int);
static int cd_play_tracks(struct cd_softc *, struct cd_formatted_toc *,
@@ -230,8 +234,14 @@
};
static struct dkdriver cddkdriver = {
+ .d_open = cdopen,
+ .d_close = cdclose,
.d_strategy = cdstrategy,
- .d_minphys = cdminphys
+ .d_minphys = cdminphys,
+ .d_diskstart = cd_diskstart,
+ .d_firstopen = cd_firstopen,
+ .d_lastclose = cd_lastclose,
+ .d_label = cd_label,
};
static const struct scsipi_periphsw cd_switch = {
@@ -262,20 +272,37 @@
cdattach(device_t parent, device_t self, void *aux)
{
struct cd_softc *cd = device_private(self);
+ struct dk_softc *dksc = &cd->sc_dksc;
struct scsipibus_attach_args *sa = aux;
struct scsipi_periph *periph = sa->sa_periph;
+ int dtype;
SC_DEBUG(periph, SCSIPI_DB2, ("cdattach: "));
- cd->sc_dev = self;
-
- mutex_init(&cd->sc_lock, MUTEX_DEFAULT, IPL_NONE);
-
- if (SCSIPI_BUSTYPE_TYPE(scsipi_periph_bustype(sa->sa_periph)) ==
- SCSIPI_BUSTYPE_SCSI && periph->periph_version == 0)
- cd->flags |= CDF_ANCIENT;
-
- bufq_alloc(&cd->buf_queue, "disksort", BUFQ_SORT_RAWBLOCK);
+ switch (SCSIPI_BUSTYPE_TYPE(scsipi_periph_bustype(sa->sa_periph))) {
+ case SCSIPI_BUSTYPE_SCSI:
+ dtype = DKTYPE_SCSI;
+ if (periph->periph_version == 0)
+ cd->flags |= CDF_ANCIENT;
+ break;
+ case SCSIPI_BUSTYPE_ATAPI:
+ dtype = DKTYPE_ATAPI;
+ break;
+ default:
+ dtype = DKTYPE_UNKNOWN;
+ break;
+ }
+
+ /*
+ * Initialize and attach the disk structure.
+ */
+ dk_init(dksc, self, dtype);
+ disk_init(&dksc->sc_dkdev, dksc->sc_xname, &cddkdriver);
+
+ dk_attach(dksc);
+ disk_attach(&dksc->sc_dkdev);
+
+ bufq_alloc(&dksc->sc_bufq, "disksort", BUFQ_SORT_RAWBLOCK);
callout_init(&cd->sc_callout, 0);
@@ -284,7 +311,7 @@
*/
cd->sc_periph = periph;
- periph->periph_dev = cd->sc_dev;
+ periph->periph_dev = dksc->sc_dev;
periph->periph_switch = &cd_switch;
/*
@@ -296,17 +323,8 @@
SCSIPI_CHAN_MAX_PERIPH(periph->periph_channel);
periph->periph_flags |= PERIPH_GROW_OPENINGS;
- /*
- * Initialize and attach the disk structure.
- */
- disk_init(&cd->sc_dk, device_xname(cd->sc_dev), &cddkdriver);
- disk_attach(&cd->sc_dk);
-
+ aprint_naive("\n");
aprint_normal("\n");
- aprint_naive("\n");
-
- rnd_attach_source(&cd->rnd_source, device_xname(cd->sc_dev),
- RND_TYPE_DISK, RND_FLAG_DEFAULT);
if (!pmf_device_register(self, NULL, NULL))
aprint_error_dev(self, "couldn't establish power handler\n");
@@ -316,16 +334,18 @@
cddetach(device_t self, int flags)
{
struct cd_softc *cd = device_private(self);
+ struct dk_softc *dksc = &cd->sc_dksc;
struct scsipi_periph *periph = cd->sc_periph;
struct scsipi_channel *chan = periph->periph_channel;
- int bmaj, cmaj, i, mn;
-
- if (cd->sc_dk.dk_openmask != 0 && (flags & DETACH_FORCE) == 0)
- return EBUSY;
+ int bmaj, cmaj, i, mn, rc;
+
+ if ((rc = disk_begindetach(&dksc->sc_dkdev, cd_lastclose, self, flags)) != 0)
+ return rc;
/* locate the major number */
bmaj = bdevsw_lookup_major(&cd_bdevsw);
cmaj = cdevsw_lookup_major(&cd_cdevsw);
+
/* Nuke the vnodes for any open instances */
for (i = 0; i < MAXPARTITIONS; i++) {
mn = CDMINOR(device_unit(self), i);
@@ -336,183 +356,185 @@
/* kill any pending restart */
callout_stop(&cd->sc_callout);
- mutex_enter(chan_mtx(chan));
-
- /* Kill off any queued buffers. */
- bufq_drain(cd->buf_queue);
+ dk_drain(dksc);
/* Kill off any pending commands. */
+ mutex_enter(chan_mtx(chan));
scsipi_kill_pending(cd->sc_periph);
-
mutex_exit(chan_mtx(chan));
- bufq_free(cd->buf_queue);
-
- mutex_destroy(&cd->sc_lock);
+ bufq_free(dksc->sc_bufq);
/* Detach from the disk list. */
- disk_detach(&cd->sc_dk);
- disk_destroy(&cd->sc_dk);
-
- /* Unhook the entropy source. */
- rnd_detach_source(&cd->rnd_source);
+ disk_detach(&dksc->sc_dkdev);
+ disk_destroy(&dksc->sc_dkdev);
+
+ dk_detach(dksc);
+
+ callout_destroy(&cd->sc_callout);
+
+ pmf_device_deregister(self);
return (0);
}
/*
+ * Serialized by caller
+ */
+static int
+cd_firstopen(device_t self, dev_t dev, int flag, int fmt)
+{
+ struct cd_softc *cd = device_private(self);
+ struct scsipi_periph *periph = cd->sc_periph;
+ struct scsipi_adapter *adapt = periph->periph_channel->chan_adapter;
+ int error, silent;
+ int part;
+
+ part = CDPART(dev);
+
+ error = scsipi_adapter_addref(adapt);
+ if (error)
+ return error;
+
+ if ((part == RAW_PART && fmt == S_IFCHR) || (flag & FSILENT))
+ silent = XS_CTL_SILENT;
+ else
+ silent = 0;
+
+ /* make cdclose() loud again */
+ cd->flags &= ~CDF_EJECTED;
+
+ /* Check that it is still responding and ok. */
+ error = scsipi_test_unit_ready(periph,
+ XS_CTL_IGNORE_ILLEGAL_REQUEST | XS_CTL_IGNORE_MEDIA_CHANGE |
+ XS_CTL_SILENT);
+
+ /*
+ * Start the pack spinning if necessary. Always allow the
+ * raw parition to be opened, for raw IOCTLs. Data transfers
+ * will check for SDEV_MEDIA_LOADED.
+ */
+ if (error == EIO) {
+ error = scsipi_start(periph, SSS_START, silent);
+ if (error == EINVAL)
+ error = EIO;
+ }
+ if (error)
+ goto bad;
+
+ /* Lock the pack in. */
+ error = scsipi_prevent(periph, SPAMR_PREVENT_DT,
+ XS_CTL_IGNORE_ILLEGAL_REQUEST |
+ XS_CTL_IGNORE_MEDIA_CHANGE);
+ SC_DEBUG(periph, SCSIPI_DB1,
+ ("cdopen: scsipi_prevent, error=%d\n", error));
+ if (error)
+ goto bad;
+
+ if ((periph->periph_flags & PERIPH_MEDIA_LOADED) == 0) {
+ int param_error;
+
+ /* Load the physical device parameters. */
+ param_error = cd_get_parms(cd, 0);
+ if (param_error == CDGP_RESULT_OFFLINE) {
+ error = ENXIO;
+ goto bad2;
+ }
+ periph->periph_flags |= PERIPH_MEDIA_LOADED;
+
+ SC_DEBUG(periph, SCSIPI_DB3, ("Params loaded "));
+
+ cd_set_geometry(cd);
+ }
+
+ periph->periph_flags |= PERIPH_OPEN;
+ return 0;
+
+bad2:
+ scsipi_prevent(periph, SPAMR_ALLOW,
+ XS_CTL_IGNORE_ILLEGAL_REQUEST |
Home |
Main Index |
Thread Index |
Old Index