View | Details | Raw Unified | Return to bug 204298 | Differences between
and this patch

Collapse All | Expand All

(-)cam_xpt.c (-16 / +25 lines)
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);

Return to bug 204298