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:
parent
ced6c23397
commit
c1f92f9a26
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user