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 4308-4315
xpt_release_devq_timeout(void *arg)
Link Here
|
4308 |
CAM_DEBUG_DEV(dev, CAM_DEBUG_TRACE, ("xpt_release_devq_timeout\n")); |
4325 |
CAM_DEBUG_DEV(dev, CAM_DEBUG_TRACE, ("xpt_release_devq_timeout\n")); |
4309 |
devq = dev->sim->devq; |
4326 |
devq = dev->sim->devq; |
4310 |
mtx_assert(&devq->send_mtx, MA_OWNED); |
4327 |
mtx_assert(&devq->send_mtx, MA_OWNED); |
|
|
4328 |
dev->flags &= ~CAM_DEV_REL_TIMEOUT_PENDING; |
4311 |
if (xpt_release_devq_device(dev, /*count*/1, /*run_queue*/TRUE)) |
4329 |
if (xpt_release_devq_device(dev, /*count*/1, /*run_queue*/TRUE)) |
4312 |
xpt_run_devq(devq); |
4330 |
xpt_run_devq(devq); |
|
|
4331 |
xpt_release_device(dev); |
4313 |
} |
4332 |
} |
4314 |
|
4333 |
|
4315 |
void |
4334 |
void |
Lines 4345-4364
xpt_release_devq_device(struct cam_ed *dev, u_int
Link Here
|
4345 |
} |
4364 |
} |
4346 |
dev->ccbq.queue.qfrozen_cnt -= count; |
4365 |
dev->ccbq.queue.qfrozen_cnt -= count; |
4347 |
if (dev->ccbq.queue.qfrozen_cnt == 0) { |
4366 |
if (dev->ccbq.queue.qfrozen_cnt == 0) { |
|
|
4367 |
KASSERT((dev->flags & CAM_DEV_REL_ON_COMPLETE) == 0, |
4368 |
("released the queue while still waiting for completion")); |
4369 |
KASSERT((dev->flags & CAM_DEV_REL_TIMEOUT_PENDING) == 0, |
4370 |
("released the queue while still having timeout pending")); |
4348 |
/* |
4371 |
/* |
4349 |
* No longer need to wait for a successful |
|
|
4350 |
* command completion. |
4351 |
*/ |
4352 |
dev->flags &= ~CAM_DEV_REL_ON_COMPLETE; |
4353 |
/* |
4354 |
* Remove any timeouts that might be scheduled |
4355 |
* to release this queue. |
4356 |
*/ |
4357 |
if ((dev->flags & CAM_DEV_REL_TIMEOUT_PENDING) != 0) { |
4358 |
callout_stop(&dev->callout); |
4359 |
dev->flags &= ~CAM_DEV_REL_TIMEOUT_PENDING; |
4360 |
} |
4361 |
/* |
4362 |
* Now that we are unfrozen schedule the |
4372 |
* Now that we are unfrozen schedule the |
4363 |
* device so any pending transactions are |
4373 |
* device so any pending transactions are |
4364 |
* run. |
4374 |
* run. |
Lines 4745-4754
xpt_release_device(struct cam_ed *device)
Link Here
|
4745 |
("destroying device, but periphs list is not empty")); |
4755 |
("destroying device, but periphs list is not empty")); |
4746 |
KASSERT(device->devq_entry.index == CAM_UNQUEUED_INDEX, |
4756 |
KASSERT(device->devq_entry.index == CAM_UNQUEUED_INDEX, |
4747 |
("destroying device while still queued for ccbs")); |
4757 |
("destroying device while still queued for ccbs")); |
|
|
4758 |
KASSERT((device->flags & CAM_DEV_REL_TIMEOUT_PENDING) == 0, |
4759 |
("destroying device while still having timeout pending")); |
4748 |
|
4760 |
|
4749 |
if ((device->flags & CAM_DEV_REL_TIMEOUT_PENDING) != 0) |
|
|
4750 |
callout_stop(&device->callout); |
4751 |
|
4752 |
xpt_release_target(device->target); |
4761 |
xpt_release_target(device->target); |
4753 |
|
4762 |
|
4754 |
cam_ccbq_fini(&device->ccbq); |
4763 |
cam_ccbq_fini(&device->ccbq); |