diff options
author | scottl <scottl@FreeBSD.org> | 2007-05-10 15:33:41 +0000 |
---|---|---|
committer | scottl <scottl@FreeBSD.org> | 2007-05-10 15:33:41 +0000 |
commit | c1f92f9a266a46d212d75d17c49062fcd72a88b1 (patch) | |
tree | 0b192bdf920c7ff1fa9073529fd2c7ef9ca382e6 | |
parent | ced6c23397bb86d97c036e35c740110c6cab4599 (diff) | |
download | FreeBSD-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.c | 39 | ||||
-rw-r--r-- | sys/dev/mfi/mfi_disk.c | 42 | ||||
-rw-r--r-- | sys/dev/mfi/mfi_ioctl.h | 10 | ||||
-rw-r--r-- | sys/dev/mfi/mfi_pci.c | 16 | ||||
-rw-r--r-- | sys/dev/mfi/mfivar.h | 16 |
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; |