Collapse the mfi_ld object. Add an ioctl to help management apps map

array Id's to FreeBSD device names.
This commit is contained in:
scottl 2007-05-10 15:33:41 +00:00
parent ced6c23397
commit c1f92f9a26
5 changed files with 79 additions and 44 deletions

View File

@ -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;

View File

@ -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);
}

View File

@ -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.

View File

@ -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);

View File

@ -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;