summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2007-05-10 15:33:41 +0000
committerscottl <scottl@FreeBSD.org>2007-05-10 15:33:41 +0000
commitc1f92f9a266a46d212d75d17c49062fcd72a88b1 (patch)
tree0b192bdf920c7ff1fa9073529fd2c7ef9ca382e6
parentced6c23397bb86d97c036e35c740110c6cab4599 (diff)
downloadFreeBSD-src-c1f92f9a266a46d212d75d17c49062fcd72a88b1.zip
FreeBSD-src-c1f92f9a266a46d212d75d17c49062fcd72a88b1.tar.gz
Collapse the mfi_ld object. Add an ioctl to help management apps map
array Id's to FreeBSD device names.
-rw-r--r--sys/dev/mfi/mfi.c39
-rw-r--r--sys/dev/mfi/mfi_disk.c42
-rw-r--r--sys/dev/mfi/mfi_ioctl.h10
-rw-r--r--sys/dev/mfi/mfi_pci.c16
-rw-r--r--sys/dev/mfi/mfivar.h16
5 files changed, 79 insertions, 44 deletions
diff --git a/sys/dev/mfi/mfi.c b/sys/dev/mfi/mfi.c
index dcbfdd4..2dae176 100644
--- a/sys/dev/mfi/mfi.c
+++ b/sys/dev/mfi/mfi.c
@@ -1363,7 +1363,6 @@ mfi_add_ld_complete(struct mfi_command *cm)
struct mfi_frame_header *hdr;
struct mfi_ld_info *ld_info;
struct mfi_softc *sc;
- struct mfi_ld *ld;
device_t child;
sc = cm->cm_sc;
@@ -1377,25 +1376,13 @@ mfi_add_ld_complete(struct mfi_command *cm)
}
mfi_release_command(cm);
- ld = malloc(sizeof(struct mfi_ld), M_MFIBUF, M_NOWAIT|M_ZERO);
- if (ld == NULL) {
- device_printf(sc->mfi_dev, "Cannot allocate ld\n");
- free(ld_info, M_MFIBUF);
- return;
- }
-
if ((child = device_add_child(sc->mfi_dev, "mfid", -1)) == NULL) {
device_printf(sc->mfi_dev, "Failed to add logical disk\n");
- free(ld, M_MFIBUF);
free(ld_info, M_MFIBUF);
return;
}
- ld->ld_id = ld_info->ld_config.properties.ld.v.target_id;
- ld->ld_disk = child;
- ld->ld_info = ld_info;
-
- device_set_ivars(child, ld);
+ device_set_ivars(child, ld_info);
device_set_desc(child, "MFI Logical Disk");
mtx_unlock(&sc->mfi_io_lock);
mtx_lock(&Giant);
@@ -1802,6 +1789,30 @@ mfi_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, d_thread_t *td)
break;
}
break;
+ case MFIIO_QUERY_DISK:
+ {
+ struct mfi_query_disk *qd;
+ struct mfi_disk *ld;
+
+ qd = (struct mfi_query_disk *)arg;
+ mtx_lock(&sc->mfi_io_lock);
+ TAILQ_FOREACH(ld, &sc->mfi_ld_tqh, ld_link) {
+ if (ld->ld_id == qd->array_id)
+ break;
+ }
+ if (ld == NULL) {
+ qd->present = 0;
+ mtx_unlock(&sc->mfi_io_lock);
+ return (0);
+ }
+ qd->present = 1;
+ if (ld->ld_flags & MFI_DISK_FLAGS_OPEN)
+ qd->open = 1;
+ bzero(qd->devname, SPECNAMELEN + 1);
+ snprintf(qd->devname, SPECNAMELEN, "mfid%d", ld->ld_unit);
+ mtx_unlock(&sc->mfi_io_lock);
+ break;
+ }
case MFI_CMD:
ioc = (struct mfi_ioc_packet *)arg;
diff --git a/sys/dev/mfi/mfi_disk.c b/sys/dev/mfi/mfi_disk.c
index 35de4df..290bf47 100644
--- a/sys/dev/mfi/mfi_disk.c
+++ b/sys/dev/mfi/mfi_disk.c
@@ -65,15 +65,6 @@ static dumper_t mfi_disk_dump;
static devclass_t mfi_disk_devclass;
-struct mfi_disk {
- device_t ld_dev;
- int ld_id;
- int ld_unit;
- struct mfi_softc *ld_controller;
- struct mfi_ld *ld_ld;
- struct disk *ld_disk;
-};
-
static device_method_t mfi_disk_methods[] = {
DEVMETHOD(device_probe, mfi_disk_probe),
DEVMETHOD(device_attach, mfi_disk_attach),
@@ -100,25 +91,26 @@ static int
mfi_disk_attach(device_t dev)
{
struct mfi_disk *sc;
- struct mfi_ld *ld;
+ struct mfi_ld_info *ld_info;
uint64_t sectors;
uint32_t secsize;
char *state;
sc = device_get_softc(dev);
- ld = device_get_ivars(dev);
+ ld_info = device_get_ivars(dev);
sc->ld_dev = dev;
- sc->ld_id = ld->ld_id;
+ sc->ld_id = ld_info->ld_config.properties.ld.v.target_id;
sc->ld_unit = device_get_unit(dev);
- sc->ld_ld = device_get_ivars(dev);
+ sc->ld_info = ld_info;
sc->ld_controller = device_get_softc(device_get_parent(dev));
+ sc->ld_flags = 0;
- sectors = ld->ld_info->size;
+ sectors = ld_info->size;
secsize = MFI_SECTOR_LEN;
- TAILQ_INSERT_TAIL(&sc->ld_controller->mfi_ld_tqh, ld, ld_link);
+ TAILQ_INSERT_TAIL(&sc->ld_controller->mfi_ld_tqh, sc, ld_link);
- switch (ld->ld_info->ld_config.params.state) {
+ switch (ld_info->ld_config.params.state) {
case MFI_LD_STATE_OFFLINE:
state = "offline";
break;
@@ -137,7 +129,7 @@ mfi_disk_attach(device_t dev)
}
device_printf(dev, "%juMB (%ju sectors) RAID volume '%s' is %s\n",
sectors / (1024 * 1024 / secsize), sectors,
- ld->ld_info->ld_config.properties.name,
+ ld_info->ld_config.properties.name,
state);
sc->ld_disk = disk_alloc();
@@ -170,9 +162,11 @@ mfi_disk_detach(device_t dev)
sc = device_get_softc(dev);
- if (sc->ld_disk->d_flags & DISKFLAG_OPEN)
+ if ((sc->ld_disk->d_flags & DISKFLAG_OPEN) ||
+ (sc->ld_flags & MFI_DISK_FLAGS_OPEN))
return (EBUSY);
+ free(sc->ld_info, M_MFIBUF);
disk_destroy(sc->ld_disk);
return (0);
}
@@ -180,6 +174,12 @@ mfi_disk_detach(device_t dev)
static int
mfi_disk_open(struct disk *dp)
{
+ struct mfi_disk *sc;
+
+ sc = dp->d_drv1;
+ mtx_lock(&sc->ld_controller->mfi_io_lock);
+ sc->ld_flags |= MFI_DISK_FLAGS_OPEN;
+ mtx_unlock(&sc->ld_controller->mfi_io_lock);
return (0);
}
@@ -187,6 +187,12 @@ mfi_disk_open(struct disk *dp)
static int
mfi_disk_close(struct disk *dp)
{
+ struct mfi_disk *sc;
+
+ sc = dp->d_drv1;
+ mtx_lock(&sc->ld_controller->mfi_io_lock);
+ sc->ld_flags &= ~MFI_DISK_FLAGS_OPEN;
+ mtx_unlock(&sc->ld_controller->mfi_io_lock);
return (0);
}
diff --git a/sys/dev/mfi/mfi_ioctl.h b/sys/dev/mfi/mfi_ioctl.h
index 747086f..40521ae 100644
--- a/sys/dev/mfi/mfi_ioctl.h
+++ b/sys/dev/mfi/mfi_ioctl.h
@@ -107,6 +107,16 @@ struct mfi_linux_ioc_aen {
uint32_t laen_class_locale;
} __packed;
+struct mfi_query_disk {
+ uint8_t array_id;
+ uint8_t present;
+ uint8_t open;
+ uint8_t reserved; /* reserved for future use */
+ char devname[SPECNAMELEN + 1];
+} __packed;
+
+#define MFIIO_QUERY_DISK _IOWR('Q', 102, struct mfi_query_disk)
+
/*
* Create a second set so the FreeBSD native ioctl doesn't
* conflict in FreeBSD ioctl handler. Translate in mfi_linux.c.
diff --git a/sys/dev/mfi/mfi_pci.c b/sys/dev/mfi/mfi_pci.c
index ebd1fef..ccec1d0 100644
--- a/sys/dev/mfi/mfi_pci.c
+++ b/sys/dev/mfi/mfi_pci.c
@@ -195,21 +195,23 @@ static int
mfi_pci_detach(device_t dev)
{
struct mfi_softc *sc;
- struct mfi_ld *ld;
+ struct mfi_disk *ld;
int error;
sc = device_get_softc(dev);
- if ((sc->mfi_flags & MFI_FLAGS_OPEN) != 0)
+ mtx_lock(&sc->mfi_io_lock);
+ if ((sc->mfi_flags & MFI_FLAGS_OPEN) != 0) {
+ mtx_unlock(&sc->mfi_io_lock);
return (EBUSY);
+ }
- while ((ld = TAILQ_FIRST(&sc->mfi_ld_tqh)) != NULL) {
- error = device_delete_child(dev, ld->ld_disk);
- if (error)
+ while ((ld = TAILQ_FIRST(&sc->mfi_ld_tqh)) != NULL) {
+ if ((error = device_delete_child(dev, ld->ld_dev)) != 0) {
+ mtx_unlock(&sc->mfi_io_lock);
return (error);
+ }
TAILQ_REMOVE(&sc->mfi_ld_tqh, ld, ld_link);
- free(ld->ld_info, M_MFIBUF);
- free(ld, M_MFIBUF);
}
EVENTHANDLER_DEREGISTER(shutdown_final, sc->mfi_eh);
diff --git a/sys/dev/mfi/mfivar.h b/sys/dev/mfi/mfivar.h
index 7028cc4..af5bb28 100644
--- a/sys/dev/mfi/mfivar.h
+++ b/sys/dev/mfi/mfivar.h
@@ -43,6 +43,7 @@ struct mfi_hwcomms {
};
struct mfi_softc;
+struct disk;
struct mfi_command {
TAILQ_ENTRY(mfi_command) cm_link;
@@ -74,11 +75,16 @@ struct mfi_command {
int cm_index;
};
-struct mfi_ld {
- TAILQ_ENTRY(mfi_ld) ld_link;
- device_t ld_disk;
+struct mfi_disk {
+ TAILQ_ENTRY(mfi_disk) ld_link;
+ device_t ld_dev;
+ int ld_id;
+ int ld_unit;
+ struct mfi_softc *ld_controller;
struct mfi_ld_info *ld_info;
- int ld_id;
+ struct disk *ld_disk;
+ int ld_flags;
+#define MFI_DISK_FLAGS_OPEN 0x01
};
struct mfi_aen {
@@ -169,7 +175,7 @@ struct mfi_softc {
*/
uint32_t mfi_max_io;
- TAILQ_HEAD(,mfi_ld) mfi_ld_tqh;
+ TAILQ_HEAD(,mfi_disk) mfi_ld_tqh;
eventhandler_tag mfi_eh;
struct cdev *mfi_cdev;
OpenPOWER on IntegriCloud