summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/cam/scsi/scsi_da.c62
1 files changed, 32 insertions, 30 deletions
diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c
index 986648a..7095eeb 100644
--- a/sys/cam/scsi/scsi_da.c
+++ b/sys/cam/scsi/scsi_da.c
@@ -998,11 +998,6 @@ dacleanup(struct cam_periph *periph)
xpt_print(periph->path, "can't remove sysctl context\n");
}
- /*
- * Nullify our periph pointer here to try and catch
- * race conditions in callbacks/downcalls.
- */
- softc->disk->d_drv1 = NULL;
disk_destroy(softc->disk);
callout_drain(&softc->sendordered_c);
free(softc, M_DEVBUF);
@@ -1082,8 +1077,13 @@ dasysctlinit(void *context, int pending)
struct ccb_trans_settings cts;
periph = (struct cam_periph *)context;
- if (cam_periph_acquire(periph) != CAM_REQ_CMP)
+ /*
+ * periph was held for us when this task was enqueued
+ */
+ if (periph->flags & CAM_PERIPH_INVALID) {
+ cam_periph_release(periph);
return;
+ }
softc = (struct da_softc *)periph->softc;
snprintf(tmpstr, sizeof(tmpstr), "CAM DA unit %d", periph->unit_number);
@@ -1263,29 +1263,6 @@ daregister(struct cam_periph *periph, void *arg)
* Register this media as a disk
*/
- mtx_unlock(periph->sim->mtx);
- softc->disk = disk_alloc();
- softc->disk->d_open = daopen;
- softc->disk->d_close = daclose;
- softc->disk->d_strategy = dastrategy;
- softc->disk->d_dump = dadump;
- softc->disk->d_name = "da";
- softc->disk->d_drv1 = periph;
- if (cpi.maxio == 0)
- softc->disk->d_maxsize = DFLTPHYS; /* traditional default */
- else if (cpi.maxio > MAXPHYS)
- softc->disk->d_maxsize = MAXPHYS; /* for safety */
- else
- softc->disk->d_maxsize = cpi.maxio;
- softc->disk->d_unit = periph->unit_number;
- softc->disk->d_flags = 0;
- if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0)
- softc->disk->d_flags |= DISKFLAG_CANFLUSHCACHE;
- strlcpy(softc->disk->d_ident, cgd->serial_num,
- MIN(sizeof(softc->disk->d_ident), cgd->serial_num_len + 1));
- disk_create(softc->disk, DISK_VERSION);
- mtx_lock(periph->sim->mtx);
-
/*
* Add async callbacks for bus reset and
* bus device reset calls. I don't bother
@@ -1303,7 +1280,6 @@ daregister(struct cam_periph *periph, void *arg)
* the end of probe.
*/
(void)cam_periph_hold(periph, PRIBIO);
- xpt_schedule(periph, CAM_PRIORITY_DEV);
/*
* Schedule a periodic event to occasionally send an
@@ -1314,6 +1290,31 @@ daregister(struct cam_periph *periph, void *arg)
(DA_DEFAULT_TIMEOUT * hz) / DA_ORDEREDTAG_INTERVAL,
dasendorderedtag, softc);
+ mtx_unlock(periph->sim->mtx);
+ softc->disk = disk_alloc();
+ softc->disk->d_open = daopen;
+ softc->disk->d_close = daclose;
+ softc->disk->d_strategy = dastrategy;
+ softc->disk->d_dump = dadump;
+ softc->disk->d_name = "da";
+ softc->disk->d_drv1 = periph;
+ if (cpi.maxio == 0)
+ softc->disk->d_maxsize = DFLTPHYS; /* traditional default */
+ else if (cpi.maxio > MAXPHYS)
+ softc->disk->d_maxsize = MAXPHYS; /* for safety */
+ else
+ softc->disk->d_maxsize = cpi.maxio;
+ softc->disk->d_unit = periph->unit_number;
+ softc->disk->d_flags = 0;
+ if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0)
+ softc->disk->d_flags |= DISKFLAG_CANFLUSHCACHE;
+ strlcpy(softc->disk->d_ident, cgd->serial_num,
+ MIN(sizeof(softc->disk->d_ident), cgd->serial_num_len + 1));
+ disk_create(softc->disk, DISK_VERSION);
+ mtx_lock(periph->sim->mtx);
+
+ xpt_schedule(periph, CAM_PRIORITY_DEV);
+
return(CAM_REQ_CMP);
}
@@ -1773,6 +1774,7 @@ dadone(struct cam_periph *periph, union ccb *done_ccb)
* Create our sysctl variables, now that we know
* we have successfully attached.
*/
+ (void) cam_periph_acquire(periph); /* increase the refcount */
taskqueue_enqueue(taskqueue_thread,&softc->sysctl_task);
}
softc->state = DA_STATE_NORMAL;
OpenPOWER on IntegriCloud