diff -ruNp cam.prev/cam_periph.c cam/cam_periph.c --- cam.prev/cam_periph.c 2010-03-21 08:04:50.000000000 +0200 +++ cam/cam_periph.c 2010-03-21 08:24:08.000000000 +0200 @@ -208,7 +208,6 @@ cam_periph_alloc(periph_ctor_t *periph_c periph->periph_oninval = periph_oninvalidate; periph->type = type; periph->periph_name = name; - periph->unit_number = camperiphunit(*p_drv, path_id, target_id, lun_id); periph->immediate_priority = CAM_PRIORITY_NONE; periph->refcount = 0; periph->sim = sim; @@ -216,31 +215,31 @@ cam_periph_alloc(periph_ctor_t *periph_c status = xpt_create_path(&path, periph, path_id, target_id, lun_id); if (status != CAM_REQ_CMP) goto failure; - periph->path = path; - init_level++; - - status = xpt_add_periph(periph); - - if (status != CAM_REQ_CMP) - goto failure; + xpt_lock_buses(); + periph->unit_number = camperiphunit(*p_drv, path_id, target_id, lun_id); cur_periph = TAILQ_FIRST(&(*p_drv)->units); while (cur_periph != NULL && cur_periph->unit_number < periph->unit_number) cur_periph = TAILQ_NEXT(cur_periph, unit_links); - if (cur_periph != NULL) TAILQ_INSERT_BEFORE(cur_periph, periph, unit_links); else { TAILQ_INSERT_TAIL(&(*p_drv)->units, periph, unit_links); (*p_drv)->generation++; } + xpt_unlock_buses(); init_level++; - status = periph_ctor(periph, arg); + status = xpt_add_periph(periph); + if (status != CAM_REQ_CMP) + goto failure; + init_level++; + + status = periph_ctor(periph, arg); if (status == CAM_REQ_CMP) init_level++; @@ -250,10 +249,12 @@ failure: /* Initialized successfully */ break; case 3: - TAILQ_REMOVE(&(*p_drv)->units, periph, unit_links); xpt_remove_periph(periph); /* FALLTHROUGH */ case 2: + xpt_lock_buses(); + TAILQ_REMOVE(&(*p_drv)->units, periph, unit_links); + xpt_unlock_buses(); xpt_free_path(periph->path); /* FALLTHROUGH */ case 1: diff -ruNp cam.prev/cam_xpt.c cam/cam_xpt.c --- cam.prev/cam_xpt.c 2010-03-21 08:04:50.000000000 +0200 +++ cam/cam_xpt.c 2010-03-21 08:07:23.000000000 +0200 @@ -2142,6 +2142,7 @@ xptpdperiphtraverse(struct periph_driver retval = 1; + xpt_lock_buses(); for (periph = (start_periph ? start_periph : TAILQ_FIRST(&(*pdrv)->units)); periph != NULL; periph = next_periph) { @@ -2149,9 +2150,12 @@ xptpdperiphtraverse(struct periph_driver next_periph = TAILQ_NEXT(periph, unit_links); retval = tr_func(periph, arg); - if (retval == 0) + if (retval == 0) { + xpt_unlock_buses(); return(retval); + } } + xpt_unlock_buses(); return(retval); }