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

Collapse All | Expand All

(-)w/sys/cam/cam_xpt.c (-30 / +63 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 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

Return to bug 204298