Commit f90dd6d6 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by James Bottomley

[PATCH] scsi_report_device_reset

aic7xxx/79xx wants a variant of scsi_report_bus_reset that operates
only on a single device.  Implement it to get rid of shost->my_devices
traversals in drivers.  (and move both to scsi_error.c)
parent 11e374fe
...@@ -4404,22 +4404,19 @@ ahd_send_async(struct ahd_softc *ahd, char channel, ...@@ -4404,22 +4404,19 @@ ahd_send_async(struct ahd_softc *ahd, char channel,
} }
case AC_SENT_BDR: case AC_SENT_BDR:
{ {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
WARN_ON(lun != CAM_LUN_WILDCARD);
scsi_report_device_reset(ahd->platform_data->host,
channel - 'A', target);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
Scsi_Device *scsi_dev; Scsi_Device *scsi_dev;
/* /*
* Find the SCSI device associated with this * Find the SCSI device associated with this
* request and indicate that a UA is expected. * request and indicate that a UA is expected.
* XXX This should really be handled by the mid-layer.
*/ */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
list_for_each_entry(scsi_dev,
&ahd->platform_data->host->my_devices,
siblings) {
#else
for (scsi_dev = ahd->platform_data->host->host_queue; for (scsi_dev = ahd->platform_data->host->host_queue;
scsi_dev != NULL; scsi_dev = scsi_dev->next) { scsi_dev != NULL; scsi_dev = scsi_dev->next) {
#endif
if (channel - 'A' == scsi_dev->channel if (channel - 'A' == scsi_dev->channel
&& target == scsi_dev->id && target == scsi_dev->id
&& (lun == CAM_LUN_WILDCARD && (lun == CAM_LUN_WILDCARD
......
...@@ -4086,22 +4086,19 @@ ahc_send_async(struct ahc_softc *ahc, char channel, ...@@ -4086,22 +4086,19 @@ ahc_send_async(struct ahc_softc *ahc, char channel,
} }
case AC_SENT_BDR: case AC_SENT_BDR:
{ {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
WARN_ON(lun != CAM_LUN_WILDCARD);
scsi_report_device_reset(ahc->platform_data->host,
channel - 'A', target);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
Scsi_Device *scsi_dev; Scsi_Device *scsi_dev;
/* /*
* Find the SCSI device associated with this * Find the SCSI device associated with this
* request and indicate that a UA is expected. * request and indicate that a UA is expected.
* XXX This should really be handled by the mid-layer.
*/ */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
list_for_each_entry(scsi_dev,
&ahc->platform_data->host->my_devices,
siblings) {
#else
for (scsi_dev = ahc->platform_data->host->host_queue; for (scsi_dev = ahc->platform_data->host->host_queue;
scsi_dev != NULL; scsi_dev = scsi_dev->next) { scsi_dev != NULL; scsi_dev = scsi_dev->next) {
#endif
if (channel - 'A' == scsi_dev->channel if (channel - 'A' == scsi_dev->channel
&& target == scsi_dev->id && target == scsi_dev->id
&& (lun == CAM_LUN_WILDCARD && (lun == CAM_LUN_WILDCARD
......
...@@ -514,6 +514,7 @@ extern Scsi_Device * scsi_get_host_dev(struct Scsi_Host *); ...@@ -514,6 +514,7 @@ extern Scsi_Device * scsi_get_host_dev(struct Scsi_Host *);
extern void scsi_unblock_requests(struct Scsi_Host *); extern void scsi_unblock_requests(struct Scsi_Host *);
extern void scsi_block_requests(struct Scsi_Host *); extern void scsi_block_requests(struct Scsi_Host *);
extern void scsi_report_bus_reset(struct Scsi_Host *, int); extern void scsi_report_bus_reset(struct Scsi_Host *, int);
extern void scsi_report_device_reset(struct Scsi_Host *, int, int);
static inline void scsi_assign_lock(struct Scsi_Host *shost, spinlock_t *lock) static inline void scsi_assign_lock(struct Scsi_Host *shost, spinlock_t *lock)
{ {
......
...@@ -1624,6 +1624,74 @@ void scsi_error_handler(void *data) ...@@ -1624,6 +1624,74 @@ void scsi_error_handler(void *data)
complete_and_exit(shost->eh_notify, 0); complete_and_exit(shost->eh_notify, 0);
} }
/*
* Function: scsi_report_bus_reset()
*
* Purpose: Utility function used by low-level drivers to report that
* they have observed a bus reset on the bus being handled.
*
* Arguments: shost - Host in question
* channel - channel on which reset was observed.
*
* Returns: Nothing
*
* Lock status: No locks are assumed held.
*
* Notes: This only needs to be called if the reset is one which
* originates from an unknown location. Resets originated
* by the mid-level itself don't need to call this, but there
* should be no harm.
*
* The main purpose of this is to make sure that a CHECK_CONDITION
* is properly treated.
*/
void scsi_report_bus_reset(struct Scsi_Host *shost, int channel)
{
struct scsi_device *sdev;
list_for_each_entry(sdev, &shost->my_devices, siblings) {
if (channel == sdev->channel) {
sdev->was_reset = 1;
sdev->expecting_cc_ua = 1;
}
}
}
/*
* Function: scsi_report_device_reset()
*
* Purpose: Utility function used by low-level drivers to report that
* they have observed a device reset on the device being handled.
*
* Arguments: shost - Host in question
* channel - channel on which reset was observed
* target - target on which reset was observed
*
* Returns: Nothing
*
* Lock status: No locks are assumed held.
*
* Notes: This only needs to be called if the reset is one which
* originates from an unknown location. Resets originated
* by the mid-level itself don't need to call this, but there
* should be no harm.
*
* The main purpose of this is to make sure that a CHECK_CONDITION
* is properly treated.
*/
void scsi_report_device_reset(struct Scsi_Host *shost, int channel, int target)
{
struct scsi_device *sdev;
list_for_each_entry(sdev, &shost->my_devices, siblings) {
if (channel == sdev->channel &&
target == sdev->id) {
sdev->was_reset = 1;
sdev->expecting_cc_ua = 1;
}
}
}
static void static void
scsi_reset_provider_done_command(struct scsi_cmnd *scmd) scsi_reset_provider_done_command(struct scsi_cmnd *scmd)
{ {
......
...@@ -1313,39 +1313,6 @@ void scsi_unblock_requests(struct Scsi_Host *shost) ...@@ -1313,39 +1313,6 @@ void scsi_unblock_requests(struct Scsi_Host *shost)
scsi_run_host_queues(shost); scsi_run_host_queues(shost);
} }
/*
* Function: scsi_report_bus_reset()
*
* Purpose: Utility function used by low-level drivers to report that
* they have observed a bus reset on the bus being handled.
*
* Arguments: shost - Host in question
* channel - channel on which reset was observed.
*
* Returns: Nothing
*
* Lock status: No locks are assumed held.
*
* Notes: This only needs to be called if the reset is one which
* originates from an unknown location. Resets originated
* by the mid-level itself don't need to call this, but there
* should be no harm.
*
* The main purpose of this is to make sure that a CHECK_CONDITION
* is properly treated.
*/
void scsi_report_bus_reset(struct Scsi_Host *shost, int channel)
{
struct scsi_device *sdev;
list_for_each_entry(sdev, &shost->my_devices, siblings) {
if (channel == sdev->channel) {
sdev->was_reset = 1;
sdev->expecting_cc_ua = 1;
}
}
}
int __init scsi_init_queue(void) int __init scsi_init_queue(void)
{ {
int i; int i;
......
...@@ -65,6 +65,7 @@ EXPORT_SYMBOL(scsi_get_command); ...@@ -65,6 +65,7 @@ EXPORT_SYMBOL(scsi_get_command);
EXPORT_SYMBOL(scsi_put_command); EXPORT_SYMBOL(scsi_put_command);
EXPORT_SYMBOL(scsi_report_bus_reset); EXPORT_SYMBOL(scsi_report_bus_reset);
EXPORT_SYMBOL(scsi_report_device_reset);
EXPORT_SYMBOL(scsi_block_requests); EXPORT_SYMBOL(scsi_block_requests);
EXPORT_SYMBOL(scsi_unblock_requests); EXPORT_SYMBOL(scsi_unblock_requests);
EXPORT_SYMBOL(scsi_adjust_queue_depth); EXPORT_SYMBOL(scsi_adjust_queue_depth);
......
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