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
Kirill Smelkov
linux
Commits
a7a339c0
Commit
a7a339c0
authored
Nov 21, 2003
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge nuts.ninka.net:/disk1/davem/BK/network-2.5
into nuts.ninka.net:/disk1/davem/BK/net-2.5
parents
ceb3d4a1
da2ee261
Changes
27
Show whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
320 additions
and
245 deletions
+320
-245
arch/i386/kernel/entry.S
arch/i386/kernel/entry.S
+3
-1
arch/ia64/ia32/ia32_signal.c
arch/ia64/ia32/ia32_signal.c
+3
-0
arch/ia64/kernel/patch.c
arch/ia64/kernel/patch.c
+1
-1
arch/ia64/kernel/signal.c
arch/ia64/kernel/signal.c
+3
-3
arch/ia64/kernel/traps.c
arch/ia64/kernel/traps.c
+2
-4
drivers/ieee1394/sbp2.c
drivers/ieee1394/sbp2.c
+7
-2
drivers/scsi/53c700.c
drivers/scsi/53c700.c
+2
-2
drivers/scsi/NCR53C9x.c
drivers/scsi/NCR53C9x.c
+13
-15
drivers/scsi/arm/acornscsi.c
drivers/scsi/arm/acornscsi.c
+4
-2
drivers/scsi/esp.c
drivers/scsi/esp.c
+18
-19
drivers/scsi/fcal.c
drivers/scsi/fcal.c
+1
-1
drivers/scsi/hosts.c
drivers/scsi/hosts.c
+16
-21
drivers/scsi/hosts.h
drivers/scsi/hosts.h
+1
-48
drivers/scsi/lasi700.c
drivers/scsi/lasi700.c
+2
-1
drivers/scsi/scsi.c
drivers/scsi/scsi.c
+103
-28
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_lib.c
+24
-18
drivers/scsi/scsi_proc.c
drivers/scsi/scsi_proc.c
+7
-9
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_scan.c
+32
-20
drivers/scsi/scsi_syms.c
drivers/scsi/scsi_syms.c
+4
-5
drivers/scsi/scsi_sysfs.c
drivers/scsi/scsi_sysfs.c
+7
-24
drivers/scsi/sg.c
drivers/scsi/sg.c
+4
-3
drivers/scsi/sim710.c
drivers/scsi/sim710.c
+1
-0
drivers/scsi/st.c
drivers/scsi/st.c
+1
-1
drivers/usb/storage/scsiglue.c
drivers/usb/storage/scsiglue.c
+3
-0
include/scsi/scsi_device.h
include/scsi/scsi_device.h
+42
-7
include/scsi/scsi_driver.h
include/scsi/scsi_driver.h
+1
-0
include/scsi/scsi_host.h
include/scsi/scsi_host.h
+15
-10
No files found.
arch/i386/kernel/entry.S
View file @
a7a339c0
...
...
@@ -49,6 +49,8 @@
#include <asm/page.h>
#include "irq_vectors.h"
#define nr_syscalls ((syscall_table_size)/4)
EBX
=
0x00
ECX
=
0x04
EDX
=
0x08
...
...
@@ -881,4 +883,4 @@ ENTRY(sys_call_table)
.
long
sys_fadvise64_64
.
long
sys_ni_syscall
/*
sys_vserver
*/
nr_syscalls
=(.-
sys_call_table
)/
4
syscall_table_size
=(.-
sys_call_table
)
arch/ia64/ia32/ia32_signal.c
View file @
a7a339c0
...
...
@@ -720,6 +720,9 @@ restore_sigcontext_ia32 (struct pt_regs *regs, struct sigcontext_ia32 *sc, int *
{
unsigned
int
err
=
0
;
/* Always make any pending restarted system calls return -EINTR */
current_thread_info
()
->
restart_block
.
fn
=
do_no_restart_syscall
;
if
(
!
access_ok
(
VERIFY_READ
,
sc
,
sizeof
(
*
sc
)))
return
(
-
EFAULT
);
...
...
arch/ia64/kernel/patch.c
View file @
a7a339c0
...
...
@@ -77,7 +77,7 @@ void
ia64_patch_imm60
(
u64
insn_addr
,
u64
val
)
{
ia64_patch
(
insn_addr
,
0x011ffffe000
,
(
((
val
&
0x
1000000000000000
)
>>
24
)
/* bit 60
-> 36 */
0x011ffffe000
,
(
((
val
&
0x
0800000000000000
)
>>
23
)
/* bit 59
-> 36 */
|
((
val
&
0x00000000000fffff
)
<<
13
)
/* bit 0 -> 13 */
));
ia64_patch
(
insn_addr
-
1
,
0x1fffffffffc
,
val
>>
18
);
}
...
...
arch/ia64/kernel/signal.c
View file @
a7a339c0
...
...
@@ -115,6 +115,9 @@ restore_sigcontext (struct sigcontext *sc, struct sigscratch *scr)
unsigned
long
ip
,
flags
,
nat
,
um
,
cfm
;
long
err
;
/* Always make any pending restarted system calls return -EINTR */
current_thread_info
()
->
restart_block
.
fn
=
do_no_restart_syscall
;
/* restore scratch that always needs gets updated during signal delivery: */
err
=
__get_user
(
flags
,
&
sc
->
sc_flags
);
err
|=
__get_user
(
nat
,
&
sc
->
sc_nat
);
...
...
@@ -559,9 +562,6 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
ka
=
&
current
->
sighand
->
action
[
signr
-
1
];
/* Always make any pending restarted system calls return -EINTR */
current_thread_info
()
->
restart_block
.
fn
=
do_no_restart_syscall
;
if
(
restart
)
{
switch
(
errno
)
{
case
ERESTART_RESTARTBLOCK
:
...
...
arch/ia64/kernel/traps.c
View file @
a7a339c0
...
...
@@ -219,16 +219,14 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs)
* Unimplemented system calls. This is called only for stuff that
* we're supposed to implement but haven't done so yet. Everything
* else goes to sys_ni_syscall.
*
* XXX Remove this for v2.6.1.
*/
asmlinkage
long
ia64_ni_syscall
(
unsigned
long
arg0
,
unsigned
long
arg1
,
unsigned
long
arg2
,
unsigned
long
arg3
,
unsigned
long
arg4
,
unsigned
long
arg5
,
unsigned
long
arg6
,
unsigned
long
arg7
,
unsigned
long
stack
)
{
struct
pt_regs
*
regs
=
(
struct
pt_regs
*
)
&
stack
;
printk
(
KERN_DEBUG
"%s(%d): <sc%ld(%lx,%lx,%lx,%lx)>
\n
"
,
current
->
comm
,
current
->
pid
,
regs
->
r15
,
arg0
,
arg1
,
arg2
,
arg3
);
return
-
ENOSYS
;
}
...
...
drivers/ieee1394/sbp2.c
View file @
a7a339c0
...
...
@@ -991,7 +991,7 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
static
void
sbp2_remove_device
(
struct
scsi_id_instance_data
*
scsi_id
)
{
struct
sbp2scsi_host_info
*
hi
=
scsi_id
->
hi
;
struct
scsi_device
*
sdev
=
scsi_find_device
(
hi
->
scsi_host
,
0
,
scsi_id
->
id
,
0
)
;
struct
scsi_device
*
sdev
;
SBP2_DEBUG
(
"sbp2_remove_device"
);
...
...
@@ -999,8 +999,13 @@ static void sbp2_remove_device(struct scsi_id_instance_data *scsi_id)
sbp2scsi_complete_all_commands
(
scsi_id
,
DID_NO_CONNECT
);
/* Remove it from the scsi layer now */
if
(
sdev
)
/* XXX(hch): why can't we simply cache the scsi_device
in struct scsi_id_instance_data? */
sdev
=
scsi_device_lookup
(
hi
->
scsi_host
,
0
,
scsi_id
->
id
,
0
);
if
(
sdev
)
{
scsi_remove_device
(
sdev
);
scsi_device_put
(
sdev
);
}
sbp2util_remove_command_orb_pool
(
scsi_id
);
...
...
drivers/scsi/53c700.c
View file @
a7a339c0
...
...
@@ -1065,7 +1065,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
DEBUG
((
"scsi%d: (%d:%d) RESELECTED!
\n
"
,
host
->
host_no
,
reselection_id
,
lun
));
/* clear the reselection indicator */
SDp
=
scsi_find_device
(
host
,
0
,
reselection_id
,
lun
);
SDp
=
__scsi_device_lookup
(
host
,
0
,
reselection_id
,
lun
);
if
(
unlikely
(
SDp
==
NULL
))
{
printk
(
KERN_ERR
"scsi%d: (%d:%d) HAS NO device
\n
"
,
host
->
host_no
,
reselection_id
,
lun
);
...
...
@@ -1498,7 +1498,7 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs)
host
->
host_no
,
SCp
,
SCp
==
NULL
?
NULL
:
SCp
->
host_scribble
,
dsp
,
dsp
-
hostdata
->
pScript
);
/* clear all the negotiated parameters */
list_for_each_entry
(
SDp
,
&
host
->
my_devices
,
siblings
)
__shost_for_each_device
(
SDp
,
host
)
SDp
->
hostdata
=
0
;
/* clear all the slots and their pending commands */
...
...
drivers/scsi/NCR53C9x.c
View file @
a7a339c0
...
...
@@ -815,6 +815,7 @@ static int copy_info(struct info_str *info, char *fmt, ...)
static
int
esp_host_info
(
struct
NCR_ESP
*
esp
,
char
*
ptr
,
off_t
offset
,
int
len
)
{
struct
scsi_device
*
sdev
;
struct
info_str
info
;
int
i
;
...
...
@@ -867,24 +868,21 @@ static int esp_host_info(struct NCR_ESP *esp, char *ptr, off_t offset, int len)
/* Now describe the state of each existing target. */
copy_info
(
&
info
,
"Target #
\t
config3
\t\t
Sync Capabilities
\t
Disconnect
\n
"
);
for
(
i
=
0
;
i
<
15
;
i
++
)
{
if
(
esp
->
targets_present
&
(
1
<<
i
))
{
Scsi_Device
*
SDptr
;
struct
esp_device
*
esp_dev
;
list_for_each_entry
(
SDptr
,
&
esp
->
ehost
->
my_devices
,
siblings
)
if
(
SDptr
->
id
==
i
)
break
;
shost_for_each_device
(
sdev
,
esp
->
ehost
)
{
struct
esp_device
*
esp_dev
=
sdev
->
hostdata
;
uint
id
=
sdev
->
id
;
esp_dev
=
SDptr
->
hostdata
;
copy_info
(
&
info
,
"%d
\t\t
"
,
i
);
copy_info
(
&
info
,
"%08lx
\t
"
,
esp
->
config3
[
i
]);
copy_info
(
&
info
,
"[%02lx,%02lx]
\t\t\t
"
,
esp_dev
->
sync_max_offset
,
if
(
!
(
esp
->
targets_present
&
(
1
<<
id
)))
continue
;
copy_info
(
&
info
,
"%d
\t\t
"
,
id
);
copy_info
(
&
info
,
"%08lx
\t
"
,
esp
->
config3
[
id
]);
copy_info
(
&
info
,
"[%02lx,%02lx]
\t\t\t
"
,
esp_dev
->
sync_max_offset
,
esp_dev
->
sync_min_period
);
copy_info
(
&
info
,
"%s
\n
"
,
esp_dev
->
disconnect
?
"yes"
:
"no"
);
}
}
return
info
.
pos
>
info
.
offset
?
info
.
pos
-
info
.
offset
:
0
;
}
...
...
drivers/scsi/arm/acornscsi.c
View file @
a7a339c0
...
...
@@ -2930,7 +2930,7 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start,
p
+=
sprintf
(
p
,
"
\n
Attached devices:
\n
"
);
list_for_each_entry
(
scd
,
&
instance
->
my_devices
,
siblings
)
{
shost_for_each_device
(
scd
,
instance
)
{
p
+=
sprintf
(
p
,
"Device/Lun TaggedQ Sync
\n
"
);
p
+=
sprintf
(
p
,
" %d/%d "
,
scd
->
id
,
scd
->
lun
);
if
(
scd
->
tagged_supported
)
...
...
@@ -2953,9 +2953,11 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start,
p
=
buffer
;
}
pos
=
p
-
buffer
;
if
(
pos
+
begin
>
offset
+
length
)
if
(
pos
+
begin
>
offset
+
length
)
{
scsi_device_put
(
scd
);
break
;
}
}
pos
=
p
-
buffer
;
...
...
drivers/scsi/esp.c
View file @
a7a339c0
...
...
@@ -1309,6 +1309,7 @@ static int copy_info(struct info_str *info, char *fmt, ...)
static
int
esp_host_info
(
struct
esp
*
esp
,
char
*
ptr
,
off_t
offset
,
int
len
)
{
struct
scsi_device
*
sdev
;
struct
info_str
info
;
int
i
;
...
...
@@ -1384,25 +1385,23 @@ static int esp_host_info(struct esp *esp, char *ptr, off_t offset, int len)
/* Now describe the state of each existing target. */
copy_info
(
&
info
,
"Target #
\t
config3
\t\t
Sync Capabilities
\t
Disconnect
\t
Wide
\n
"
);
for
(
i
=
0
;
i
<
15
;
i
++
)
{
if
(
esp
->
targets_present
&
(
1
<<
i
))
{
Scsi_Device
*
SDptr
;
struct
esp_device
*
esp_dev
;
list_for_each_entry
(
SDptr
,
&
esp
->
ehost
->
my_devices
,
siblings
)
if
(
SDptr
->
id
==
i
)
break
;
shost_for_each_device
(
sdev
,
esp
->
ehost
)
{
struct
esp_device
*
esp_dev
=
sdev
->
hostdata
;
uint
id
=
sdev
->
id
;
esp_dev
=
SDptr
->
hostdata
;
copy_info
(
&
info
,
"%d
\t\t
"
,
i
);
copy_info
(
&
info
,
"%08lx
\t
"
,
esp
->
config3
[
i
]);
copy_info
(
&
info
,
"[%02lx,%02lx]
\t\t\t
"
,
esp_dev
->
sync_max_offset
,
if
(
!
(
esp
->
targets_present
&
(
1
<<
id
)))
continue
;
copy_info
(
&
info
,
"%d
\t\t
"
,
id
);
copy_info
(
&
info
,
"%08lx
\t
"
,
esp
->
config3
[
id
]);
copy_info
(
&
info
,
"[%02lx,%02lx]
\t\t\t
"
,
esp_dev
->
sync_max_offset
,
esp_dev
->
sync_min_period
);
copy_info
(
&
info
,
"%s
\t\t
"
,
esp_dev
->
disconnect
?
"yes"
:
"no"
);
copy_info
(
&
info
,
"%s
\t\t
"
,
esp_dev
->
disconnect
?
"yes"
:
"no"
);
copy_info
(
&
info
,
"%s
\n
"
,
(
esp
->
config3
[
i
]
&
ESP_CONFIG3_EWIDE
)
?
"yes"
:
"no"
);
}
(
esp
->
config3
[
id
]
&
ESP_CONFIG3_EWIDE
)
?
"yes"
:
"no"
);
}
return
info
.
pos
>
info
.
offset
?
info
.
pos
-
info
.
offset
:
0
;
}
...
...
drivers/scsi/fcal.c
View file @
a7a339c0
...
...
@@ -228,7 +228,7 @@ int fcal_proc_info (struct Scsi_Host *host, char *buffer, char **start, off_t of
#endif
SPRINTF
(
"Initiator AL-PA: %02x
\n
"
,
fc
->
sid
);
SPRINTF
(
"
\n
Attached devices:
%s
\n
"
,
!
list_empty
(
&
host
->
my_devices
)
?
""
:
"none
"
);
SPRINTF
(
"
\n
Attached devices:
\n
"
);
for
(
i
=
0
;
i
<
fc
->
posmap
->
len
;
i
++
)
{
unsigned
char
alpa
=
fc
->
posmap
->
list
[
i
];
...
...
drivers/scsi/hosts.c
View file @
a7a339c0
/*
* hosts.c Copyright (C) 1992 Drew Eckhardt
* Copyright (C) 1993, 1994, 1995 Eric Youngdale
* Copyright (C) 2002-2003 Christoph Hellwig
*
* mid to lowlevel SCSI driver interface
* Initial versions: Drew Eckhardt
...
...
@@ -30,8 +31,8 @@
#include <linux/completion.h>
#include <linux/unistd.h>
#include <scsi/scsi_host.h>
#include "scsi.h"
#include "hosts.h"
#include "scsi_priv.h"
#include "scsi_logging.h"
...
...
@@ -50,6 +51,11 @@ static struct class shost_class = {
.
release
=
scsi_host_cls_release
,
};
static
int
scsi_device_cancel_cb
(
struct
device
*
dev
,
void
*
data
)
{
return
scsi_device_cancel
(
to_scsi_device
(
dev
),
*
(
int
*
)
data
);
}
/**
* scsi_host_cancel - cancel outstanding IO to this host
* @shost: pointer to struct Scsi_Host
...
...
@@ -57,11 +63,7 @@ static struct class shost_class = {
**/
void
scsi_host_cancel
(
struct
Scsi_Host
*
shost
,
int
recovery
)
{
unsigned
long
flags
;
spin_lock_irqsave
(
shost
->
host_lock
,
flags
);
set_bit
(
SHOST_CANCEL
,
&
shost
->
shost_state
);
spin_unlock_irqrestore
(
shost
->
host_lock
,
flags
);
device_for_each_child
(
&
shost
->
shost_gendev
,
&
recovery
,
scsi_device_cancel_cb
);
wait_event
(
shost
->
host_wait
,
(
!
test_bit
(
SHOST_RECOVERY
,
...
...
@@ -74,15 +76,11 @@ void scsi_host_cancel(struct Scsi_Host *shost, int recovery)
**/
void
scsi_remove_host
(
struct
Scsi_Host
*
shost
)
{
unsigned
long
flags
;
scsi_host_cancel
(
shost
,
0
);
scsi_proc_host_rm
(
shost
);
scsi_forget_host
(
shost
);
spin_lock_irqsave
(
shost
->
host_lock
,
flags
);
set_bit
(
SHOST_DEL
,
&
shost
->
shost_state
);
spin_unlock_irqrestore
(
shost
->
host_lock
,
flags
);
class_device_unregister
(
&
shost
->
shost_classdev
);
device_del
(
&
shost
->
shost_gendev
);
...
...
@@ -209,7 +207,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
spin_lock_init
(
&
shost
->
default_lock
);
scsi_assign_lock
(
shost
,
&
shost
->
default_lock
);
INIT_LIST_HEAD
(
&
shost
->
my
_devices
);
INIT_LIST_HEAD
(
&
shost
->
_
_devices
);
INIT_LIST_HEAD
(
&
shost
->
eh_cmd_q
);
INIT_LIST_HEAD
(
&
shost
->
starved_list
);
init_waitqueue_head
(
&
shost
->
host_wait
);
...
...
@@ -323,11 +321,10 @@ void scsi_unregister(struct Scsi_Host *shost)
**/
struct
Scsi_Host
*
scsi_host_lookup
(
unsigned
short
hostnum
)
{
struct
class
*
class
=
class_get
(
&
shost_class
)
;
struct
class
*
class
=
&
shost_class
;
struct
class_device
*
cdev
;
struct
Scsi_Host
*
shost
=
ERR_PTR
(
-
ENXIO
),
*
p
;
if
(
class
)
{
down_read
(
&
class
->
subsys
.
rwsem
);
list_for_each_entry
(
cdev
,
&
class
->
children
,
node
)
{
p
=
class_to_shost
(
cdev
);
...
...
@@ -337,9 +334,7 @@ struct Scsi_Host *scsi_host_lookup(unsigned short hostnum)
}
}
up_read
(
&
class
->
subsys
.
rwsem
);
}
class_put
(
&
shost_class
);
return
shost
;
}
...
...
drivers/scsi/hosts.h
View file @
a7a339c0
/*
* hosts.h Copyright (C) 1992 Drew Eckhardt
* Copyright (C) 1993, 1994, 1995, 1998, 1999 Eric Youngdale
*
* mid to low-level SCSI driver interface header
* Initial versions: Drew Eckhardt
* Subsequent revisions: Eric Youngdale
*
* <drew@colorado.edu>
*
* Modified by Eric Youngdale eric@andante.org to
* add scatter-gather, multiple outstanding request, and other
* enhancements.
*
* Further modified by Eric Youngdale to support multiple host adapters
* of the same type.
*
* Jiffies wrap fixes (host->resetting), 3 Dec 1998 Andrea Arcangeli
*
* Restructured scsi_host lists and associated functions.
* September 04, 2002 Mike Anderson (andmike@us.ibm.com)
*/
#ifndef _HOSTS_H
#define _HOSTS_H
#include <linux/config.h>
// #warning "This file is obsolete, please use <scsi/scsi_host.h> instead"
#include <scsi/scsi_host.h>
/**
* scsi_find_device - find a device given the host
* @shost: SCSI host pointer
* @channel: SCSI channel (zero if only one channel)
* @pun: SCSI target number (physical unit number)
* @lun: SCSI Logical Unit Number
**/
static
inline
struct
scsi_device
*
scsi_find_device
(
struct
Scsi_Host
*
shost
,
int
channel
,
int
pun
,
int
lun
)
{
struct
scsi_device
*
sdev
;
list_for_each_entry
(
sdev
,
&
shost
->
my_devices
,
siblings
)
if
(
sdev
->
channel
==
channel
&&
sdev
->
id
==
pun
&&
sdev
->
lun
==
lun
)
return
sdev
;
return
NULL
;
}
#endif
drivers/scsi/lasi700.c
View file @
a7a339c0
...
...
@@ -69,8 +69,9 @@ static Scsi_Host_Template lasi700_template = {
.
name
=
"LASI SCSI 53c700"
,
.
proc_name
=
"lasi700"
,
.
this_id
=
7
,
.
module
=
THIS_MODULE
,
};
MODULE_DEVICE_TABLE
(
parisc
,
lasi700_
scsi_tbl
);
MODULE_DEVICE_TABLE
(
parisc
,
lasi700_
ids
);
static
int
__init
lasi700_probe
(
struct
parisc_device
*
dev
)
...
...
drivers/scsi/scsi.c
View file @
a7a339c0
/*
* scsi.c Copyright (C) 1992 Drew Eckhardt
* Copyright (C) 1993, 1994, 1995, 1999 Eric Youngdale
* Copyright (C) 2002, 2003 Christoph Hellwig
*
* generic mid-level SCSI driver
* Initial versions: Drew Eckhardt
...
...
@@ -36,7 +37,6 @@
* out_of_space hacks, D. Gilbert (dpg) 990608
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
...
...
@@ -54,8 +54,8 @@
#include <linux/kmod.h>
#include <linux/interrupt.h>
#include <scsi/scsi_host.h>
#include "scsi.h"
#include "hosts.h"
#include "scsi_priv.h"
#include "scsi_logging.h"
...
...
@@ -883,49 +883,124 @@ int scsi_track_queue_full(struct scsi_device *sdev, int depth)
return
depth
;
}
/**
* scsi_device_get - get an addition reference to a scsi_device
* @sdev: device to get a reference to
*
* Gets a reference to the scsi_device and increments the use count
* of the underlying LLDD module. You must hold host_lock of the
* parent Scsi_Host or already have a reference when calling this.
*/
int
scsi_device_get
(
struct
scsi_device
*
sdev
)
{
struct
class
*
class
=
class_get
(
&
sdev_class
);
if
(
!
class
)
goto
out
;
if
(
test_bit
(
SDEV_DEL
,
&
sdev
->
sdev_state
))
goto
out
;
if
(
!
try_module_get
(
sdev
->
host
->
hostt
->
module
))
goto
out
;
return
-
ENXIO
;
if
(
!
get_device
(
&
sdev
->
sdev_gendev
))
goto
out_put_module
;
atomic_inc
(
&
sdev
->
access_count
);
class_put
(
&
sdev_class
);
return
-
ENXIO
;
if
(
!
try_module_get
(
sdev
->
host
->
hostt
->
module
))
{
put_device
(
&
sdev
->
sdev_gendev
);
return
-
ENXIO
;
}
return
0
;
}
EXPORT_SYMBOL
(
scsi_device_get
);
out_put_module:
/**
* scsi_device_put - release a reference to a scsi_device
* @sdev: device to release a reference on.
*
* Release a reference to the scsi_device and decrements the use count
* of the underlying LLDD module. The device is freed once the last
* user vanishes.
*/
void
scsi_device_put
(
struct
scsi_device
*
sdev
)
{
module_put
(
sdev
->
host
->
hostt
->
module
);
out:
class_put
(
&
sdev_class
);
return
-
ENXIO
;
put_device
(
&
sdev
->
sdev_gendev
);
}
EXPORT_SYMBOL
(
scsi_device_put
);
void
scsi_device_put
(
struct
scsi_device
*
sdev
)
/* helper for shost_for_each_device, thus not documented */
struct
scsi_device
*
__scsi_iterate_devices
(
struct
Scsi_Host
*
shost
,
struct
scsi_device
*
prev
)
{
struct
class
*
class
=
class_get
(
&
sdev_class
);
struct
list_head
*
list
=
(
prev
?
&
prev
->
siblings
:
&
shost
->
__devices
);
struct
scsi_device
*
next
=
NULL
;
unsigned
long
flags
;
if
(
!
class
)
return
;
spin_lock_irqsave
(
shost
->
host_lock
,
flags
);
while
(
list
->
next
!=
&
shost
->
__devices
)
{
next
=
list_entry
(
list
->
next
,
struct
scsi_device
,
siblings
);
/* skip devices that we can't get a reference to */
if
(
!
scsi_device_get
(
next
))
break
;
list
=
list
->
next
;
}
spin_unlock_irqrestore
(
shost
->
host_lock
,
flags
);
module_put
(
sdev
->
host
->
hostt
->
module
);
atomic_dec
(
&
sdev
->
access_count
);
put_device
(
&
sdev
->
sdev_gendev
);
class_put
(
&
sdev_class
);
if
(
prev
)
scsi_device_put
(
prev
);
return
next
;
}
EXPORT_SYMBOL
(
__scsi_iterate_devices
);
int
scsi_device_cancel_cb
(
struct
device
*
dev
,
void
*
data
)
/**
* scsi_device_lookup - find a device given the host (UNLOCKED)
* @shost: SCSI host pointer
* @channel: SCSI channel (zero if only one channel)
* @pun: SCSI target number (physical unit number)
* @lun: SCSI Logical Unit Number
*
* Looks up the scsi_device with the specified @channel, @id, @lun for a
* give host. The returned scsi_device does not have an additional reference.
* You must hold the host's host_lock over this call and any access to the
* returned scsi_device.
*
* Note: The only reason why drivers would want to use this is because
* they're need to access the device list in irq context. Otherwise you
* really want to use scsi_device_lookup instead.
**/
struct
scsi_device
*
__scsi_device_lookup
(
struct
Scsi_Host
*
shost
,
uint
channel
,
uint
id
,
uint
lun
)
{
struct
scsi_device
*
sdev
=
to_scsi_device
(
dev
);
int
recovery
=
*
(
int
*
)
data
;
struct
scsi_device
*
sdev
;
list_for_each_entry
(
sdev
,
&
shost
->
__devices
,
siblings
)
{
if
(
sdev
->
channel
==
channel
&&
sdev
->
id
==
id
&&
sdev
->
lun
==
lun
)
return
sdev
;
}
return
NULL
;
}
EXPORT_SYMBOL
(
__scsi_device_lookup
);
/**
* scsi_device_lookup - find a device given the host
* @shost: SCSI host pointer
* @channel: SCSI channel (zero if only one channel)
* @id: SCSI target number (physical unit number)
* @lun: SCSI Logical Unit Number
*
* Looks up the scsi_device with the specified @channel, @id, @lun for a
* give host. The returned scsi_device has an additional reference that
* needs to be release with scsi_host_put once you're done with it.
**/
struct
scsi_device
*
scsi_device_lookup
(
struct
Scsi_Host
*
shost
,
uint
channel
,
uint
id
,
uint
lun
)
{
struct
scsi_device
*
sdev
;
unsigned
long
flags
;
spin_lock_irqsave
(
shost
->
host_lock
,
flags
);
sdev
=
__scsi_device_lookup
(
shost
,
channel
,
id
,
lun
);
if
(
sdev
&&
scsi_device_get
(
sdev
))
sdev
=
NULL
;
spin_unlock_irqrestore
(
shost
->
host_lock
,
flags
);
return
s
csi_device_cancel
(
sdev
,
recovery
)
;
return
s
dev
;
}
EXPORT_SYMBOL
(
scsi_device_lookup
);
/**
* scsi_device_cancel - cancel outstanding IO to this device
...
...
drivers/scsi/scsi_lib.c
View file @
a7a339c0
...
...
@@ -16,9 +16,9 @@
#include <linux/init.h>
#include <linux/pci.h>
#include "scsi.h"
#include "hosts.h"
#include <scsi/scsi_driver.h>
#include <scsi/scsi_host.h>
#include "scsi.h"
#include "scsi_priv.h"
#include "scsi_logging.h"
...
...
@@ -335,13 +335,14 @@ void scsi_device_unbusy(struct scsi_device *sdev)
*/
static
void
scsi_single_lun_run
(
struct
scsi_device
*
current_sdev
)
{
struct
scsi_device
*
sdev
;
struct
Scsi_Host
*
shost
=
current_sdev
->
host
;
struct
scsi_device
*
sdev
,
*
tmp
;
unsigned
long
flags
;
spin_lock_irqsave
(
current_sdev
->
host
->
host_lock
,
flags
);
spin_lock_irqsave
(
s
host
->
host_lock
,
flags
);
WARN_ON
(
!
current_sdev
->
sdev_target
->
starget_sdev_user
);
current_sdev
->
sdev_target
->
starget_sdev_user
=
NULL
;
spin_unlock_irqrestore
(
current_sdev
->
host
->
host_lock
,
flags
);
spin_unlock_irqrestore
(
s
host
->
host_lock
,
flags
);
/*
* Call blk_run_queue for all LUNs on the target, starting with
...
...
@@ -351,21 +352,26 @@ static void scsi_single_lun_run(struct scsi_device *current_sdev)
*/
blk_run_queue
(
current_sdev
->
request_queue
);
spin_lock_irqsave
(
current_sdev
->
host
->
host_lock
,
flags
);
if
(
current_sdev
->
sdev_target
->
starget_sdev_user
)
{
/*
* After unlock, this races with anyone clearing
* starget_sdev_user, but we (should) always enter this
* function again, avoiding any problems.
* After unlock, this races with anyone clearing starget_sdev_user,
* but we always enter this function again, avoiding any problems.
*/
spin_unlock_irqrestore
(
current_sdev
->
host
->
host_lock
,
flags
);
return
;
}
spin_unlock_irqrestore
(
current_sdev
->
host
->
host_lock
,
flags
);
spin_lock_irqsave
(
shost
->
host_lock
,
flags
);
if
(
current_sdev
->
sdev_target
->
starget_sdev_user
)
goto
out
;
list_for_each_entry_safe
(
sdev
,
tmp
,
&
current_sdev
->
same_target_siblings
,
same_target_siblings
)
{
if
(
scsi_device_get
(
sdev
))
continue
;
list_for_each_entry
(
sdev
,
&
current_sdev
->
same_target_siblings
,
same_target_siblings
)
spin_unlock_irqrestore
(
shost
->
host_lock
,
flags
);
blk_run_queue
(
sdev
->
request_queue
);
spin_lock_irqsave
(
shost
->
host_lock
,
flags
);
scsi_device_put
(
sdev
);
}
out:
spin_unlock_irqrestore
(
shost
->
host_lock
,
flags
);
}
/*
...
...
drivers/scsi/scsi_proc.c
View file @
a7a339c0
...
...
@@ -27,8 +27,8 @@
#include <linux/seq_file.h>
#include <asm/uaccess.h>
#include <scsi/scsi_host.h>
#include "scsi.h"
#include "hosts.h"
#include "scsi_priv.h"
#include "scsi_logging.h"
...
...
@@ -212,15 +212,13 @@ static int scsi_remove_single_device(uint host, uint channel, uint id, uint lun)
shost
=
scsi_host_lookup
(
host
);
if
(
IS_ERR
(
shost
))
return
PTR_ERR
(
shost
);
sdev
=
scsi_find_device
(
shost
,
channel
,
id
,
lun
);
if
(
!
sdev
)
goto
out
;
if
(
atomic_read
(
&
sdev
->
access_count
))
goto
out
;
sdev
=
scsi_device_lookup
(
shost
,
channel
,
id
,
lun
);
if
(
sdev
)
{
scsi_remove_device
(
sdev
);
scsi_device_put
(
sdev
);
error
=
0
;
out:
}
scsi_host_put
(
shost
);
return
error
;
}
...
...
drivers/scsi/scsi_scan.c
View file @
a7a339c0
...
...
@@ -32,10 +32,10 @@
#include <linux/blkdev.h>
#include <asm/semaphore.h>
#include "scsi.h"
#include "hosts.h"
#include <scsi/scsi_driver.h>
#include <scsi/scsi_devinfo.h>
#include <scsi/scsi_host.h>
#include "scsi.h"
#include "scsi_priv.h"
#include "scsi_logging.h"
...
...
@@ -190,13 +190,13 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
uint
channel
,
uint
id
,
uint
lun
)
{
struct
scsi_device
*
sdev
,
*
device
;
unsigned
long
flags
;
sdev
=
kmalloc
(
sizeof
(
*
sdev
),
GFP_ATOMIC
);
if
(
!
sdev
)
goto
out
;
memset
(
sdev
,
0
,
sizeof
(
*
sdev
));
atomic_set
(
&
sdev
->
access_count
,
0
);
sdev
->
vendor
=
scsi_null_device_strs
;
sdev
->
model
=
scsi_null_device_strs
;
sdev
->
rev
=
scsi_null_device_strs
;
...
...
@@ -240,7 +240,8 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
* If there are any same target siblings, add this to the
* sibling list
*/
list_for_each_entry
(
device
,
&
shost
->
my_devices
,
siblings
)
{
spin_lock_irqsave
(
shost
->
host_lock
,
flags
);
list_for_each_entry
(
device
,
&
shost
->
__devices
,
siblings
)
{
if
(
device
->
id
==
sdev
->
id
&&
device
->
channel
==
sdev
->
channel
)
{
list_add_tail
(
&
sdev
->
same_target_siblings
,
...
...
@@ -258,10 +259,8 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
if
(
!
sdev
->
scsi_level
)
sdev
->
scsi_level
=
SCSI_2
;
/*
* Add it to the end of the shost->my_devices list.
*/
list_add_tail
(
&
sdev
->
siblings
,
&
shost
->
my_devices
);
list_add_tail
(
&
sdev
->
siblings
,
&
shost
->
__devices
);
spin_unlock_irqrestore
(
shost
->
host_lock
,
flags
);
return
sdev
;
out_free_queue:
...
...
@@ -285,21 +284,21 @@ void scsi_free_sdev(struct scsi_device *sdev)
{
unsigned
long
flags
;
spin_lock_irqsave
(
sdev
->
host
->
host_lock
,
flags
);
list_del
(
&
sdev
->
siblings
);
list_del
(
&
sdev
->
same_target_siblings
);
spin_unlock_irqrestore
(
sdev
->
host
->
host_lock
,
flags
);
if
(
sdev
->
request_queue
)
scsi_free_queue
(
sdev
->
request_queue
);
if
(
sdev
->
inquiry
)
kfree
(
sdev
->
inquiry
);
spin_lock_irqsave
(
sdev
->
host
->
host_lock
,
flags
);
list_del
(
&
sdev
->
starved_entry
);
if
(
sdev
->
single_lun
)
{
if
(
--
sdev
->
sdev_target
->
starget_refcnt
==
0
)
if
(
sdev
->
single_lun
&&
--
sdev
->
sdev_target
->
starget_refcnt
==
0
)
kfree
(
sdev
->
sdev_target
);
}
spin_unlock_irqrestore
(
sdev
->
host
->
host_lock
,
flags
);
kfree
(
sdev
->
inquiry
);
kfree
(
sdev
);
}
...
...
@@ -678,7 +677,7 @@ static int scsi_probe_and_add_lun(struct Scsi_Host *host,
* host adapter calls into here with rescan == 0.
*/
if
(
rescan
)
{
sdev
=
scsi_
find_device
(
host
,
channel
,
id
,
lun
);
sdev
=
scsi_
device_lookup
(
host
,
channel
,
id
,
lun
);
if
(
sdev
)
{
SCSI_LOG_SCAN_BUS
(
3
,
printk
(
KERN_INFO
"scsi scan: device exists on <%d:%d:%d:%d>
\n
"
,
...
...
@@ -689,6 +688,8 @@ static int scsi_probe_and_add_lun(struct Scsi_Host *host,
*
bflagsp
=
scsi_get_device_flags
(
sdev
,
sdev
->
vendor
,
sdev
->
model
);
/* XXX: bandaid until callers do refcounting */
scsi_device_put
(
sdev
);
return
SCSI_SCAN_LUN_PRESENT
;
}
}
...
...
@@ -1232,14 +1233,25 @@ void scsi_scan_host(struct Scsi_Host *shost)
void
scsi_forget_host
(
struct
Scsi_Host
*
shost
)
{
struct
list_head
*
le
,
*
lh
;
struct
scsi_device
*
sdev
;
list_for_each_safe
(
le
,
lh
,
&
shost
->
my_devices
)
{
sdev
=
list_entry
(
le
,
struct
scsi_device
,
siblings
);
struct
scsi_device
*
sdev
,
*
tmp
;
unsigned
long
flags
;
/*
* Ok, this look a bit strange. We always look for the first device
* on the list as scsi_remove_device removes them from it - thus we
* also have to release the lock.
* We don't need to get another reference to the device before
* releasing the lock as we already own the reference from
* scsi_register_device that's release in scsi_remove_device. And
* after that we don't look at sdev anymore.
*/
spin_lock_irqsave
(
shost
->
host_lock
,
flags
);
list_for_each_entry_safe
(
sdev
,
tmp
,
&
shost
->
__devices
,
siblings
)
{
spin_unlock_irqrestore
(
shost
->
host_lock
,
flags
);
scsi_remove_device
(
sdev
);
spin_lock_irqsave
(
shost
->
host_lock
,
flags
);
}
spin_unlock_irqrestore
(
shost
->
host_lock
,
flags
);
}
/*
...
...
drivers/scsi/scsi_syms.c
View file @
a7a339c0
...
...
@@ -18,13 +18,14 @@
#include <asm/irq.h>
#include <asm/dma.h>
#include "scsi.h"
#include <scsi/scsi_driver.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_ioctl.h>
#include "hosts.h"
#include <scsi/scsicam.h>
#include "scsi.h"
#include "scsi_logging.h"
#include <scsi/scsicam.h>
/*
* This source file contains the symbol table used by scsi loadable
...
...
@@ -82,8 +83,6 @@ EXPORT_SYMBOL(scsi_sleep);
EXPORT_SYMBOL
(
scsi_io_completion
);
EXPORT_SYMBOL
(
scsi_device_get
);
EXPORT_SYMBOL
(
scsi_device_put
);
EXPORT_SYMBOL
(
scsi_add_device
);
EXPORT_SYMBOL
(
scsi_remove_device
);
EXPORT_SYMBOL
(
scsi_device_cancel
);
...
...
drivers/scsi/scsi_sysfs.c
View file @
a7a339c0
...
...
@@ -11,8 +11,9 @@
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/device.h>
#include <scsi/scsi_host.h>
#include "scsi.h"
#include "hosts.h"
#include "scsi_priv.h"
#include "scsi_logging.h"
...
...
@@ -257,20 +258,12 @@ store_rescan_field (struct device *dev, const char *buf, size_t count)
scsi_rescan_device
(
dev
);
return
count
;
}
static
DEVICE_ATTR
(
rescan
,
S_IWUSR
,
NULL
,
store_rescan_field
)
static
ssize_t
sdev_store_delete
(
struct
device
*
dev
,
const
char
*
buf
,
size_t
count
)
{
struct
scsi_device
*
sdev
=
to_scsi_device
(
dev
);
/*
* FIXME and scsi_proc.c: racey use of access_count,
*/
if
(
atomic_read
(
&
sdev
->
access_count
))
return
-
EBUSY
;
scsi_remove_device
(
sdev
);
scsi_remove_device
(
to_scsi_device
(
dev
));
return
count
;
};
static
DEVICE_ATTR
(
delete
,
S_IWUSR
,
NULL
,
sdev_store_delete
);
...
...
@@ -403,22 +396,12 @@ int scsi_device_register(struct scsi_device *sdev)
**/
void
scsi_remove_device
(
struct
scsi_device
*
sdev
)
{
struct
class
*
class
=
class_get
(
&
sdev_class
);
class_device_unregister
(
&
sdev
->
sdev_classdev
);
if
(
class
)
{
down_write
(
&
class
->
subsys
.
rwsem
);
set_bit
(
SDEV_DEL
,
&
sdev
->
sdev_state
);
if
(
sdev
->
host
->
hostt
->
slave_destroy
)
sdev
->
host
->
hostt
->
slave_destroy
(
sdev
);
device_del
(
&
sdev
->
sdev_gendev
);
up_write
(
&
class
->
subsys
.
rwsem
);
}
put_device
(
&
sdev
->
sdev_gendev
);
class_put
(
&
sdev_class
);
}
int
scsi_register_driver
(
struct
device_driver
*
drv
)
...
...
drivers/scsi/sg.c
View file @
a7a339c0
...
...
@@ -914,7 +914,8 @@ sg_ioctl(struct inode *inode, struct file *filp,
case
SG_GET_VERSION_NUM
:
return
put_user
(
sg_version_num
,
(
int
*
)
arg
);
case
SG_GET_ACCESS_COUNT
:
val
=
(
sdp
->
device
?
atomic_read
(
&
sdp
->
device
->
access_count
)
:
0
);
/* faked - we don't have a real access count anymore */
val
=
(
sdp
->
device
?
1
:
0
);
return
put_user
(
val
,
(
int
*
)
arg
);
case
SG_GET_REQUEST_TABLE
:
result
=
verify_area
(
VERIFY_WRITE
,
(
void
*
)
arg
,
...
...
@@ -1627,7 +1628,7 @@ st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
unsigned
int
nr_pages
;
struct
page
**
pages
;
nr_pages
=
((
uaddr
&
~
PAGE_MASK
)
+
count
-
1
+
~
PAGE_MASK
)
>>
PAGE_SHIFT
;
nr_pages
=
((
uaddr
&
~
PAGE_MASK
)
+
count
+
~
PAGE_MASK
)
>>
PAGE_SHIFT
;
/* User attempted Overflow! */
if
((
uaddr
+
count
)
<
uaddr
)
...
...
@@ -2903,7 +2904,7 @@ sg_proc_dev_info(char *buffer, int *len, off_t * begin, off_t offset, int size)
PRINT_PROC
(
"%d
\t
%d
\t
%d
\t
%d
\t
%d
\t
%d
\t
%d
\t
%d
\t
%d
\n
"
,
scsidp
->
host
->
host_no
,
scsidp
->
channel
,
scsidp
->
id
,
scsidp
->
lun
,
(
int
)
scsidp
->
type
,
(
int
)
atomic_read
(
&
scsidp
->
access_count
)
,
1
,
(
int
)
scsidp
->
queue_depth
,
(
int
)
scsidp
->
device_busy
,
(
int
)
scsidp
->
online
);
...
...
drivers/scsi/sim710.c
View file @
a7a339c0
...
...
@@ -90,6 +90,7 @@ static Scsi_Host_Template sim710_driver_template = {
.
name
=
"LSI (Symbios) 710 MCA/EISA"
,
.
proc_name
=
"sim710"
,
.
this_id
=
7
,
.
module
=
THIS_MODULE
,
};
static
__devinit
int
...
...
drivers/scsi/st.c
View file @
a7a339c0
...
...
@@ -4036,7 +4036,7 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa
unsigned
int
nr_pages
;
struct
page
**
pages
;
nr_pages
=
((
uaddr
&
~
PAGE_MASK
)
+
count
-
1
+
~
PAGE_MASK
)
>>
PAGE_SHIFT
;
nr_pages
=
((
uaddr
&
~
PAGE_MASK
)
+
count
+
~
PAGE_MASK
)
>>
PAGE_SHIFT
;
/* User attempted Overflow! */
if
((
uaddr
+
count
)
<
uaddr
)
...
...
drivers/usb/storage/scsiglue.c
View file @
a7a339c0
...
...
@@ -312,6 +312,9 @@ struct scsi_host_template usb_stor_host_template = {
/* lots of sg segments can be handled */
.
sg_tablesize
=
SG_ALL
,
/* limit the total size of a transfer to 120 KB */
.
max_sectors
=
240
,
/* merge commands... this seems to help performance, but
* periodically someone should test to see which setting is more
* optimal.
...
...
include/scsi/scsi_device.h
View file @
a7a339c0
...
...
@@ -22,10 +22,13 @@ enum {
};
struct
scsi_device
{
struct
list_head
siblings
;
/* list of all devices on this host */
struct
list_head
same_target_siblings
;
/* just the devices sharing same target id */
struct
Scsi_Host
*
host
;
struct
request_queue
*
request_queue
;
/* the next two are protected by the host->host_lock */
struct
list_head
siblings
;
/* list of all devices on this host */
struct
list_head
same_target_siblings
;
/* just the devices sharing same target id */
volatile
unsigned
short
device_busy
;
/* commands actually active on low-level */
spinlock_t
sdev_lock
;
/* also the request queue_lock */
spinlock_t
list_lock
;
...
...
@@ -45,8 +48,6 @@ struct scsi_device {
* vendor-specific cmd's */
unsigned
sector_size
;
/* size in bytes */
atomic_t
access_count
;
/* Count of open channels/mounts */
void
*
hostdata
;
/* available to low-level driver */
char
devfs_name
[
256
];
/* devfs junk */
char
type
;
...
...
@@ -108,14 +109,48 @@ struct scsi_device {
extern
struct
scsi_device
*
scsi_add_device
(
struct
Scsi_Host
*
,
uint
,
uint
,
uint
);
extern
void
scsi_remove_device
(
struct
scsi_device
*
);
extern
int
scsi_device_cancel_cb
(
struct
device
*
,
void
*
);
extern
int
scsi_device_cancel
(
struct
scsi_device
*
,
int
);
extern
int
scsi_device_get
(
struct
scsi_device
*
);
extern
void
scsi_device_put
(
struct
scsi_device
*
);
extern
struct
scsi_device
*
scsi_device_lookup
(
struct
Scsi_Host
*
,
uint
,
uint
,
uint
);
extern
struct
scsi_device
*
__scsi_device_lookup
(
struct
Scsi_Host
*
,
uint
,
uint
,
uint
);
/* only exposed to implement shost_for_each_device */
extern
struct
scsi_device
*
__scsi_iterate_devices
(
struct
Scsi_Host
*
,
struct
scsi_device
*
);
/**
* shost_for_each_device - iterate over all devices of a host
* @sdev: iterator
* @host: host whiches devices we want to iterate over
*
* This traverses over each devices of @shost. The devices have
* a reference that must be released by scsi_host_put when breaking
* out of the loop.
*/
#define shost_for_each_device(sdev, shost) \
list_for_each_entry((sdev), &((shost)->my_devices), siblings)
for ((sdev) = __scsi_iterate_devices((shost), NULL); \
(sdev); \
(sdev) = __scsi_iterate_devices((shost), (sdev)))
/**
* __shost_for_each_device - iterate over all devices of a host (UNLOCKED)
* @sdev: iterator
* @host: host whiches devices we want to iterate over
*
* This traverses over each devices of @shost. It does _not_ take a
* reference on the scsi_device, thus it the whole loop must be protected
* by shost->host_lock.
*
* Note: The only reason why drivers would want to use this is because
* they're need to access the device list in irq context. Otherwise you
* really want to use shost_for_each_device instead.
*/
#define __shost_for_each_device(sdev, shost) \
list_for_each_entry((sdev), &((shost)->__devices), siblings)
extern
void
scsi_adjust_queue_depth
(
struct
scsi_device
*
,
int
,
int
);
extern
int
scsi_track_queue_full
(
struct
scsi_device
*
,
int
);
...
...
include/scsi/scsi_driver.h
View file @
a7a339c0
...
...
@@ -4,6 +4,7 @@
#include <linux/device.h>
struct
module
;
struct
scsi_cmnd
;
struct
scsi_driver
{
...
...
include/scsi/scsi_host.h
View file @
a7a339c0
...
...
@@ -363,7 +363,16 @@ enum {
};
struct
Scsi_Host
{
struct
list_head
my_devices
;
/*
* __devices is protected by the host_lock, but you should
* usually use scsi_device_lookup / shost_for_each_device
* to access it and don't care about locking yourself.
* In the rare case of beeing in irq context you can use
* their __ prefixed variants with the lock held. NEVER
* access this list directly from a driver.
*/
struct
list_head
__devices
;
struct
scsi_host_cmd_pool
*
cmd_pool
;
spinlock_t
free_list_lock
;
struct
list_head
free_list
;
/* backup store of cmd structs */
...
...
@@ -372,10 +381,12 @@ struct Scsi_Host {
spinlock_t
default_lock
;
spinlock_t
*
host_lock
;
struct
semaphore
scan_mutex
;
/* serialize scanning activity */
struct
list_head
eh_cmd_q
;
struct
task_struct
*
ehandler
;
/* Error recovery thread. */
struct
semaphore
*
eh_wait
;
/* The error recovery thread waits
on
this. */
struct
semaphore
*
eh_wait
;
/* The error recovery thread waits
on
this. */
struct
completion
*
eh_notify
;
/* wait for eh to begin or end */
struct
semaphore
*
eh_action
;
/* Wait for specific actions on the
host. */
...
...
@@ -478,12 +489,6 @@ struct Scsi_Host {
*/
struct
list_head
sht_legacy_list
;
/*
* This mutex serializes all scsi scanning activity from kernel- and
* userspace.
*/
struct
semaphore
scan_mutex
;
/*
* We should ensure that this is aligned, both for better performance
* and also because some compilers (m68k) don't automatically force
...
...
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