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, ...@@ -1082,6 +1082,28 @@ struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *shost,
} }
EXPORT_SYMBOL(__scsi_iterate_devices); 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) * scsi_device_lookup - find a device given the host (UNLOCKED)
* @shost: SCSI host pointer * @shost: SCSI host pointer
......
...@@ -1782,31 +1782,29 @@ scsi_device_resume(struct scsi_device *sdev) ...@@ -1782,31 +1782,29 @@ scsi_device_resume(struct scsi_device *sdev)
} }
EXPORT_SYMBOL(scsi_device_resume); EXPORT_SYMBOL(scsi_device_resume);
static int static void
device_quiesce_fn(struct device *dev, void *data) device_quiesce_fn(struct scsi_device *sdev, void *data)
{ {
scsi_device_quiesce(to_scsi_device(dev)); scsi_device_quiesce(sdev);
return 0;
} }
void void
scsi_target_quiesce(struct scsi_target *starget) 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); EXPORT_SYMBOL(scsi_target_quiesce);
static int static void
device_resume_fn(struct device *dev, void *data) device_resume_fn(struct scsi_device *sdev, void *data)
{ {
scsi_device_resume(to_scsi_device(dev)); scsi_device_resume(sdev);
return 0;
} }
void void
scsi_target_resume(struct scsi_target *starget) 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); EXPORT_SYMBOL(scsi_target_resume);
......
...@@ -808,10 +808,9 @@ EXPORT_SYMBOL(fc_release_transport); ...@@ -808,10 +808,9 @@ EXPORT_SYMBOL(fc_release_transport);
* @dev: scsi device * @dev: scsi device
* @data: unused * @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)); scsi_internal_device_block(sdev);
return 0;
} }
/** /**
...@@ -819,10 +818,9 @@ static int fc_device_block(struct device *dev, void *data) ...@@ -819,10 +818,9 @@ static int fc_device_block(struct device *dev, void *data)
* @dev: scsi device * @dev: scsi device
* @data: unused * @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)); scsi_internal_device_unblock(sdev);
return 0;
} }
/** /**
...@@ -842,7 +840,7 @@ static void fc_timeout_blocked_tgt(void *data) ...@@ -842,7 +840,7 @@ static void fc_timeout_blocked_tgt(void *data)
* unblock this device, then IO errors will probably * unblock this device, then IO errors will probably
* result if the host still isn't ready. * 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) ...@@ -870,7 +868,7 @@ fc_target_block(struct scsi_target *starget)
if (timeout < 0 || timeout > SCSI_DEVICE_BLOCK_MAX_TIMEOUT) if (timeout < 0 || timeout > SCSI_DEVICE_BLOCK_MAX_TIMEOUT)
return -EINVAL; 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. */ /* The scsi lld blocks this target for the timeout period only. */
schedule_delayed_work(work, timeout * HZ); schedule_delayed_work(work, timeout * HZ);
...@@ -901,7 +899,7 @@ fc_target_unblock(struct scsi_target *starget) ...@@ -901,7 +899,7 @@ fc_target_unblock(struct scsi_target *starget)
if (cancel_delayed_work(&fc_starget_dev_loss_work(starget))) if (cancel_delayed_work(&fc_starget_dev_loss_work(starget)))
flush_scheduled_work(); 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); EXPORT_SYMBOL(fc_target_unblock);
......
...@@ -172,6 +172,8 @@ extern struct scsi_device *scsi_device_lookup(struct Scsi_Host *, ...@@ -172,6 +172,8 @@ extern struct scsi_device *scsi_device_lookup(struct Scsi_Host *,
uint, uint, uint); uint, uint, uint);
extern struct scsi_device *__scsi_device_lookup(struct Scsi_Host *, extern struct scsi_device *__scsi_device_lookup(struct Scsi_Host *,
uint, uint, uint); 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 */ /* only exposed to implement shost_for_each_device */
extern struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *, 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