Lines 2901-2907
call_sim:
Link Here
|
2901 |
*/ |
2901 |
*/ |
2902 |
start_ccb->ccb_h.flags &= ~CAM_DEV_QFREEZE; |
2902 |
start_ccb->ccb_h.flags &= ~CAM_DEV_QFREEZE; |
2903 |
callout_stop(&dev->callout); |
2903 |
callout_stop(&dev->callout); |
|
|
2904 |
/* |
2905 |
* If CAM_DEV_REL_TIMEOUT_PENDING is still |
2906 |
* set, then the callout is still |
2907 |
* cancelable, since we hold the callout |
2908 |
* mutex and the callout function clears the |
2909 |
* flag before it ever unlocks/relocks the |
2910 |
* mutex. Since we already acquired a |
2911 |
* device ref for the callout we just |
2912 |
* stopped, we don't need another ref. |
2913 |
*/ |
2904 |
} else { |
2914 |
} else { |
|
|
2915 |
/* |
2916 |
* Since the callout gets a pointer to the |
2917 |
* device, acquire a reference to make sure |
2918 |
* the device can't go away until the |
2919 |
* callout finishes or is stopped. |
2920 |
*/ |
2921 |
xpt_acquire_device(dev); |
2905 |
|
2922 |
|
2906 |
start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE; |
2923 |
start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE; |
2907 |
} |
2924 |
} |
Lines 4355-4361
xpt_release_devq_device(struct cam_ed *dev, u_int count, int run_queue)
Link Here
|
4355 |
* to release this queue. |
4372 |
* to release this queue. |
4356 |
*/ |
4373 |
*/ |
4357 |
if ((dev->flags & CAM_DEV_REL_TIMEOUT_PENDING) != 0) { |
4374 |
if ((dev->flags & CAM_DEV_REL_TIMEOUT_PENDING) != 0) { |
4358 |
callout_stop(&dev->callout); |
4375 |
/* |
|
|
4376 |
* If CAM_DEV_REL_TIMEOUT_PENDING is still set, |
4377 |
* either the callout is still cancelable, or the |
4378 |
* callout function (xpt_release_devq_timeout) is |
4379 |
* our caller. It's too early for the callout |
4380 |
* itself to release its ref, so only release the |
4381 |
* device ref if we stop the callout. If we |
4382 |
* can't stop the callout, it will release |
4383 |
* its ref when it finishes. |
4384 |
*/ |
4385 |
if (callout_stop(&dev->callout) != 0) { |
4386 |
/* Release the callout's device reference */ |
4387 |
xpt_release_device(dev); |
4388 |
} |
4359 |
dev->flags &= ~CAM_DEV_REL_TIMEOUT_PENDING; |
4389 |
dev->flags &= ~CAM_DEV_REL_TIMEOUT_PENDING; |
4360 |
} |
4390 |
} |
4361 |
/* |
4391 |
/* |
Lines 4646-4651
static void
Link Here
|
4646 |
xpt_destroy_device(void *context, int pending) |
4676 |
xpt_destroy_device(void *context, int pending) |
4647 |
{ |
4677 |
{ |
4648 |
struct cam_ed *device = context; |
4678 |
struct cam_ed *device = context; |
|
|
4679 |
struct cam_eb *bus = device->target->bus; |
4680 |
struct cam_devq *devq; |
4681 |
|
4682 |
callout_drain(&device->callout); |
4683 |
|
4684 |
/* Release our slot in the devq */ |
4685 |
devq = bus->sim->devq; |
4686 |
mtx_lock(&devq->send_mtx); |
4687 |
KASSERT((device->flags & CAM_DEV_REL_TIMEOUT_PENDING) == 0, |
4688 |
("device %p has timeout pending", device)); |
4689 |
cam_devq_resize(devq, devq->send_queue.array_size - 1); |
4690 |
mtx_unlock(&devq->send_mtx); |
4691 |
|
4692 |
KASSERT(SLIST_EMPTY(&device->periphs), |
4693 |
("destroying device, but periphs list is not empty")); |
4694 |
KASSERT(device->devq_entry.index == CAM_UNQUEUED_INDEX, |
4695 |
("destroying device while still queued for ccbs")); |
4696 |
|
4697 |
xpt_release_target(device->target); |
4698 |
|
4699 |
cam_ccbq_fini(&device->ccbq); |
4700 |
/* |
4701 |
* Free allocated memory. free(9) does nothing if the |
4702 |
* supplied pointer is NULL, so it is safe to call without |
4703 |
* checking. |
4704 |
*/ |
4705 |
free(device->supported_vpds, M_CAMXPT); |
4706 |
free(device->device_id, M_CAMXPT); |
4707 |
free(device->ext_inq, M_CAMXPT); |
4708 |
free(device->physpath, M_CAMXPT); |
4709 |
free(device->rcap_buf, M_CAMXPT); |
4710 |
free(device->serial_num, M_CAMXPT); |
4649 |
|
4711 |
|
4650 |
mtx_lock(&device->device_mtx); |
4712 |
mtx_lock(&device->device_mtx); |
4651 |
mtx_destroy(&device->device_mtx); |
4713 |
mtx_destroy(&device->device_mtx); |
Lines 4723-4729
void
Link Here
|
4723 |
xpt_release_device(struct cam_ed *device) |
4785 |
xpt_release_device(struct cam_ed *device) |
4724 |
{ |
4786 |
{ |
4725 |
struct cam_eb *bus = device->target->bus; |
4787 |
struct cam_eb *bus = device->target->bus; |
4726 |
struct cam_devq *devq; |
|
|
4727 |
|
4788 |
|
4728 |
mtx_lock(&bus->eb_mtx); |
4789 |
mtx_lock(&bus->eb_mtx); |
4729 |
if (--device->refcount > 0) { |
4790 |
if (--device->refcount > 0) { |
Lines 4735-4768
xpt_release_device(struct cam_ed *device)
Link Here
|
4735 |
device->target->generation++; |
4796 |
device->target->generation++; |
4736 |
mtx_unlock(&bus->eb_mtx); |
4797 |
mtx_unlock(&bus->eb_mtx); |
4737 |
|
4798 |
|
4738 |
/* Release our slot in the devq */ |
|
|
4739 |
devq = bus->sim->devq; |
4740 |
mtx_lock(&devq->send_mtx); |
4741 |
cam_devq_resize(devq, devq->send_queue.array_size - 1); |
4742 |
mtx_unlock(&devq->send_mtx); |
4743 |
|
4744 |
KASSERT(SLIST_EMPTY(&device->periphs), |
4745 |
("destroying device, but periphs list is not empty")); |
4746 |
KASSERT(device->devq_entry.index == CAM_UNQUEUED_INDEX, |
4747 |
("destroying device while still queued for ccbs")); |
4748 |
|
4749 |
if ((device->flags & CAM_DEV_REL_TIMEOUT_PENDING) != 0) |
4750 |
callout_stop(&device->callout); |
4751 |
|
4752 |
xpt_release_target(device->target); |
4753 |
|
4754 |
cam_ccbq_fini(&device->ccbq); |
4755 |
/* |
4756 |
* Free allocated memory. free(9) does nothing if the |
4757 |
* supplied pointer is NULL, so it is safe to call without |
4758 |
* checking. |
4759 |
*/ |
4760 |
free(device->supported_vpds, M_CAMXPT); |
4761 |
free(device->device_id, M_CAMXPT); |
4762 |
free(device->ext_inq, M_CAMXPT); |
4763 |
free(device->physpath, M_CAMXPT); |
4764 |
free(device->rcap_buf, M_CAMXPT); |
4765 |
free(device->serial_num, M_CAMXPT); |
4766 |
taskqueue_enqueue(xsoftc.xpt_taskq, &device->device_destroy_task); |
4799 |
taskqueue_enqueue(xsoftc.xpt_taskq, &device->device_destroy_task); |
4767 |
} |
4800 |
} |
4768 |
|
4801 |
|