Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
9b46c836
Commit
9b46c836
authored
Sep 30, 2002
by
Mike Anderson
Committed by
James Bottomley
Sep 30, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Error handler general clean up
parent
8885e375
Changes
5
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
1236 additions
and
1548 deletions
+1236
-1548
drivers/scsi/hosts.c
drivers/scsi/hosts.c
+42
-0
drivers/scsi/hosts.h
drivers/scsi/hosts.h
+7
-0
drivers/scsi/scsi.c
drivers/scsi/scsi.c
+6
-53
drivers/scsi/scsi.h
drivers/scsi/scsi.h
+23
-1
drivers/scsi/scsi_error.c
drivers/scsi/scsi_error.c
+1158
-1494
No files found.
drivers/scsi/hosts.c
View file @
9b46c836
...
...
@@ -259,6 +259,48 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j)
return
retval
;
}
void
scsi_host_busy_inc
(
struct
Scsi_Host
*
shost
,
Scsi_Device
*
sdev
)
{
unsigned
long
flags
;
spin_lock_irqsave
(
shost
->
host_lock
,
flags
);
shost
->
host_busy
++
;
sdev
->
device_busy
++
;
spin_unlock_irqrestore
(
shost
->
host_lock
,
flags
);
}
void
scsi_host_busy_dec_and_test
(
struct
Scsi_Host
*
shost
,
Scsi_Device
*
sdev
)
{
unsigned
long
flags
;
spin_lock_irqsave
(
shost
->
host_lock
,
flags
);
shost
->
host_busy
--
;
sdev
->
device_busy
--
;
if
(
shost
->
in_recovery
&&
(
shost
->
host_busy
==
shost
->
host_failed
))
{
up
(
shost
->
eh_wait
);
SCSI_LOG_ERROR_RECOVERY
(
5
,
printk
(
"Waking error handler"
"thread (%d)
\n
"
,
atomic_read
(
&
shost
->
eh_wait
->
count
)));
}
spin_unlock_irqrestore
(
shost
->
host_lock
,
flags
);
}
void
scsi_host_failed_inc_and_test
(
struct
Scsi_Host
*
shost
)
{
unsigned
long
flags
;
spin_lock_irqsave
(
shost
->
host_lock
,
flags
);
shost
->
in_recovery
=
1
;
shost
->
host_failed
++
;
if
(
shost
->
host_busy
==
shost
->
host_failed
)
{
up
(
shost
->
eh_wait
);
SCSI_LOG_ERROR_RECOVERY
(
5
,
printk
(
"Waking error handler"
"thread (%d)
\n
"
,
atomic_read
(
&
shost
->
eh_wait
->
count
)));
}
spin_unlock_irqrestore
(
shost
->
host_lock
,
flags
);
}
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
...
...
drivers/scsi/hosts.h
View file @
9b46c836
...
...
@@ -543,6 +543,13 @@ extern int scsi_unregister_device(struct Scsi_Device_Template *);
extern
int
scsi_register_host
(
Scsi_Host_Template
*
);
extern
int
scsi_unregister_host
(
Scsi_Host_Template
*
);
/*
* host_busy inc/dec/test functions
*/
extern
void
scsi_host_busy_inc
(
struct
Scsi_Host
*
,
Scsi_Device
*
);
extern
void
scsi_host_busy_dec_and_test
(
struct
Scsi_Host
*
,
Scsi_Device
*
);
extern
void
scsi_host_failed_inc_and_test
(
struct
Scsi_Host
*
);
/*
* This is an ugly hack. If we expect to be able to load devices at run time,
...
...
drivers/scsi/scsi.c
View file @
9b46c836
...
...
@@ -566,22 +566,6 @@ inline void __scsi_release_command(Scsi_Cmnd * SCpnt)
SCpnt
->
target
,
atomic_read
(
&
SCpnt
->
host
->
host_active
),
SCpnt
->
host
->
host_failed
));
if
(
SCpnt
->
host
->
host_failed
!=
0
)
{
SCSI_LOG_ERROR_RECOVERY
(
5
,
printk
(
"Error handler thread %d %d
\n
"
,
SCpnt
->
host
->
in_recovery
,
SCpnt
->
host
->
eh_active
));
}
/*
* If the host is having troubles, then look to see if this was the last
* command that might have failed. If so, wake up the error handler.
*/
if
(
SCpnt
->
host
->
in_recovery
&&
!
SCpnt
->
host
->
eh_active
&&
SCpnt
->
host
->
host_busy
==
SCpnt
->
host
->
host_failed
)
{
SCSI_LOG_ERROR_RECOVERY
(
5
,
printk
(
"Waking error handler thread (%d)
\n
"
,
atomic_read
(
&
SCpnt
->
host
->
eh_wait
->
count
)));
up
(
SCpnt
->
host
->
eh_wait
);
}
spin_unlock_irqrestore
(
&
device_request_lock
,
flags
);
...
...
@@ -1217,28 +1201,11 @@ void scsi_done(Scsi_Cmnd * SCpnt)
* etc, etc.
*/
if
(
!
tstatus
)
{
SCpnt
->
done_late
=
1
;
return
;
}
/* Set the serial numbers back to zero */
SCpnt
->
serial_number
=
0
;
/*
* First, see whether this command already timed out. If so, we ignore
* the response. We treat it as if the command never finished.
*
* Since serial_number is now 0, the error handler cound detect this
* situation and avoid to call the low level driver abort routine.
* (DB)
*
* FIXME(eric) - I believe that this test is now redundant, due to
* the test of the return status of del_timer().
*/
if
(
SCpnt
->
state
==
SCSI_STATE_TIMEOUT
)
{
SCSI_LOG_MLCOMPLETE
(
1
,
printk
(
"Ignoring completion of %p due to timeout status"
,
SCpnt
));
return
;
}
SCpnt
->
serial_number_at_timeout
=
0
;
SCpnt
->
state
=
SCSI_STATE_BHQUEUE
;
SCpnt
->
owner
=
SCSI_OWNER_BH_HANDLER
;
...
...
@@ -1349,21 +1316,11 @@ static void scsi_softirq(struct softirq_action *h)
SCSI_LOG_MLCOMPLETE
(
3
,
print_sense
(
"bh"
,
SCpnt
));
}
if
(
SCpnt
->
host
->
eh_wait
!=
NULL
)
{
SCpnt
->
host
->
host_failed
++
;
scsi_eh_eflags_set
(
SCpnt
,
SCSI_EH_CMD_FAILED
|
SCSI_EH_CMD_ERR
)
;
SCpnt
->
owner
=
SCSI_OWNER_ERROR_HANDLER
;
SCpnt
->
state
=
SCSI_STATE_FAILED
;
SCpnt
->
host
->
in_recovery
=
1
;
/*
* If the host is having troubles, then
* look to see if this was the last
* command that might have failed. If
* so, wake up the error handler.
*/
if
(
SCpnt
->
host
->
host_busy
==
SCpnt
->
host
->
host_failed
)
{
SCSI_LOG_ERROR_RECOVERY
(
5
,
printk
(
"Waking error handler thread (%d)
\n
"
,
atomic_read
(
&
SCpnt
->
host
->
eh_wait
->
count
)));
up
(
SCpnt
->
host
->
eh_wait
);
}
scsi_host_failed_inc_and_test
(
SCpnt
->
host
);
}
else
{
/*
* We only get here if the error
...
...
@@ -1418,7 +1375,6 @@ void scsi_finish_command(Scsi_Cmnd * SCpnt)
struct
Scsi_Host
*
host
;
Scsi_Device
*
device
;
Scsi_Request
*
SRpnt
;
unsigned
long
flags
;
host
=
SCpnt
->
host
;
device
=
SCpnt
->
device
;
...
...
@@ -1432,10 +1388,7 @@ void scsi_finish_command(Scsi_Cmnd * SCpnt)
* one execution context, but the device and host structures are
* shared.
*/
spin_lock_irqsave
(
host
->
host_lock
,
flags
);
host
->
host_busy
--
;
/* Indicate that we are free */
device
->
device_busy
--
;
/* Decrement device usage counter. */
spin_unlock_irqrestore
(
host
->
host_lock
,
flags
);
scsi_host_busy_dec_and_test
(
host
,
device
);
/*
* Clear the flags which say that the device/host is no longer
...
...
@@ -1450,7 +1403,7 @@ void scsi_finish_command(Scsi_Cmnd * SCpnt)
* If we have valid sense information, then some kind of recovery
* must have taken place. Make a note of this.
*/
if
(
scsi_sense_valid
(
SCpnt
))
{
if
(
SCSI_SENSE_VALID
(
SCpnt
))
{
SCpnt
->
result
|=
(
DRIVER_SENSE
<<
24
);
}
SCSI_LOG_MLCOMPLETE
(
3
,
printk
(
"Notifying upper driver of completion for device %d %x
\n
"
,
...
...
drivers/scsi/scsi.h
View file @
9b46c836
...
...
@@ -428,7 +428,6 @@ extern void scsi_add_timer(Scsi_Cmnd * SCset, int timeout,
void
(
*
complete
)
(
Scsi_Cmnd
*
));
extern
int
scsi_delete_timer
(
Scsi_Cmnd
*
SCset
);
extern
void
scsi_error_handler
(
void
*
host
);
extern
int
scsi_sense_valid
(
Scsi_Cmnd
*
);
extern
int
scsi_decide_disposition
(
Scsi_Cmnd
*
SCpnt
);
extern
int
scsi_block_when_processing_errors
(
Scsi_Device
*
);
extern
void
scsi_sleep
(
int
);
...
...
@@ -701,6 +700,7 @@ struct scsi_cmnd {
struct
scsi_cmnd
*
reset_chain
;
int
eh_state
;
/* Used for state tracking in error handlr */
int
eh_eflags
;
/* Used by error handlr */
void
(
*
done
)
(
struct
scsi_cmnd
*
);
/* Mid-level done function */
/*
A SCSI Command is assigned a nonzero serial_number when internal_cmnd
...
...
@@ -940,4 +940,26 @@ static inline Scsi_Cmnd *scsi_find_tag(Scsi_Device *SDpnt, int tag) {
return
(
Scsi_Cmnd
*
)
req
->
special
;
}
#define scsi_eh_eflags_chk(scp, flags) (scp->eh_eflags & flags)
#define scsi_eh_eflags_set(scp, flags) do { \
scp->eh_eflags |= flags; \
} while(0)
#define scsi_eh_eflags_clr(scp, flags) do { \
scp->eh_eflags &= ~flags; \
} while(0)
#define scsi_eh_eflags_clr_all(scp) (scp->eh_eflags = 0)
/*
* Scsi Error Handler Flags
*/
#define SCSI_EH_CMD_ERR 0x0001
/* Orig cmd error'd */
#define SCSI_EH_CMD_FAILED 0x0002
/* Orig cmd error type failed */
#define SCSI_EH_CMD_TIMEOUT 0x0004
/* Orig cmd error type timeout */
#define SCSI_EH_REC_TIMEOUT 0x0008
/* Recovery cmd timeout */
#define SCSI_SENSE_VALID(scmd) ((scmd->sense_buffer[0] & 0x70) == 0x70)
#endif
drivers/scsi/scsi_error.c
View file @
9b46c836
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment