On Thu, 2012-08-02 at 12:27 +0200, Oliver Neukum wrote: > Synchronizing caches may fail. The reason for these > failures need to be translated to the generic layer > so that it nows whether to ignore a failure, retry later > or give up, aborting sleep. > > Signed-off-by: Oliver Neukum <oneukum@xxxxxxx> > --- > drivers/scsi/scsi_error.c | 33 +++++++++++++++++++++++++++++++++ > drivers/scsi/sd.c | 3 +-- > include/scsi/scsi_eh.h | 1 + > 3 files changed, 35 insertions(+), 2 deletions(-) > > diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c > index 4a6381c..13f7060 100644 > --- a/drivers/scsi/scsi_error.c > +++ b/drivers/scsi/scsi_error.c > @@ -2217,3 +2217,36 @@ void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq) > } > } > EXPORT_SYMBOL(scsi_build_sense_buffer); > + > +/** > + * scsi_translate_errors_to_power_management - errors in a form driver core understands > + * @res: Result of scsi command > + * > + * Return value: > + * error code driver core understands > + **/ > +int scsi_translate_errors_to_power_management(int res) > +{ > + int rv = -EIO; No need for a variable, I think > + switch (host_byte(res)) { > + /* ignore errors due to racing a disconnection */ > + case DID_BAD_TARGET: > + case DID_NO_CONNECT: > + return 0; > + /* signal the upper layer it might try again */ > + case DID_BUS_BUSY: > + case DID_IMM_RETRY: > + case DID_REQUEUE: > + case DID_SOFT_ERROR: > + case DID_TIME_OUT: > + case DID_ABORT: > + case DID_RESET: > + case DID_TRANSPORT_DISRUPTED: > + return -EBUSY; > + case DID_OK: > + return 0; > + } > + return rv; this should be inside the switch as default: return -EIO; and no return statment outside of the switch. Don't you still want to handle BUSY and QUEUE_FULL as -EBUSY? Right at the moment they'll fall through the default case and return -EIO. James > +} > +EXPORT_SYMBOL(scsi_translate_errors_to_power_management); > diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c > index c39a97e..8597294 100644 > --- a/drivers/scsi/sd.c > +++ b/drivers/scsi/sd.c > @@ -1288,10 +1288,9 @@ static int sd_sync_cache(struct scsi_disk *sdkp) > */ > if ((scsi_sense_valid(&sshdr) && sshdr.asc == 0x3a)) > return 0; > + return scsi_translate_errors_to_power_management(res); > } > > - if (res) > - return -EIO; > return 0; > } > > diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h > index 06a8790..bdf6d6c 100644 > --- a/include/scsi/scsi_eh.h > +++ b/include/scsi/scsi_eh.h > @@ -59,6 +59,7 @@ extern int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len, > u64 * info_out); > > extern void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq); > +extern int scsi_translate_errors_to_power_management(int res); > > /* > * Reset request from external source -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html