Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/uebayasi-xip]: src/sys/dev Sync with HEAD.
details: https://anonhg.NetBSD.org/src/rev/405ad0669ebd
branches: uebayasi-xip
changeset: 751862:405ad0669ebd
user: uebayasi <uebayasi%NetBSD.org@localhost>
date: Thu Nov 18 16:07:52 2010 +0000
description:
Sync with HEAD.
diffstat:
sys/dev/md.c | 158 +++++++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 121 insertions(+), 37 deletions(-)
diffs (truncated from 340 to 300 lines):
diff -r 21ab699fff2c -r 405ad0669ebd sys/dev/md.c
--- a/sys/dev/md.c Thu Nov 18 01:53:04 2010 +0000
+++ b/sys/dev/md.c Thu Nov 18 16:07:52 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: md.c,v 1.62 2010/01/21 02:14:42 dyoung Exp $ */
+/* $NetBSD: md.c,v 1.62.2.1 2010/11/18 16:07:52 uebayasi Exp $ */
/*
* Copyright (c) 1995 Gordon W. Ross, Leo Weppelman.
@@ -40,10 +40,9 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: md.c,v 1.62 2010/01/21 02:14:42 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: md.c,v 1.62.2.1 2010/11/18 16:07:52 uebayasi Exp $");
#include "opt_md.h"
-#include "opt_tftproot.h"
#include <sys/param.h>
#include <sys/kernel.h>
@@ -78,6 +77,7 @@
/* autoconfig stuff... */
struct md_softc {
+ device_t sc_dev; /* Self. */
struct disk sc_dkdev; /* hook for generic disk handling */
struct md_conf sc_md;
struct bufq_state *sc_buflist;
@@ -115,43 +115,23 @@
CFATTACH_DECL3_NEW(md, sizeof(struct md_softc),
0, md_attach, md_detach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN);
+static kmutex_t md_device_lock; /* Protect unit creation / deletion. */
extern size_t md_root_size;
+static void md_set_disklabel(struct md_softc *);
+
/*
* This is called if we are configured as a pseudo-device
*/
void
mdattach(int n)
{
- int i;
- cfdata_t cf;
-#ifdef TFTPROOT
- /*
- * Attachement of md0 must be done after md_root_setconf(),
- * because the RAMdisk is not loaded yet.
- */
- if (md_root_size == 0)
- return;
-#endif
- if (config_cfattach_attach("md", &md_ca)) {
- printf("md: cfattach_attach failed\n");
+ mutex_init(&md_device_lock, MUTEX_DEFAULT, IPL_NONE);
+ if (config_cfattach_attach(md_cd.cd_name, &md_ca)) {
+ aprint_error("%s: cfattach_attach failed\n", md_cd.cd_name);
return;
}
-
- /* XXX: Are we supposed to provide a default? */
- if (n <= 1)
- n = 1;
-
- /* Attach as if by autoconfig. */
- for (i = 0; i < n; i++) {
- cf = malloc(sizeof(*cf), M_DEVBUF, M_WAITOK);
- cf->cf_name = "md";
- cf->cf_atname = "md";
- cf->cf_unit = i;
- cf->cf_fstate = FSTATE_NOTFOUND;
- (void)config_attach_pseudo(cf);
- }
}
static void
@@ -159,6 +139,7 @@
{
struct md_softc *sc = device_private(self);
+ sc->sc_dev = self;
bufq_alloc(&sc->sc_buflist, "fcfs", 0);
/* XXX - Could accept aux info here to set the config. */
@@ -177,6 +158,9 @@
disk_init(&sc->sc_dkdev, device_xname(self), &mddkdriver);
disk_attach(&sc->sc_dkdev);
+ if (sc->sc_type != MD_UNCONFIGURED)
+ md_set_disklabel(sc);
+
if (!pmf_device_register(self, NULL, NULL))
aprint_error_dev(self, "couldn't establish power handler\n");
}
@@ -240,13 +224,29 @@
int unit;
int part = DISKPART(dev);
int pmask = 1 << part;
+ cfdata_t cf;
struct md_softc *sc;
struct disk *dk;
+ mutex_enter(&md_device_lock);
unit = MD_UNIT(dev);
sc = device_lookup_private(&md_cd, unit);
- if (sc == NULL)
- return ENXIO;
+ if (sc == NULL) {
+ if (part != RAW_PART) {
+ mutex_exit(&md_device_lock);
+ return ENXIO;
+ }
+ cf = malloc(sizeof(*cf), M_DEVBUF, M_WAITOK);
+ cf->cf_name = md_cd.cd_name;
+ cf->cf_atname = md_cd.cd_name;
+ cf->cf_unit = unit;
+ cf->cf_fstate = FSTATE_STAR;
+ sc = device_private(config_attach_pseudo(cf));
+ if (sc == NULL) {
+ mutex_exit(&md_device_lock);
+ return ENOMEM;
+ }
+ }
dk = &sc->sc_dkdev;
@@ -265,8 +265,10 @@
* This is a normal, "slave" device, so
* enforce initialized.
*/
- if (sc->sc_type == MD_UNCONFIGURED)
+ if (sc->sc_type == MD_UNCONFIGURED) {
+ mutex_exit(&md_device_lock);
return ENXIO;
+ }
ok:
/* XXX duplicates code in dk_open(). Call dk_open(), instead? */
@@ -284,6 +286,7 @@
dk->dk_openmask = dk->dk_copenmask | dk->dk_bopenmask;
mutex_exit(&dk->dk_openlock);
+ mutex_exit(&md_device_lock);
return 0;
}
@@ -292,6 +295,8 @@
{
int part = DISKPART(dev);
int pmask = 1 << part;
+ int error;
+ cfdata_t cf;
struct md_softc *sc;
struct disk *dk;
@@ -314,7 +319,14 @@
dk->dk_openmask = dk->dk_copenmask | dk->dk_bopenmask;
mutex_exit(&dk->dk_openlock);
- return 0;
+
+ mutex_enter(&md_device_lock);
+ cf = device_cfdata(sc->sc_dev);
+ error = config_detach(sc->sc_dev, DETACH_QUIET);
+ if (! error)
+ free(cf, M_DEVBUF);
+ mutex_exit(&md_device_lock);
+ return error;
}
static int
@@ -353,6 +365,7 @@
struct md_softc *sc;
void * addr;
size_t off, xfer;
+ bool is_read;
sc = device_lookup_private(&md_cd, MD_UNIT(bp->b_dev));
@@ -375,10 +388,11 @@
case MD_KMEM_FIXED:
case MD_KMEM_ALLOCATED:
/* These are in kernel space. Access directly. */
+ is_read = ((bp->b_flags & B_READ) == B_READ);
bp->b_resid = bp->b_bcount;
off = (bp->b_blkno << DEV_BSHIFT);
if (off >= sc->sc_size) {
- if (bp->b_flags & B_READ)
+ if (is_read)
break; /* EOF */
goto set_eio;
}
@@ -386,10 +400,12 @@
if (xfer > (sc->sc_size - off))
xfer = (sc->sc_size - off);
addr = (char *)sc->sc_addr + off;
- if (bp->b_flags & B_READ)
+ disk_busy(&sc->sc_dkdev);
+ if (is_read)
memcpy(bp->b_data, addr, xfer);
else
memcpy(addr, bp->b_data, xfer);
+ disk_unbusy(&sc->sc_dkdev, xfer, is_read);
bp->b_resid -= xfer;
break;
@@ -408,10 +424,28 @@
{
struct md_softc *sc;
struct md_conf *umd;
+ struct disklabel *lp;
+ struct partinfo *pp;
if ((sc = device_lookup_private(&md_cd, MD_UNIT(dev))) == NULL)
return ENXIO;
+ if (sc->sc_type != MD_UNCONFIGURED) {
+ switch (cmd) {
+ case DIOCGDINFO:
+ lp = (struct disklabel *)data;
+ *lp = *sc->sc_dkdev.dk_label;
+ return 0;
+
+ case DIOCGPART:
+ pp = (struct partinfo *)data;
+ pp->disklab = sc->sc_dkdev.dk_label;
+ pp->part =
+ &sc->sc_dkdev.dk_label->d_partitions[DISKPART(dev)];
+ return 0;
+ }
+ }
+
/* If this is not the raw partition, punt! */
if (DISKPART(dev) != RAW_PART)
return ENOTTY;
@@ -441,6 +475,50 @@
return EINVAL;
}
+static void
+md_set_disklabel(struct md_softc *sc)
+{
+ struct disklabel *lp = sc->sc_dkdev.dk_label;
+ struct partition *pp;
+
+ memset(lp, 0, sizeof(*lp));
+
+ lp->d_secsize = DEV_BSIZE;
+ lp->d_secperunit = sc->sc_size / DEV_BSIZE;
+ if (lp->d_secperunit >= (32*64)) {
+ lp->d_nsectors = 32;
+ lp->d_ntracks = 64;
+ lp->d_ncylinders = lp->d_secperunit / (32*64);
+ } else {
+ lp->d_nsectors = 1;
+ lp->d_ntracks = 1;
+ lp->d_ncylinders = lp->d_secperunit;
+ }
+ lp->d_secpercyl = lp->d_ntracks*lp->d_nsectors;
+
+ strncpy(lp->d_typename, md_cd.cd_name, sizeof(lp->d_typename));
+ lp->d_type = DTYPE_UNKNOWN;
+ strncpy(lp->d_packname, "fictitious", sizeof(lp->d_packname));
+ lp->d_rpm = 3600;
+ lp->d_interleave = 1;
+ lp->d_flags = 0;
+
+ pp = &lp->d_partitions[0];
+ pp->p_offset = 0;
+ pp->p_size = lp->d_secperunit;
+ pp->p_fstype = FS_BSDFFS;
+
+ pp = &lp->d_partitions[RAW_PART];
+ pp->p_offset = 0;
+ pp->p_size = lp->d_secperunit;
+ pp->p_fstype = FS_UNUSED;
+
+ lp->d_npartitions = RAW_PART+1;
+ lp->d_magic = DISKMAGIC;
+ lp->d_magic2 = DISKMAGIC;
+ lp->d_checksum = dkcksum(lp);
+}
+
/*
* Handle ioctl MD_SETCONF for (sc_type == MD_KMEM_ALLOCATED)
* Just allocate some kernel memory and return.
@@ -462,6 +540,7 @@
sc->sc_addr = (void *)addr; /* kernel space */
sc->sc_size = (size_t)size;
sc->sc_type = MD_KMEM_ALLOCATED;
+ md_set_disklabel(sc);
return 0;
}
@@ -489,6 +568,7 @@
sc->sc_addr = umd->md_addr; /* user space */
sc->sc_size = umd->md_size;
Home |
Main Index |
Thread Index |
Old Index