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
3f7401c6
Commit
3f7401c6
authored
Jan 11, 2003
by
James Bottomley
Browse files
Options
Browse Files
Download
Plain Diff
Merge mulgrave.(none):/home/jejb/BK/scsi-misc-2.5
into mulgrave.(none):/home/jejb/BK/scsi-misc-new-2.5
parents
efa0596f
dabae96e
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
70 additions
and
55 deletions
+70
-55
drivers/block/scsi_ioctl.c
drivers/block/scsi_ioctl.c
+29
-13
drivers/scsi/hosts.c
drivers/scsi/hosts.c
+6
-5
drivers/scsi/hosts.h
drivers/scsi/hosts.h
+2
-1
drivers/scsi/scsi_error.c
drivers/scsi/scsi_error.c
+13
-32
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_lib.c
+18
-4
drivers/scsi/scsi_sysfs.c
drivers/scsi/scsi_sysfs.c
+2
-0
No files found.
drivers/block/scsi_ioctl.c
View file @
3f7401c6
...
...
@@ -40,6 +40,11 @@ const unsigned char scsi_command_size[8] =
#define BLK_DEFAULT_TIMEOUT (60 * HZ)
/* defined in ../scsi/scsi.h ... should it be included? */
#ifndef SCSI_SENSE_BUFFERSIZE
#define SCSI_SENSE_BUFFERSIZE 64
#endif
int
blk_do_rq
(
request_queue_t
*
q
,
struct
block_device
*
bdev
,
struct
request
*
rq
)
{
DECLARE_COMPLETION
(
wait
);
...
...
@@ -126,11 +131,11 @@ static int sg_io(request_queue_t *q, struct block_device *bdev,
struct
sg_io_hdr
*
uptr
)
{
unsigned
long
uaddr
,
start_time
;
int
err
,
reading
,
writing
,
nr_sectors
;
int
reading
,
writing
,
nr_sectors
;
struct
sg_io_hdr
hdr
;
struct
request
*
rq
;
struct
bio
*
bio
;
char
sense
[
24
];
char
sense
[
SCSI_SENSE_BUFFERSIZE
];
void
*
buffer
;
if
(
!
access_ok
(
VERIFY_WRITE
,
uptr
,
sizeof
(
*
uptr
)))
...
...
@@ -265,26 +270,36 @@ static int sg_io(request_queue_t *q, struct block_device *bdev,
start_time
=
jiffies
;
/*
*
return -EIO if we didn't transfer all data, caller can look at
*
residual count to find out how much did succeed
/*
ignore return value. All information is passed back to caller
*
(if he doesn't check that is his problem).
*
N.B. a non-zero SCSI status is _not_ necessarily an error.
*/
err
=
blk_do_rq
(
q
,
bdev
,
rq
);
if
(
rq
->
data_len
>
0
)
err
=
-
EIO
;
blk_do_rq
(
q
,
bdev
,
rq
);
if
(
bio
)
{
bio_unmap_user
(
bio
,
reading
);
bio_put
(
bio
);
}
hdr
.
status
=
rq
->
errors
;
/* write to all output members */
hdr
.
status
=
rq
->
errors
;
hdr
.
masked_status
=
(
hdr
.
status
>>
1
)
&
0x1f
;
hdr
.
msg_status
=
0
;
hdr
.
host_status
=
0
;
hdr
.
driver_status
=
0
;
hdr
.
info
=
0
;
if
(
hdr
.
masked_status
||
hdr
.
host_status
||
hdr
.
driver_status
)
hdr
.
info
|=
SG_INFO_CHECK
;
hdr
.
resid
=
rq
->
data_len
;
hdr
.
duration
=
(
jiffies
-
start_time
)
*
(
1000
/
HZ
);
hdr
.
sb_len_wr
=
0
;
if
(
rq
->
sense_len
&&
hdr
.
sbp
)
{
if
(
!
copy_to_user
(
hdr
.
sbp
,
rq
->
sense
,
rq
->
sense_len
))
hdr
.
sb_len_wr
=
rq
->
sense_len
;
int
len
=
(
hdr
.
mx_sb_len
<
rq
->
sense_len
)
?
hdr
.
mx_sb_len
:
rq
->
sense_len
;
if
(
!
copy_to_user
(
hdr
.
sbp
,
rq
->
sense
,
len
))
hdr
.
sb_len_wr
=
len
;
}
blk_put_request
(
rq
);
...
...
@@ -297,8 +312,9 @@ static int sg_io(request_queue_t *q, struct block_device *bdev,
kfree
(
buffer
);
}
return
err
;
/* may not have succeeded, but output values written to control
* structure (struct sg_io_hdr). */
return
0
;
}
#define FORMAT_UNIT_TIMEOUT (2 * 60 * 60 * HZ)
...
...
drivers/scsi/hosts.c
View file @
3f7401c6
...
...
@@ -36,6 +36,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/completion.h>
#define __KERNEL_SYSCALLS__
...
...
@@ -335,10 +336,10 @@ void scsi_unregister(struct Scsi_Host *shost)
* Next, kill the kernel error recovery thread for this host.
*/
if
(
shost
->
ehandler
)
{
DECLARE_
MUTEX_LOCKED
(
sem
);
DECLARE_
COMPLETION
(
sem
);
shost
->
eh_notify
=
&
sem
;
send_sig
(
SIGHUP
,
shost
->
ehandler
,
1
);
dow
n
(
&
sem
);
up
(
shost
->
eh_wait
);
wait_for_completio
n
(
&
sem
);
shost
->
eh_notify
=
NULL
;
}
...
...
@@ -368,7 +369,7 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template *shost_tp, int xtr_bytes)
{
struct
Scsi_Host
*
shost
,
*
shost_scr
;
int
gfp_mask
;
DECLARE_
MUTEX_LOCKED
(
sem
);
DECLARE_
COMPLETION
(
sem
);
/* Check to see if this host has any error handling facilities */
if
(
shost_tp
->
eh_strategy_handler
==
NULL
&&
...
...
@@ -464,7 +465,7 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template *shost_tp, int xtr_bytes)
* Now wait for the kernel error thread to initialize itself
* as it might be needed when we scan the bus.
*/
dow
n
(
&
sem
);
wait_for_completio
n
(
&
sem
);
shost
->
eh_notify
=
NULL
;
shost
->
hostt
->
present
++
;
...
...
drivers/scsi/hosts.h
View file @
3f7401c6
...
...
@@ -381,11 +381,12 @@ struct Scsi_Host
struct
task_struct
*
ehandler
;
/* Error recovery thread. */
struct
semaphore
*
eh_wait
;
/* The error recovery thread waits on
this. */
struct
semaphore
*
eh_notify
;
/* wait for eh to begin
*/
struct
completion
*
eh_notify
;
/* wait for eh to begin or end
*/
struct
semaphore
*
eh_action
;
/* Wait for specific actions on the
host. */
unsigned
int
eh_active
:
1
;
/* Indicates the eh thread is awake and active if
this is true. */
unsigned
int
eh_kill
:
1
;
/* set when killing the eh thread */
wait_queue_head_t
host_wait
;
Scsi_Host_Template
*
hostt
;
atomic_t
host_active
;
/* commands checked out */
...
...
drivers/scsi/scsi_error.c
View file @
3f7401c6
...
...
@@ -27,6 +27,7 @@
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/smp_lock.h>
#include <linux/completion.h>
#define __KERNEL_SYSCALLS__
...
...
@@ -41,20 +42,6 @@
#include <scsi/scsi_ioctl.h>
/* grr */
/*
* We must always allow SHUTDOWN_SIGS. Even if we are not a module,
* the host drivers that we are using may be loaded as modules, and
* when we unload these, we need to ensure that the error handler thread
* can be shut down.
*
* Note - when we unload a module, we send a SIGHUP. We mustn't
* enable SIGTERM, as this is how the init shuts things down when you
* go to single-user mode. For that matter, init also sends SIGKILL,
* so we mustn't enable that one either. We use SIGHUP instead. Other
* options would be SIGPWR, I suppose.
*/
#define SHUTDOWN_SIGS (sigmask(SIGHUP))
#ifdef DEBUG
#define SENSE_TIMEOUT SCSI_TIMEOUT
#else
...
...
@@ -1589,12 +1576,10 @@ void scsi_error_handler(void *data)
int
rtn
;
DECLARE_MUTEX_LOCKED
(
sem
);
/*
* We only listen to signals if the HA was loaded as a module.
* If the HA was compiled into the kernel, then we don't listen
* to any signals.
*/
siginitsetinv
(
&
current
->
blocked
,
SHUTDOWN_SIGS
);
spin_lock_irq
(
&
current
->
sig
->
siglock
);
sigfillset
(
&
current
->
blocked
);
recalc_sigpending
();
spin_unlock_irq
(
&
current
->
sig
->
siglock
);
lock_kernel
();
...
...
@@ -1618,9 +1603,9 @@ void scsi_error_handler(void *data)
/*
* Wake up the thread that created us.
*/
SCSI_LOG_ERROR_RECOVERY
(
3
,
printk
(
"Wake up parent
\n
"
));
SCSI_LOG_ERROR_RECOVERY
(
3
,
printk
(
"Wake up parent
of scsi_eh_%d
\n
"
,
shost
->
host_no
));
up
(
shost
->
eh_notify
);
complete
(
shost
->
eh_notify
);
while
(
1
)
{
/*
...
...
@@ -1628,7 +1613,7 @@ void scsi_error_handler(void *data)
* away and die. This typically happens if the user is
* trying to unload a module.
*/
SCSI_LOG_ERROR_RECOVERY
(
1
,
printk
(
"Error handler s
leeping
\n
"
));
SCSI_LOG_ERROR_RECOVERY
(
1
,
printk
(
"Error handler s
csi_eh_%d sleeping
\n
"
,
shost
->
host_no
));
/*
* Note - we always use down_interruptible with the semaphore
...
...
@@ -1640,10 +1625,10 @@ void scsi_error_handler(void *data)
* semaphores isn't unreasonable.
*/
down_interruptible
(
&
sem
);
if
(
s
ignal_pending
(
current
)
)
if
(
s
host
->
eh_kill
)
break
;
SCSI_LOG_ERROR_RECOVERY
(
1
,
printk
(
"Error handler
waking up
\n
"
));
SCSI_LOG_ERROR_RECOVERY
(
1
,
printk
(
"Error handler
scsi_eh_%d waking up
\n
"
,
shost
->
host_no
));
shost
->
eh_active
=
1
;
...
...
@@ -1671,7 +1656,7 @@ void scsi_error_handler(void *data)
}
SCSI_LOG_ERROR_RECOVERY
(
1
,
printk
(
"Error handler
exiting
\n
"
));
SCSI_LOG_ERROR_RECOVERY
(
1
,
printk
(
"Error handler
scsi_eh_%d exiting
\n
"
,
shost
->
host_no
));
/*
* Make sure that nobody tries to wake us up again.
...
...
@@ -1691,13 +1676,9 @@ void scsi_error_handler(void *data)
/*
* If anyone is waiting for us to exit (i.e. someone trying to unload
* a driver), then wake up that process to let them know we are on
* the way out the door. This may be overkill - I *think* that we
* could probably just unload the driver and send the signal, and when
* the error handling thread wakes up that it would just exit without
* needing to touch any memory associated with the driver itself.
* the way out the door.
*/
if
(
shost
->
eh_notify
!=
NULL
)
up
(
shost
->
eh_notify
);
complete_and_exit
(
shost
->
eh_notify
,
0
);
}
/**
...
...
drivers/scsi/scsi_lib.c
View file @
3f7401c6
...
...
@@ -495,6 +495,7 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
int
this_count
=
SCpnt
->
bufflen
>>
9
;
request_queue_t
*
q
=
SCpnt
->
device
->
request_queue
;
struct
request
*
req
=
SCpnt
->
request
;
int
clear_errors
=
1
;
/*
* We must do one of several things here:
...
...
@@ -528,10 +529,22 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
kfree
(
SCpnt
->
buffer
);
}
if
(
blk_pc_request
(
req
))
{
req
->
errors
=
result
&
0xff
;
if
(
!
result
)
if
(
blk_pc_request
(
req
))
{
/* SG_IO ioctl from block level */
req
->
errors
=
(
driver_byte
(
result
)
&
DRIVER_SENSE
)
?
(
CHECK_CONDITION
<<
1
)
:
(
result
&
0xff
);
if
(
!
result
)
req
->
data_len
-=
SCpnt
->
bufflen
;
else
{
clear_errors
=
0
;
if
(
SCpnt
->
sense_buffer
[
0
]
&
0x70
)
{
int
len
=
8
+
SCpnt
->
sense_buffer
[
7
];
if
(
len
>
SCSI_SENSE_BUFFERSIZE
)
len
=
SCSI_SENSE_BUFFERSIZE
;
memcpy
(
req
->
sense
,
SCpnt
->
sense_buffer
,
len
);
req
->
sense_len
=
len
;
}
}
}
/*
...
...
@@ -552,7 +565,8 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
req
->
nr_sectors
,
good_sectors
));
SCSI_LOG_HLCOMPLETE
(
1
,
printk
(
"use_sg is %d
\n
"
,
SCpnt
->
use_sg
));
req
->
errors
=
0
;
if
(
clear_errors
)
req
->
errors
=
0
;
/*
* If multiple sectors are requested in one buffer, then
* they will have been finished off by the first command.
...
...
drivers/scsi/scsi_sysfs.c
View file @
3f7401c6
...
...
@@ -224,6 +224,7 @@ sdev_rd_attr (device_blocked, "%d\n");
sdev_rd_attr
(
current_queue_depth
,
"%d
\n
"
);
sdev_rd_attr
(
new_queue_depth
,
"%d
\n
"
);
sdev_rd_attr
(
type
,
"%d
\n
"
);
sdev_rd_attr
(
scsi_level
,
"%d
\n
"
);
sdev_rd_attr
(
access_count
,
"%d
\n
"
);
sdev_rd_attr
(
vendor
,
"%.8s
\n
"
);
sdev_rd_attr
(
model
,
"%.16s
\n
"
);
...
...
@@ -235,6 +236,7 @@ static struct device_attribute * const sdev_attrs[] = {
&
dev_attr_current_queue_depth
,
&
dev_attr_new_queue_depth
,
&
dev_attr_type
,
&
dev_attr_scsi_level
,
&
dev_attr_access_count
,
&
dev_attr_vendor
,
&
dev_attr_model
,
...
...
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