diff options
author | thomas <thomas@FreeBSD.org> | 2003-10-07 14:46:59 +0000 |
---|---|---|
committer | thomas <thomas@FreeBSD.org> | 2003-10-07 14:46:59 +0000 |
commit | 5490709ba19a70d01f2c0cb374e5e424e29e32e4 (patch) | |
tree | b10f5253afc30685ea6f4f4ac5c12d0179f041e3 | |
parent | 93a92c1266311444a1058482a428106431367842 (diff) | |
download | FreeBSD-src-5490709ba19a70d01f2c0cb374e5e424e29e32e4.zip FreeBSD-src-5490709ba19a70d01f2c0cb374e5e424e29e32e4.tar.gz |
(cdcleanup): Defend against calling sysctl_ctx_free before the sysctl_ctx
has been initialized.
(cdsysctlinit): Set flag CD_FLAG_SCTX_INIT after sysctl_ctx has been
initialized.
This resolves a panic encountered when a cd drive is sucessfully probed
but fails to attach.
Reviewed by: ken
-rw-r--r-- | sys/cam/scsi/scsi_cd.c | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c index db382ed..285c221 100644 --- a/sys/cam/scsi/scsi_cd.c +++ b/sys/cam/scsi/scsi_cd.c @@ -92,17 +92,18 @@ typedef enum { } cd_quirks; typedef enum { - CD_FLAG_INVALID = 0x001, - CD_FLAG_NEW_DISC = 0x002, - CD_FLAG_DISC_LOCKED = 0x004, - CD_FLAG_DISC_REMOVABLE = 0x008, - CD_FLAG_TAGGED_QUEUING = 0x010, - CD_FLAG_CHANGER = 0x040, - CD_FLAG_ACTIVE = 0x080, - CD_FLAG_SCHED_ON_COMP = 0x100, - CD_FLAG_RETRY_UA = 0x200, - CD_FLAG_VALID_MEDIA = 0x400, - CD_FLAG_VALID_TOC = 0x800 + CD_FLAG_INVALID = 0x0001, + CD_FLAG_NEW_DISC = 0x0002, + CD_FLAG_DISC_LOCKED = 0x0004, + CD_FLAG_DISC_REMOVABLE = 0x0008, + CD_FLAG_TAGGED_QUEUING = 0x0010, + CD_FLAG_CHANGER = 0x0040, + CD_FLAG_ACTIVE = 0x0080, + CD_FLAG_SCHED_ON_COMP = 0x0100, + CD_FLAG_RETRY_UA = 0x0200, + CD_FLAG_VALID_MEDIA = 0x0400, + CD_FLAG_VALID_TOC = 0x0800, + CD_FLAG_SCTX_INIT = 0x1000 } cd_flags; typedef enum { @@ -421,7 +422,8 @@ cdcleanup(struct cam_periph *periph) xpt_print_path(periph->path); printf("removing device entry\n"); - if (sysctl_ctx_free(&softc->sysctl_ctx) != 0) { + if ((softc->flags & CD_FLAG_SCTX_INIT) != 0 + && sysctl_ctx_free(&softc->sysctl_ctx) != 0) { xpt_print_path(periph->path); printf("can't remove sysctl context\n"); } @@ -581,6 +583,7 @@ cdsysctlinit(void *context, int pending) mtx_lock(&Giant); sysctl_ctx_init(&softc->sysctl_ctx); + softc->flags |= CD_FLAG_SCTX_INIT; softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx, SYSCTL_STATIC_CHILDREN(_kern_cam_cd), OID_AUTO, tmpstr2, CTLFLAG_RD, 0, tmpstr); |