Commit 65c333c9 authored by James Bottomley's avatar James Bottomley

SCSI: add starget_for_each_device

From: 	James.Smart@Emulex.Com

This patch deprecates the use of device_for_each_child() with stargets.
The reasoning behind this is due to issues regarding:
      Semaphores that device_for_each_child() takes
      Implicit assumptions that each child is an sdev device.

The patch adds a new helper function, starget_for_each_device(), and
replaces all previous uses of device_for_each_child().
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 09cb5719
......@@ -1082,6 +1082,28 @@ struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *shost,
}
EXPORT_SYMBOL(__scsi_iterate_devices);
/**
* starget_for_each_device - helper to walk all devices of a target
* @starget: target whose devices we want to iterate over.
*
* This traverses over each devices of @shost. The devices have
* a reference that must be released by scsi_host_put when breaking
* out of the loop.
*/
void starget_for_each_device(struct scsi_target *starget, void * data,
void (*fn)(struct scsi_device *, void *))
{
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
struct scsi_device *sdev;
shost_for_each_device(sdev, shost) {
if ((sdev->channel == starget->channel) &&
(sdev->id == starget->id))
fn(sdev, data);
}
}
EXPORT_SYMBOL(starget_for_each_device);
/**
* scsi_device_lookup - find a device given the host (UNLOCKED)
* @shost: SCSI host pointer
......
......@@ -1782,31 +1782,29 @@ scsi_device_resume(struct scsi_device *sdev)
}
EXPORT_SYMBOL(scsi_device_resume);
static int
device_quiesce_fn(struct device *dev, void *data)
static void
device_quiesce_fn(struct scsi_device *sdev, void *data)
{
scsi_device_quiesce(to_scsi_device(dev));
return 0;
scsi_device_quiesce(sdev);
}
void
scsi_target_quiesce(struct scsi_target *starget)
{
device_for_each_child(&starget->dev, NULL, device_quiesce_fn);
starget_for_each_device(starget, NULL, device_quiesce_fn);
}
EXPORT_SYMBOL(scsi_target_quiesce);
static int
device_resume_fn(struct device *dev, void *data)
static void
device_resume_fn(struct scsi_device *sdev, void *data)
{
scsi_device_resume(to_scsi_device(dev));
return 0;
scsi_device_resume(sdev);
}
void
scsi_target_resume(struct scsi_target *starget)
{
device_for_each_child(&starget->dev, NULL, device_resume_fn);
starget_for_each_device(starget, NULL, device_resume_fn);
}
EXPORT_SYMBOL(scsi_target_resume);
......
......@@ -808,10 +808,9 @@ EXPORT_SYMBOL(fc_release_transport);
* @dev: scsi device
* @data: unused
**/
static int fc_device_block(struct device *dev, void *data)
static void fc_device_block(struct scsi_device *sdev, void *data)
{
scsi_internal_device_block(to_scsi_device(dev));
return 0;
scsi_internal_device_block(sdev);
}
/**
......@@ -819,10 +818,9 @@ static int fc_device_block(struct device *dev, void *data)
* @dev: scsi device
* @data: unused
**/
static int fc_device_unblock(struct device *dev, void *data)
static void fc_device_unblock(struct scsi_device *sdev, void *data)
{
scsi_internal_device_unblock(to_scsi_device(dev));
return 0;
scsi_internal_device_unblock(sdev);
}
/**
......@@ -842,7 +840,7 @@ static void fc_timeout_blocked_tgt(void *data)
* unblock this device, then IO errors will probably
* result if the host still isn't ready.
*/
device_for_each_child(&starget->dev, NULL, fc_device_unblock);
starget_for_each_device(starget, NULL, fc_device_unblock);
}
/**
......@@ -870,7 +868,7 @@ fc_target_block(struct scsi_target *starget)
if (timeout < 0 || timeout > SCSI_DEVICE_BLOCK_MAX_TIMEOUT)
return -EINVAL;
device_for_each_child(&starget->dev, NULL, fc_device_block);
starget_for_each_device(starget, NULL, fc_device_block);
/* The scsi lld blocks this target for the timeout period only. */
schedule_delayed_work(work, timeout * HZ);
......@@ -901,7 +899,7 @@ fc_target_unblock(struct scsi_target *starget)
if (cancel_delayed_work(&fc_starget_dev_loss_work(starget)))
flush_scheduled_work();
device_for_each_child(&starget->dev, NULL, fc_device_unblock);
starget_for_each_device(starget, NULL, fc_device_unblock);
}
EXPORT_SYMBOL(fc_target_unblock);
......
......@@ -172,6 +172,8 @@ extern struct scsi_device *scsi_device_lookup(struct Scsi_Host *,
uint, uint, uint);
extern struct scsi_device *__scsi_device_lookup(struct Scsi_Host *,
uint, uint, uint);
extern void starget_for_each_device(struct scsi_target *, void *,
void (*fn)(struct scsi_device *, void *));
/* only exposed to implement shost_for_each_device */
extern struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment