--- linux/drivers/scsi/scsi.h Thu Jan 13 22:06:53 2000 +++ linux/drivers/scsi/scsi.h_rs Sat Feb 5 17:53:56 2000 @@ -329,6 +329,11 @@ #define CONTIGUOUS_BUFFERS(X,Y) ((X->b_data+X->b_size) == Y->b_data) #endif +/* Defines to let high level drivers reset a device/bus/host */ +#define SCSI_TRY_RESET_DEVICE 1 +#define SCSI_TRY_RESET_BUS 2 +#define SCSI_TRY_RESET_HOST 3 + /* * This is the crap from the old error handling code. We have it in a special @@ -732,6 +737,11 @@ remove_wait_queue(QUEUE, &wait);\ current->state = TASK_RUNNING; \ }; } +/* old style reset request from external source (private to sg.c and + * scsi_error.c, supplied by scsi_obsolete.c) + * */ +extern int scsi_old_reset(Scsi_Cmnd *, unsigned int); +extern int scsi_reset_provider(Scsi_Device *, int); #endif --- linux/drivers/scsi/scsi_error.c Mon Aug 9 15:04:40 1999 +++ linux/drivers/scsi/scsi_error.c_rs Thu May 11 20:56:20 2000 @@ -2044,6 +2044,65 @@ } /* + * Function: scsi_reset_provider + * + * Purpose: Send requested reset to a bus or device at any phase. + * + * Arguments: device - device to send reset to + * + * Returns: SUCCESS/FAILURE. + * + * Notes: This is used by the SCSI Generic driver to provide + * Bus/Device reset capability. + * + * Contributed by : James Bottomley + */ +int +scsi_reset_provider(Scsi_Device *dev, int flag) +{ + int rtn; + /* get a dummy command to issue the reset to */ + Scsi_Cmnd *SCpnt = scsi_allocate_device(NULL, dev, 1); + if (! SCpnt) + return FAILED; + switch(flag) { + case SCSI_TRY_RESET_DEVICE: + rtn = scsi_try_bus_device_reset(SCpnt, 0); + if(rtn == SUCCESS) + break; + /* fall through */ + case SCSI_TRY_RESET_BUS: + rtn = scsi_try_bus_reset(SCpnt); + if(rtn == SUCCESS) + break; + /* fall through */ + case SCSI_TRY_RESET_HOST: + rtn = scsi_try_host_reset(SCpnt); + break; + default: + rtn = FAILED; + goto error_out; + } + if(rtn == FAILED) { + /* if we get here, the new code all failed, so try the old + * reset code */ + unsigned int old_flags = SCSI_RESET_SYNCHRONOUS; + switch(flag) { + case SCSI_TRY_RESET_BUS: + old_flags |= SCSI_RESET_SUGGEST_BUS_RESET; + break; + case SCSI_TRY_RESET_HOST: + old_flags |= SCSI_RESET_SUGGEST_HOST_RESET; + break; + } + rtn = (scsi_old_reset(SCpnt, old_flags) == 0) ? SUCCESS : FAILED; + } + error_out: + scsi_release_command(SCpnt); + return rtn; +} + +/* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically * adjust the settings for this buffer only. This must remain at the end --- linux/drivers/scsi/scsi_obsolete.c Sun Jan 17 21:29:54 1999 +++ linux/drivers/scsi/scsi_obsolete.c_rs Thu Feb 3 21:25:56 2000 @@ -1120,6 +1120,16 @@ return rtn; } +/* This function exports SCSI Bus, Device or Host reset capability + * and is for use with the SCSI generic driver. + */ +int scsi_old_reset(Scsi_Cmnd *SCpnt, unsigned int flag) +{ + int retval = scsi_reset(SCpnt, flag); + return retval; +} + + /* * Overrides for Emacs so that we follow Linus's tabbing style. --- linux/drivers/scsi/scsi_syms.c Wed Jun 9 19:59:34 1999 +++ linux/drivers/scsi/scsi_syms.c_rs Thu Feb 3 21:25:56 2000 @@ -80,5 +80,10 @@ EXPORT_SYMBOL(scsi_devicelist); EXPORT_SYMBOL(scsi_device_types); +/* + * This symbol is for the sg device only + */ +EXPORT_SYMBOL(scsi_reset_provider); + #endif /* CONFIG_MODULES */