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
5237662f
Commit
5237662f
authored
Nov 20, 2003
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://linux-scsi.bkbits.net/scsi-bugfixes-2.6
into home.osdl.org:/home/torvalds/v2.5/linux
parents
03f78a19
d177ca18
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
305 additions
and
236 deletions
+305
-236
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
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.
drivers/ieee1394/sbp2.c
View file @
5237662f
...
@@ -991,7 +991,7 @@ static int sbp2_start_device(struct scsi_id_instance_data *scsi_id)
...
@@ -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
)
static
void
sbp2_remove_device
(
struct
scsi_id_instance_data
*
scsi_id
)
{
{
struct
sbp2scsi_host_info
*
hi
=
scsi_id
->
hi
;
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"
);
SBP2_DEBUG
(
"sbp2_remove_device"
);
...
@@ -999,8 +999,13 @@ static void sbp2_remove_device(struct scsi_id_instance_data *scsi_id)
...
@@ -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
);
sbp2scsi_complete_all_commands
(
scsi_id
,
DID_NO_CONNECT
);
/* Remove it from the scsi layer now */
/* 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_remove_device
(
sdev
);
scsi_device_put
(
sdev
);
}
sbp2util_remove_command_orb_pool
(
scsi_id
);
sbp2util_remove_command_orb_pool
(
scsi_id
);
...
...
drivers/scsi/53c700.c
View file @
5237662f
...
@@ -1065,7 +1065,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
...
@@ -1065,7 +1065,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
DEBUG
((
"scsi%d: (%d:%d) RESELECTED!
\n
"
,
DEBUG
((
"scsi%d: (%d:%d) RESELECTED!
\n
"
,
host
->
host_no
,
reselection_id
,
lun
));
host
->
host_no
,
reselection_id
,
lun
));
/* clear the reselection indicator */
/* 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
))
{
if
(
unlikely
(
SDp
==
NULL
))
{
printk
(
KERN_ERR
"scsi%d: (%d:%d) HAS NO device
\n
"
,
printk
(
KERN_ERR
"scsi%d: (%d:%d) HAS NO device
\n
"
,
host
->
host_no
,
reselection_id
,
lun
);
host
->
host_no
,
reselection_id
,
lun
);
...
@@ -1498,7 +1498,7 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs)
...
@@ -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
);
host
->
host_no
,
SCp
,
SCp
==
NULL
?
NULL
:
SCp
->
host_scribble
,
dsp
,
dsp
-
hostdata
->
pScript
);
/* clear all the negotiated parameters */
/* clear all the negotiated parameters */
list_for_each_entry
(
SDp
,
&
host
->
my_devices
,
siblings
)
__shost_for_each_device
(
SDp
,
host
)
SDp
->
hostdata
=
0
;
SDp
->
hostdata
=
0
;
/* clear all the slots and their pending commands */
/* clear all the slots and their pending commands */
...
...
drivers/scsi/NCR53C9x.c
View file @
5237662f
...
@@ -815,6 +815,7 @@ static int copy_info(struct info_str *info, char *fmt, ...)
...
@@ -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
)
static
int
esp_host_info
(
struct
NCR_ESP
*
esp
,
char
*
ptr
,
off_t
offset
,
int
len
)
{
{
struct
scsi_device
*
sdev
;
struct
info_str
info
;
struct
info_str
info
;
int
i
;
int
i
;
...
@@ -867,23 +868,20 @@ static int esp_host_info(struct NCR_ESP *esp, char *ptr, off_t offset, int len)
...
@@ -867,23 +868,20 @@ static int esp_host_info(struct NCR_ESP *esp, char *ptr, off_t offset, int len)
/* Now describe the state of each existing target. */
/* Now describe the state of each existing target. */
copy_info
(
&
info
,
"Target #
\t
config3
\t\t
Sync Capabilities
\t
Disconnect
\n
"
);
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
,
shost_for_each_device
(
sdev
,
esp
->
ehost
)
{
siblings
)
struct
esp_device
*
esp_dev
=
sdev
->
hostdata
;
if
(
SDptr
->
id
==
i
)
uint
id
=
sdev
->
id
;
break
;
esp_dev
=
SDptr
->
hostdata
;
if
(
!
(
esp
->
targets_present
&
(
1
<<
id
)))
copy_info
(
&
info
,
"%d
\t\t
"
,
i
);
continue
;
copy_info
(
&
info
,
"%08lx
\t
"
,
esp
->
config3
[
i
]);
copy_info
(
&
info
,
"[%02lx,%02lx]
\t\t\t
"
,
esp_dev
->
sync_max_offset
,
copy_info
(
&
info
,
"%d
\t\t
"
,
id
);
esp_dev
->
sync_min_period
);
copy_info
(
&
info
,
"%08lx
\t
"
,
esp
->
config3
[
id
]);
copy_info
(
&
info
,
"%s
\n
"
,
esp_dev
->
disconnect
?
"yes"
:
"no"
);
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
;
return
info
.
pos
>
info
.
offset
?
info
.
pos
-
info
.
offset
:
0
;
...
...
drivers/scsi/arm/acornscsi.c
View file @
5237662f
...
@@ -2930,7 +2930,7 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start,
...
@@ -2930,7 +2930,7 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start,
p
+=
sprintf
(
p
,
"
\n
Attached devices:
\n
"
);
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
,
"Device/Lun TaggedQ Sync
\n
"
);
p
+=
sprintf
(
p
,
" %d/%d "
,
scd
->
id
,
scd
->
lun
);
p
+=
sprintf
(
p
,
" %d/%d "
,
scd
->
id
,
scd
->
lun
);
if
(
scd
->
tagged_supported
)
if
(
scd
->
tagged_supported
)
...
@@ -2953,8 +2953,10 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start,
...
@@ -2953,8 +2953,10 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start,
p
=
buffer
;
p
=
buffer
;
}
}
pos
=
p
-
buffer
;
pos
=
p
-
buffer
;
if
(
pos
+
begin
>
offset
+
length
)
if
(
pos
+
begin
>
offset
+
length
)
{
scsi_device_put
(
scd
);
break
;
break
;
}
}
}
pos
=
p
-
buffer
;
pos
=
p
-
buffer
;
...
...
drivers/scsi/esp.c
View file @
5237662f
...
@@ -1309,6 +1309,7 @@ static int copy_info(struct info_str *info, char *fmt, ...)
...
@@ -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
)
static
int
esp_host_info
(
struct
esp
*
esp
,
char
*
ptr
,
off_t
offset
,
int
len
)
{
{
struct
scsi_device
*
sdev
;
struct
info_str
info
;
struct
info_str
info
;
int
i
;
int
i
;
...
@@ -1384,25 +1385,23 @@ static int esp_host_info(struct esp *esp, char *ptr, off_t offset, int len)
...
@@ -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. */
/* Now describe the state of each existing target. */
copy_info
(
&
info
,
"Target #
\t
config3
\t\t
Sync Capabilities
\t
Disconnect
\t
Wide
\n
"
);
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
))
{
shost_for_each_device
(
sdev
,
esp
->
ehost
)
{
Scsi_Device
*
SDptr
;
struct
esp_device
*
esp_dev
=
sdev
->
hostdata
;
struct
esp_device
*
esp_dev
;
uint
id
=
sdev
->
id
;
list_for_each_entry
(
SDptr
,
&
esp
->
ehost
->
my_devices
,
if
(
!
(
esp
->
targets_present
&
(
1
<<
id
)))
siblings
)
continue
;
if
(
SDptr
->
id
==
i
)
break
;
copy_info
(
&
info
,
"%d
\t\t
"
,
id
);
copy_info
(
&
info
,
"%08lx
\t
"
,
esp
->
config3
[
id
]);
esp_dev
=
SDptr
->
hostdata
;
copy_info
(
&
info
,
"[%02lx,%02lx]
\t\t\t
"
,
copy_info
(
&
info
,
"%d
\t\t
"
,
i
);
esp_dev
->
sync_max_offset
,
copy_info
(
&
info
,
"%08lx
\t
"
,
esp
->
config3
[
i
]);
esp_dev
->
sync_min_period
);
copy_info
(
&
info
,
"[%02lx,%02lx]
\t\t\t
"
,
esp_dev
->
sync_max_offset
,
copy_info
(
&
info
,
"%s
\t\t
"
,
esp_dev
->
sync_min_period
);
esp_dev
->
disconnect
?
"yes"
:
"no"
);
copy_info
(
&
info
,
"%s
\t\t
"
,
esp_dev
->
disconnect
?
"yes"
:
"no"
);
copy_info
(
&
info
,
"%s
\n
"
,
copy_info
(
&
info
,
"%s
\n
"
,
(
esp
->
config3
[
id
]
&
ESP_CONFIG3_EWIDE
)
?
"yes"
:
"no"
);
(
esp
->
config3
[
i
]
&
ESP_CONFIG3_EWIDE
)
?
"yes"
:
"no"
);
}
}
}
return
info
.
pos
>
info
.
offset
?
info
.
pos
-
info
.
offset
:
0
;
return
info
.
pos
>
info
.
offset
?
info
.
pos
-
info
.
offset
:
0
;
}
}
...
...
drivers/scsi/fcal.c
View file @
5237662f
...
@@ -228,7 +228,7 @@ int fcal_proc_info (struct Scsi_Host *host, char *buffer, char **start, off_t of
...
@@ -228,7 +228,7 @@ int fcal_proc_info (struct Scsi_Host *host, char *buffer, char **start, off_t of
#endif
#endif
SPRINTF
(
"Initiator AL-PA: %02x
\n
"
,
fc
->
sid
);
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
++
)
{
for
(
i
=
0
;
i
<
fc
->
posmap
->
len
;
i
++
)
{
unsigned
char
alpa
=
fc
->
posmap
->
list
[
i
];
unsigned
char
alpa
=
fc
->
posmap
->
list
[
i
];
...
...
drivers/scsi/hosts.c
View file @
5237662f
/*
/*
* hosts.c Copyright (C) 1992 Drew Eckhardt
* hosts.c Copyright (C) 1992 Drew Eckhardt
* Copyright (C) 1993, 1994, 1995 Eric Youngdale
* Copyright (C) 1993, 1994, 1995 Eric Youngdale
* Copyright (C) 2002-2003 Christoph Hellwig
*
*
* mid to lowlevel SCSI driver interface
* mid to lowlevel SCSI driver interface
* Initial versions: Drew Eckhardt
* Initial versions: Drew Eckhardt
...
@@ -30,8 +31,8 @@
...
@@ -30,8 +31,8 @@
#include <linux/completion.h>
#include <linux/completion.h>
#include <linux/unistd.h>
#include <linux/unistd.h>
#include <scsi/scsi_host.h>
#include "scsi.h"
#include "scsi.h"
#include "hosts.h"
#include "scsi_priv.h"
#include "scsi_priv.h"
#include "scsi_logging.h"
#include "scsi_logging.h"
...
@@ -50,6 +51,11 @@ static struct class shost_class = {
...
@@ -50,6 +51,11 @@ static struct class shost_class = {
.
release
=
scsi_host_cls_release
,
.
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
* scsi_host_cancel - cancel outstanding IO to this host
* @shost: pointer to struct Scsi_Host
* @shost: pointer to struct Scsi_Host
...
@@ -57,11 +63,7 @@ static struct class shost_class = {
...
@@ -57,11 +63,7 @@ static struct class shost_class = {
**/
**/
void
scsi_host_cancel
(
struct
Scsi_Host
*
shost
,
int
recovery
)
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
);
set_bit
(
SHOST_CANCEL
,
&
shost
->
shost_state
);
spin_unlock_irqrestore
(
shost
->
host_lock
,
flags
);
device_for_each_child
(
&
shost
->
shost_gendev
,
&
recovery
,
device_for_each_child
(
&
shost
->
shost_gendev
,
&
recovery
,
scsi_device_cancel_cb
);
scsi_device_cancel_cb
);
wait_event
(
shost
->
host_wait
,
(
!
test_bit
(
SHOST_RECOVERY
,
wait_event
(
shost
->
host_wait
,
(
!
test_bit
(
SHOST_RECOVERY
,
...
@@ -74,15 +76,11 @@ void scsi_host_cancel(struct Scsi_Host *shost, int recovery)
...
@@ -74,15 +76,11 @@ void scsi_host_cancel(struct Scsi_Host *shost, int recovery)
**/
**/
void
scsi_remove_host
(
struct
Scsi_Host
*
shost
)
void
scsi_remove_host
(
struct
Scsi_Host
*
shost
)
{
{
unsigned
long
flags
;
scsi_host_cancel
(
shost
,
0
);
scsi_host_cancel
(
shost
,
0
);
scsi_proc_host_rm
(
shost
);
scsi_proc_host_rm
(
shost
);
scsi_forget_host
(
shost
);
scsi_forget_host
(
shost
);
spin_lock_irqsave
(
shost
->
host_lock
,
flags
);
set_bit
(
SHOST_DEL
,
&
shost
->
shost_state
);
set_bit
(
SHOST_DEL
,
&
shost
->
shost_state
);
spin_unlock_irqrestore
(
shost
->
host_lock
,
flags
);
class_device_unregister
(
&
shost
->
shost_classdev
);
class_device_unregister
(
&
shost
->
shost_classdev
);
device_del
(
&
shost
->
shost_gendev
);
device_del
(
&
shost
->
shost_gendev
);
...
@@ -209,7 +207,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
...
@@ -209,7 +207,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
spin_lock_init
(
&
shost
->
default_lock
);
spin_lock_init
(
&
shost
->
default_lock
);
scsi_assign_lock
(
shost
,
&
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
->
eh_cmd_q
);
INIT_LIST_HEAD
(
&
shost
->
starved_list
);
INIT_LIST_HEAD
(
&
shost
->
starved_list
);
init_waitqueue_head
(
&
shost
->
host_wait
);
init_waitqueue_head
(
&
shost
->
host_wait
);
...
@@ -323,23 +321,20 @@ void scsi_unregister(struct Scsi_Host *shost)
...
@@ -323,23 +321,20 @@ void scsi_unregister(struct Scsi_Host *shost)
**/
**/
struct
Scsi_Host
*
scsi_host_lookup
(
unsigned
short
hostnum
)
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
class_device
*
cdev
;
struct
Scsi_Host
*
shost
=
ERR_PTR
(
-
ENXIO
),
*
p
;
struct
Scsi_Host
*
shost
=
ERR_PTR
(
-
ENXIO
),
*
p
;
if
(
class
)
{
down_read
(
&
class
->
subsys
.
rwsem
);
down_read
(
&
class
->
subsys
.
rwsem
);
list_for_each_entry
(
cdev
,
&
class
->
children
,
node
)
{
list_for_each_entry
(
cdev
,
&
class
->
children
,
node
)
{
p
=
class_to_shost
(
cdev
);
p
=
class_to_shost
(
cdev
);
if
(
p
->
host_no
==
hostnum
)
{
if
(
p
->
host_no
==
hostnum
)
{
shost
=
scsi_host_get
(
p
);
shost
=
scsi_host_get
(
p
);
break
;
break
;
}
}
}
up_read
(
&
class
->
subsys
.
rwsem
);
}
}
up_read
(
&
class
->
subsys
.
rwsem
);
class_put
(
&
shost_class
);
return
shost
;
return
shost
;
}
}
...
...
drivers/scsi/hosts.h
View file @
5237662f
/*
// #warning "This file is obsolete, please use <scsi/scsi_host.h> instead"
* 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>
#include <scsi/scsi_host.h>
#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 @
5237662f
...
@@ -69,8 +69,9 @@ static Scsi_Host_Template lasi700_template = {
...
@@ -69,8 +69,9 @@ static Scsi_Host_Template lasi700_template = {
.
name
=
"LASI SCSI 53c700"
,
.
name
=
"LASI SCSI 53c700"
,
.
proc_name
=
"lasi700"
,
.
proc_name
=
"lasi700"
,
.
this_id
=
7
,
.
this_id
=
7
,
.
module
=
THIS_MODULE
,
};
};
MODULE_DEVICE_TABLE
(
parisc
,
lasi700_
scsi_tbl
);
MODULE_DEVICE_TABLE
(
parisc
,
lasi700_
ids
);
static
int
__init
static
int
__init
lasi700_probe
(
struct
parisc_device
*
dev
)
lasi700_probe
(
struct
parisc_device
*
dev
)
...
...
drivers/scsi/scsi.c
View file @
5237662f
/*
/*
* scsi.c Copyright (C) 1992 Drew Eckhardt
* scsi.c Copyright (C) 1992 Drew Eckhardt
* Copyright (C) 1993, 1994, 1995, 1999 Eric Youngdale
* Copyright (C) 1993, 1994, 1995, 1999 Eric Youngdale
* Copyright (C) 2002, 2003 Christoph Hellwig
*
*
* generic mid-level SCSI driver
* generic mid-level SCSI driver
* Initial versions: Drew Eckhardt
* Initial versions: Drew Eckhardt
...
@@ -36,7 +37,6 @@
...
@@ -36,7 +37,6 @@
* out_of_space hacks, D. Gilbert (dpg) 990608
* out_of_space hacks, D. Gilbert (dpg) 990608
*/
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
...
@@ -54,8 +54,8 @@
...
@@ -54,8 +54,8 @@
#include <linux/kmod.h>
#include <linux/kmod.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <scsi/scsi_host.h>
#include "scsi.h"
#include "scsi.h"
#include "hosts.h"
#include "scsi_priv.h"
#include "scsi_priv.h"
#include "scsi_logging.h"
#include "scsi_logging.h"
...
@@ -883,49 +883,124 @@ int scsi_track_queue_full(struct scsi_device *sdev, int depth)
...
@@ -883,49 +883,124 @@ int scsi_track_queue_full(struct scsi_device *sdev, int depth)
return
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
)
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
))
if
(
test_bit
(
SDEV_DEL
,
&
sdev
->
sdev_state
))
goto
out
;
return
-
ENXIO
;
if
(
!
try_module_get
(
sdev
->
host
->
hostt
->
module
))
goto
out
;
if
(
!
get_device
(
&
sdev
->
sdev_gendev
))
if
(
!
get_device
(
&
sdev
->
sdev_gendev
))
goto
out_put_module
;
return
-
ENXIO
;
atomic_inc
(
&
sdev
->
access_count
);
if
(
!
try_module_get
(
sdev
->
host
->
hostt
->
module
))
{
class_put
(
&
sdev_class
);
put_device
(
&
sdev
->
sdev_gendev
);
return
-
ENXIO
;
}
return
0
;
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
);
module_put
(
sdev
->
host
->
hostt
->
module
);
out:
put_device
(
&
sdev
->
sdev_gendev
);
class_put
(
&
sdev_class
);
return
-
ENXIO
;
}
}
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
)
spin_lock_irqsave
(
shost
->
host_lock
,
flags
);
return
;
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
);
if
(
prev
)
atomic_dec
(
&
sdev
->
access_count
);
scsi_device_put
(
prev
);
put_device
(
&
sdev
->
sdev_gendev
);
return
next
;
class_put
(
&
sdev_class
);
}
}
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
);
struct
scsi_device
*
sdev
;
int
recovery
=
*
(
int
*
)
data
;
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
* scsi_device_cancel - cancel outstanding IO to this device
...
...
drivers/scsi/scsi_lib.c
View file @
5237662f
...
@@ -16,9 +16,9 @@
...
@@ -16,9 +16,9 @@
#include <linux/init.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/pci.h>
#include "scsi.h"
#include "hosts.h"
#include <scsi/scsi_driver.h>
#include <scsi/scsi_driver.h>
#include <scsi/scsi_host.h>
#include "scsi.h"
#include "scsi_priv.h"
#include "scsi_priv.h"
#include "scsi_logging.h"
#include "scsi_logging.h"
...
@@ -335,13 +335,14 @@ void scsi_device_unbusy(struct scsi_device *sdev)
...
@@ -335,13 +335,14 @@ void scsi_device_unbusy(struct scsi_device *sdev)
*/
*/
static
void
scsi_single_lun_run
(
struct
scsi_device
*
current_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
;
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
);
WARN_ON
(
!
current_sdev
->
sdev_target
->
starget_sdev_user
);
current_sdev
->
sdev_target
->
starget_sdev_user
=
NULL
;
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
* 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)
...
@@ -351,21 +352,26 @@ static void scsi_single_lun_run(struct scsi_device *current_sdev)
*/
*/
blk_run_queue
(
current_sdev
->
request_queue
);
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 always enter this function again, avoiding any problems.
* After unlock, this races with anyone clearing
*/
* starget_sdev_user, but we (should) always enter this
spin_lock_irqsave
(
shost
->
host_lock
,
flags
);
* function again, avoiding any problems.
if
(
current_sdev
->
sdev_target
->
starget_sdev_user
)
*/
goto
out
;
spin_unlock_irqrestore
(
current_sdev
->
host
->
host_lock
,
flags
);
list_for_each_entry_safe
(
sdev
,
tmp
,
&
current_sdev
->
same_target_siblings
,
return
;
same_target_siblings
)
{
}
if
(
scsi_device_get
(
sdev
))
spin_unlock_irqrestore
(
current_sdev
->
host
->
host_lock
,
flags
)
;
continue
;
list_for_each_entry
(
sdev
,
&
current_sdev
->
same_target_siblings
,
spin_unlock_irqrestore
(
shost
->
host_lock
,
flags
);
same_target_siblings
)
blk_run_queue
(
sdev
->
request_queue
);
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 @
5237662f
...
@@ -27,8 +27,8 @@
...
@@ -27,8 +27,8 @@
#include <linux/seq_file.h>
#include <linux/seq_file.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#include <scsi/scsi_host.h>
#include "scsi.h"
#include "scsi.h"
#include "hosts.h"
#include "scsi_priv.h"
#include "scsi_priv.h"
#include "scsi_logging.h"
#include "scsi_logging.h"
...
@@ -212,15 +212,13 @@ static int scsi_remove_single_device(uint host, uint channel, uint id, uint lun)
...
@@ -212,15 +212,13 @@ static int scsi_remove_single_device(uint host, uint channel, uint id, uint lun)
shost
=
scsi_host_lookup
(
host
);
shost
=
scsi_host_lookup
(
host
);
if
(
IS_ERR
(
shost
))
if
(
IS_ERR
(
shost
))
return
PTR_ERR
(
shost
);
return
PTR_ERR
(
shost
);
sdev
=
scsi_find_device
(
shost
,
channel
,
id
,
lun
);
sdev
=
scsi_device_lookup
(
shost
,
channel
,
id
,
lun
);
if
(
!
sdev
)
if
(
sdev
)
{
goto
out
;
scsi_remove_device
(
sdev
);
if
(
atomic_read
(
&
sdev
->
access_count
))
scsi_device_put
(
sdev
);
goto
out
;
error
=
0
;
}
scsi_remove_device
(
sdev
);
error
=
0
;
out:
scsi_host_put
(
shost
);
scsi_host_put
(
shost
);
return
error
;
return
error
;
}
}
...
...
drivers/scsi/scsi_scan.c
View file @
5237662f
...
@@ -32,10 +32,10 @@
...
@@ -32,10 +32,10 @@
#include <linux/blkdev.h>
#include <linux/blkdev.h>
#include <asm/semaphore.h>
#include <asm/semaphore.h>
#include "scsi.h"
#include "hosts.h"
#include <scsi/scsi_driver.h>
#include <scsi/scsi_driver.h>
#include <scsi/scsi_devinfo.h>
#include <scsi/scsi_devinfo.h>
#include <scsi/scsi_host.h>
#include "scsi.h"
#include "scsi_priv.h"
#include "scsi_priv.h"
#include "scsi_logging.h"
#include "scsi_logging.h"
...
@@ -190,13 +190,13 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
...
@@ -190,13 +190,13 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
uint
channel
,
uint
id
,
uint
lun
)
uint
channel
,
uint
id
,
uint
lun
)
{
{
struct
scsi_device
*
sdev
,
*
device
;
struct
scsi_device
*
sdev
,
*
device
;
unsigned
long
flags
;
sdev
=
kmalloc
(
sizeof
(
*
sdev
),
GFP_ATOMIC
);
sdev
=
kmalloc
(
sizeof
(
*
sdev
),
GFP_ATOMIC
);
if
(
!
sdev
)
if
(
!
sdev
)
goto
out
;
goto
out
;
memset
(
sdev
,
0
,
sizeof
(
*
sdev
));
memset
(
sdev
,
0
,
sizeof
(
*
sdev
));
atomic_set
(
&
sdev
->
access_count
,
0
);
sdev
->
vendor
=
scsi_null_device_strs
;
sdev
->
vendor
=
scsi_null_device_strs
;
sdev
->
model
=
scsi_null_device_strs
;
sdev
->
model
=
scsi_null_device_strs
;
sdev
->
rev
=
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,
...
@@ -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
* If there are any same target siblings, add this to the
* sibling list
* 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
&&
if
(
device
->
id
==
sdev
->
id
&&
device
->
channel
==
sdev
->
channel
)
{
device
->
channel
==
sdev
->
channel
)
{
list_add_tail
(
&
sdev
->
same_target_siblings
,
list_add_tail
(
&
sdev
->
same_target_siblings
,
...
@@ -258,10 +259,8 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
...
@@ -258,10 +259,8 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
if
(
!
sdev
->
scsi_level
)
if
(
!
sdev
->
scsi_level
)
sdev
->
scsi_level
=
SCSI_2
;
sdev
->
scsi_level
=
SCSI_2
;
/*
list_add_tail
(
&
sdev
->
siblings
,
&
shost
->
__devices
);
* Add it to the end of the shost->my_devices list.
spin_unlock_irqrestore
(
shost
->
host_lock
,
flags
);
*/
list_add_tail
(
&
sdev
->
siblings
,
&
shost
->
my_devices
);
return
sdev
;
return
sdev
;
out_free_queue:
out_free_queue:
...
@@ -285,21 +284,21 @@ void scsi_free_sdev(struct scsi_device *sdev)
...
@@ -285,21 +284,21 @@ void scsi_free_sdev(struct scsi_device *sdev)
{
{
unsigned
long
flags
;
unsigned
long
flags
;
spin_lock_irqsave
(
sdev
->
host
->
host_lock
,
flags
);
list_del
(
&
sdev
->
siblings
);
list_del
(
&
sdev
->
siblings
);
list_del
(
&
sdev
->
same_target_siblings
);
list_del
(
&
sdev
->
same_target_siblings
);
spin_unlock_irqrestore
(
sdev
->
host
->
host_lock
,
flags
);
if
(
sdev
->
request_queue
)
if
(
sdev
->
request_queue
)
scsi_free_queue
(
sdev
->
request_queue
);
scsi_free_queue
(
sdev
->
request_queue
);
if
(
sdev
->
inquiry
)
kfree
(
sdev
->
inquiry
);
spin_lock_irqsave
(
sdev
->
host
->
host_lock
,
flags
);
spin_lock_irqsave
(
sdev
->
host
->
host_lock
,
flags
);
list_del
(
&
sdev
->
starved_entry
);
list_del
(
&
sdev
->
starved_entry
);
if
(
sdev
->
single_lun
)
{
if
(
sdev
->
single_lun
&&
--
sdev
->
sdev_target
->
starget_refcnt
==
0
)
if
(
--
sdev
->
sdev_target
->
starget_refcnt
==
0
)
kfree
(
sdev
->
sdev_target
);
kfree
(
sdev
->
sdev_target
);
}
spin_unlock_irqrestore
(
sdev
->
host
->
host_lock
,
flags
);
spin_unlock_irqrestore
(
sdev
->
host
->
host_lock
,
flags
);
kfree
(
sdev
->
inquiry
);
kfree
(
sdev
);
kfree
(
sdev
);
}
}
...
@@ -678,7 +677,7 @@ static int scsi_probe_and_add_lun(struct Scsi_Host *host,
...
@@ -678,7 +677,7 @@ static int scsi_probe_and_add_lun(struct Scsi_Host *host,
* host adapter calls into here with rescan == 0.
* host adapter calls into here with rescan == 0.
*/
*/
if
(
rescan
)
{
if
(
rescan
)
{
sdev
=
scsi_
find_device
(
host
,
channel
,
id
,
lun
);
sdev
=
scsi_
device_lookup
(
host
,
channel
,
id
,
lun
);
if
(
sdev
)
{
if
(
sdev
)
{
SCSI_LOG_SCAN_BUS
(
3
,
printk
(
KERN_INFO
SCSI_LOG_SCAN_BUS
(
3
,
printk
(
KERN_INFO
"scsi scan: device exists on <%d:%d:%d:%d>
\n
"
,
"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,
...
@@ -689,6 +688,8 @@ static int scsi_probe_and_add_lun(struct Scsi_Host *host,
*
bflagsp
=
scsi_get_device_flags
(
sdev
,
*
bflagsp
=
scsi_get_device_flags
(
sdev
,
sdev
->
vendor
,
sdev
->
vendor
,
sdev
->
model
);
sdev
->
model
);
/* XXX: bandaid until callers do refcounting */
scsi_device_put
(
sdev
);
return
SCSI_SCAN_LUN_PRESENT
;
return
SCSI_SCAN_LUN_PRESENT
;
}
}
}
}
...
@@ -1232,14 +1233,25 @@ void scsi_scan_host(struct Scsi_Host *shost)
...
@@ -1232,14 +1233,25 @@ void scsi_scan_host(struct Scsi_Host *shost)
void
scsi_forget_host
(
struct
Scsi_Host
*
shost
)
void
scsi_forget_host
(
struct
Scsi_Host
*
shost
)
{
{
struct
list_head
*
le
,
*
lh
;
struct
scsi_device
*
sdev
,
*
tmp
;
struct
scsi_device
*
sdev
;
unsigned
long
flags
;
list_for_each_safe
(
le
,
lh
,
&
shost
->
my_devices
)
{
/*
sdev
=
list_entry
(
le
,
struct
scsi_device
,
siblings
);
* 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
);
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 @
5237662f
...
@@ -18,13 +18,14 @@
...
@@ -18,13 +18,14 @@
#include <asm/irq.h>
#include <asm/irq.h>
#include <asm/dma.h>
#include <asm/dma.h>
#include "scsi.h"
#include <scsi/scsi_driver.h>
#include <scsi/scsi_driver.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_ioctl.h>
#include <scsi/scsi_ioctl.h>
#include "hosts.h"
#include <scsi/scsicam.h>
#include "scsi.h"
#include "scsi_logging.h"
#include "scsi_logging.h"
#include <scsi/scsicam.h>
/*
/*
* This source file contains the symbol table used by scsi loadable
* This source file contains the symbol table used by scsi loadable
...
@@ -82,8 +83,6 @@ EXPORT_SYMBOL(scsi_sleep);
...
@@ -82,8 +83,6 @@ EXPORT_SYMBOL(scsi_sleep);
EXPORT_SYMBOL
(
scsi_io_completion
);
EXPORT_SYMBOL
(
scsi_io_completion
);
EXPORT_SYMBOL
(
scsi_device_get
);
EXPORT_SYMBOL
(
scsi_device_put
);
EXPORT_SYMBOL
(
scsi_add_device
);
EXPORT_SYMBOL
(
scsi_add_device
);
EXPORT_SYMBOL
(
scsi_remove_device
);
EXPORT_SYMBOL
(
scsi_remove_device
);
EXPORT_SYMBOL
(
scsi_device_cancel
);
EXPORT_SYMBOL
(
scsi_device_cancel
);
...
...
drivers/scsi/scsi_sysfs.c
View file @
5237662f
...
@@ -11,8 +11,9 @@
...
@@ -11,8 +11,9 @@
#include <linux/init.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/blkdev.h>
#include <linux/device.h>
#include <linux/device.h>
#include <scsi/scsi_host.h>
#include "scsi.h"
#include "scsi.h"
#include "hosts.h"
#include "scsi_priv.h"
#include "scsi_priv.h"
#include "scsi_logging.h"
#include "scsi_logging.h"
...
@@ -257,20 +258,12 @@ store_rescan_field (struct device *dev, const char *buf, size_t count)
...
@@ -257,20 +258,12 @@ store_rescan_field (struct device *dev, const char *buf, size_t count)
scsi_rescan_device
(
dev
);
scsi_rescan_device
(
dev
);
return
count
;
return
count
;
}
}
static
DEVICE_ATTR
(
rescan
,
S_IWUSR
,
NULL
,
store_rescan_field
)
static
DEVICE_ATTR
(
rescan
,
S_IWUSR
,
NULL
,
store_rescan_field
)
static
ssize_t
sdev_store_delete
(
struct
device
*
dev
,
const
char
*
buf
,
static
ssize_t
sdev_store_delete
(
struct
device
*
dev
,
const
char
*
buf
,
size_t
count
)
size_t
count
)
{
{
struct
scsi_device
*
sdev
=
to_scsi_device
(
dev
);
scsi_remove_device
(
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
);
return
count
;
return
count
;
};
};
static
DEVICE_ATTR
(
delete
,
S_IWUSR
,
NULL
,
sdev_store_delete
);
static
DEVICE_ATTR
(
delete
,
S_IWUSR
,
NULL
,
sdev_store_delete
);
...
@@ -403,22 +396,12 @@ int scsi_device_register(struct scsi_device *sdev)
...
@@ -403,22 +396,12 @@ int scsi_device_register(struct scsi_device *sdev)
**/
**/
void
scsi_remove_device
(
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
);
class_device_unregister
(
&
sdev
->
sdev_classdev
);
set_bit
(
SDEV_DEL
,
&
sdev
->
sdev_state
);
if
(
class
)
{
if
(
sdev
->
host
->
hostt
->
slave_destroy
)
down_write
(
&
class
->
subsys
.
rwsem
);
sdev
->
host
->
hostt
->
slave_destroy
(
sdev
);
set_bit
(
SDEV_DEL
,
&
sdev
->
sdev_state
);
device_del
(
&
sdev
->
sdev_gendev
);
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
);
put_device
(
&
sdev
->
sdev_gendev
);
class_put
(
&
sdev_class
);
}
}
int
scsi_register_driver
(
struct
device_driver
*
drv
)
int
scsi_register_driver
(
struct
device_driver
*
drv
)
...
...
drivers/scsi/sg.c
View file @
5237662f
...
@@ -914,7 +914,8 @@ sg_ioctl(struct inode *inode, struct file *filp,
...
@@ -914,7 +914,8 @@ sg_ioctl(struct inode *inode, struct file *filp,
case
SG_GET_VERSION_NUM
:
case
SG_GET_VERSION_NUM
:
return
put_user
(
sg_version_num
,
(
int
*
)
arg
);
return
put_user
(
sg_version_num
,
(
int
*
)
arg
);
case
SG_GET_ACCESS_COUNT
:
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
);
return
put_user
(
val
,
(
int
*
)
arg
);
case
SG_GET_REQUEST_TABLE
:
case
SG_GET_REQUEST_TABLE
:
result
=
verify_area
(
VERIFY_WRITE
,
(
void
*
)
arg
,
result
=
verify_area
(
VERIFY_WRITE
,
(
void
*
)
arg
,
...
@@ -1627,7 +1628,7 @@ st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
...
@@ -1627,7 +1628,7 @@ st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
unsigned
int
nr_pages
;
unsigned
int
nr_pages
;
struct
page
**
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! */
/* User attempted Overflow! */
if
((
uaddr
+
count
)
<
uaddr
)
if
((
uaddr
+
count
)
<
uaddr
)
...
@@ -2903,7 +2904,7 @@ sg_proc_dev_info(char *buffer, int *len, off_t * begin, off_t offset, int size)
...
@@ -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
"
,
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
->
host
->
host_no
,
scsidp
->
channel
,
scsidp
->
id
,
scsidp
->
lun
,
(
int
)
scsidp
->
type
,
scsidp
->
id
,
scsidp
->
lun
,
(
int
)
scsidp
->
type
,
(
int
)
atomic_read
(
&
scsidp
->
access_count
)
,
1
,
(
int
)
scsidp
->
queue_depth
,
(
int
)
scsidp
->
queue_depth
,
(
int
)
scsidp
->
device_busy
,
(
int
)
scsidp
->
device_busy
,
(
int
)
scsidp
->
online
);
(
int
)
scsidp
->
online
);
...
...
drivers/scsi/sim710.c
View file @
5237662f
...
@@ -90,6 +90,7 @@ static Scsi_Host_Template sim710_driver_template = {
...
@@ -90,6 +90,7 @@ static Scsi_Host_Template sim710_driver_template = {
.
name
=
"LSI (Symbios) 710 MCA/EISA"
,
.
name
=
"LSI (Symbios) 710 MCA/EISA"
,
.
proc_name
=
"sim710"
,
.
proc_name
=
"sim710"
,
.
this_id
=
7
,
.
this_id
=
7
,
.
module
=
THIS_MODULE
,
};
};
static
__devinit
int
static
__devinit
int
...
...
drivers/scsi/st.c
View file @
5237662f
...
@@ -4036,7 +4036,7 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa
...
@@ -4036,7 +4036,7 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa
unsigned
int
nr_pages
;
unsigned
int
nr_pages
;
struct
page
**
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! */
/* User attempted Overflow! */
if
((
uaddr
+
count
)
<
uaddr
)
if
((
uaddr
+
count
)
<
uaddr
)
...
...
include/scsi/scsi_device.h
View file @
5237662f
...
@@ -22,10 +22,13 @@ enum {
...
@@ -22,10 +22,13 @@ enum {
};
};
struct
scsi_device
{
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
Scsi_Host
*
host
;
struct
request_queue
*
request_queue
;
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 */
volatile
unsigned
short
device_busy
;
/* commands actually active on low-level */
spinlock_t
sdev_lock
;
/* also the request queue_lock */
spinlock_t
sdev_lock
;
/* also the request queue_lock */
spinlock_t
list_lock
;
spinlock_t
list_lock
;
...
@@ -45,8 +48,6 @@ struct scsi_device {
...
@@ -45,8 +48,6 @@ struct scsi_device {
* vendor-specific cmd's */
* vendor-specific cmd's */
unsigned
sector_size
;
/* size in bytes */
unsigned
sector_size
;
/* size in bytes */
atomic_t
access_count
;
/* Count of open channels/mounts */
void
*
hostdata
;
/* available to low-level driver */
void
*
hostdata
;
/* available to low-level driver */
char
devfs_name
[
256
];
/* devfs junk */
char
devfs_name
[
256
];
/* devfs junk */
char
type
;
char
type
;
...
@@ -108,14 +109,48 @@ struct scsi_device {
...
@@ -108,14 +109,48 @@ struct scsi_device {
extern
struct
scsi_device
*
scsi_add_device
(
struct
Scsi_Host
*
,
extern
struct
scsi_device
*
scsi_add_device
(
struct
Scsi_Host
*
,
uint
,
uint
,
uint
);
uint
,
uint
,
uint
);
extern
void
scsi_remove_device
(
struct
scsi_device
*
);
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_cancel
(
struct
scsi_device
*
,
int
);
extern
int
scsi_device_get
(
struct
scsi_device
*
);
extern
int
scsi_device_get
(
struct
scsi_device
*
);
extern
void
scsi_device_put
(
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) \
#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
void
scsi_adjust_queue_depth
(
struct
scsi_device
*
,
int
,
int
);
extern
int
scsi_track_queue_full
(
struct
scsi_device
*
,
int
);
extern
int
scsi_track_queue_full
(
struct
scsi_device
*
,
int
);
...
...
include/scsi/scsi_driver.h
View file @
5237662f
...
@@ -4,6 +4,7 @@
...
@@ -4,6 +4,7 @@
#include <linux/device.h>
#include <linux/device.h>
struct
module
;
struct
module
;
struct
scsi_cmnd
;
struct
scsi_driver
{
struct
scsi_driver
{
...
...
include/scsi/scsi_host.h
View file @
5237662f
...
@@ -363,19 +363,30 @@ enum {
...
@@ -363,19 +363,30 @@ enum {
};
};
struct
Scsi_Host
{
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
;
struct
scsi_host_cmd_pool
*
cmd_pool
;
spinlock_t
free_list_lock
;
spinlock_t
free_list_lock
;
struct
list_head
free_list
;
/* backup store of cmd structs */
struct
list_head
free_list
;
/* backup store of cmd structs */
struct
list_head
starved_list
;
struct
list_head
starved_list
;
spinlock_t
default_lock
;
spinlock_t
default_lock
;
spinlock_t
*
host_lock
;
spinlock_t
*
host_lock
;
struct
semaphore
scan_mutex
;
/* serialize scanning activity */
struct
list_head
eh_cmd_q
;
struct
list_head
eh_cmd_q
;
struct
task_struct
*
ehandler
;
/* Error recovery thread. */
struct
task_struct
*
ehandler
;
/* Error recovery thread. */
struct
semaphore
*
eh_wait
;
/* The error recovery thread waits
on
struct
semaphore
*
eh_wait
;
/* The error recovery thread waits
this. */
on
this. */
struct
completion
*
eh_notify
;
/* wait for eh to begin or end */
struct
completion
*
eh_notify
;
/* wait for eh to begin or end */
struct
semaphore
*
eh_action
;
/* Wait for specific actions on the
struct
semaphore
*
eh_action
;
/* Wait for specific actions on the
host. */
host. */
...
@@ -478,12 +489,6 @@ struct Scsi_Host {
...
@@ -478,12 +489,6 @@ struct Scsi_Host {
*/
*/
struct
list_head
sht_legacy_list
;
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
* We should ensure that this is aligned, both for better performance
* and also because some compilers (m68k) don't automatically force
* 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