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
ab2d582d
Commit
ab2d582d
authored
Aug 17, 2003
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge SCSI update
parents
08f34001
bede2c88
Changes
25
Show whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
5893 additions
and
5515 deletions
+5893
-5515
drivers/scsi/dc395x.c
drivers/scsi/dc395x.c
+329
-379
drivers/scsi/hosts.c
drivers/scsi/hosts.c
+74
-11
drivers/scsi/ips.c
drivers/scsi/ips.c
+5168
-4835
drivers/scsi/ips.h
drivers/scsi/ips.h
+41
-39
drivers/scsi/lasi700.c
drivers/scsi/lasi700.c
+3
-7
drivers/scsi/pcmcia/aha152x_stub.c
drivers/scsi/pcmcia/aha152x_stub.c
+1
-9
drivers/scsi/pcmcia/fdomain_stub.c
drivers/scsi/pcmcia/fdomain_stub.c
+2
-9
drivers/scsi/pcmcia/nsp_cs.c
drivers/scsi/pcmcia/nsp_cs.c
+3
-24
drivers/scsi/pcmcia/qlogic_stub.c
drivers/scsi/pcmcia/qlogic_stub.c
+2
-9
drivers/scsi/ppa.c
drivers/scsi/ppa.c
+1
-0
drivers/scsi/qla1280.c
drivers/scsi/qla1280.c
+20
-10
drivers/scsi/qla1280.h
drivers/scsi/qla1280.h
+4
-2
drivers/scsi/scsi.c
drivers/scsi/scsi.c
+7
-1
drivers/scsi/scsi_error.c
drivers/scsi/scsi_error.c
+6
-1
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_lib.c
+15
-7
drivers/scsi/scsi_priv.h
drivers/scsi/scsi_priv.h
+12
-5
drivers/scsi/scsi_proc.c
drivers/scsi/scsi_proc.c
+7
-9
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_scan.c
+88
-38
drivers/scsi/scsi_sysfs.c
drivers/scsi/scsi_sysfs.c
+80
-94
drivers/scsi/sd.c
drivers/scsi/sd.c
+7
-1
drivers/scsi/sr.c
drivers/scsi/sr.c
+18
-13
drivers/scsi/sym53c8xx_2/sym_glue.c
drivers/scsi/sym53c8xx_2/sym_glue.c
+1
-1
drivers/scsi/sym53c8xx_2/sym_hipd.c
drivers/scsi/sym53c8xx_2/sym_hipd.c
+0
-7
drivers/scsi/zalon.c
drivers/scsi/zalon.c
+2
-4
include/scsi/scsi.h
include/scsi/scsi.h
+2
-0
No files found.
drivers/scsi/dc395x.c
View file @
ab2d582d
...
...
@@ -60,6 +60,7 @@
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/pci.h>
#include <linux/list.h>
/*---------------------------------------------------------------------------
Features
...
...
@@ -306,7 +307,7 @@ struct NvRamType {
SCSI Request Block
-----------------------------------------------------------------------*/
struct
ScsiReqBlk
{
struct
ScsiReqBlk
*
next
;
struct
list_head
list
;
/* next/prev ptrs for srb lists */
struct
DeviceCtlBlk
*
dcb
;
/* HW scatter list (up to 64 entries) */
...
...
@@ -350,22 +351,16 @@ struct ScsiReqBlk {
Device Control Block
-----------------------------------------------------------------------*/
struct
DeviceCtlBlk
{
struct
DeviceCtlBlk
*
next
;
struct
list_head
list
;
/* next/prev ptrs for the dcb list */
struct
AdapterCtlBlk
*
acb
;
struct
ScsiReqBlk
*
going_srb
;
struct
ScsiReqBlk
*
going_last
;
struct
ScsiReqBlk
*
waiting_srb
;
struct
ScsiReqBlk
*
wait_list
;
struct
list_head
srb_going_list
;
/* head of going srb list */
struct
list_head
srb_waiting_list
;
/* head of waiting srb list */
struct
ScsiReqBlk
*
active_srb
;
u32
tag_mask
;
u16
max_command
;
u16
going_srb_count
;
u16
waiting_srb_count
;
u8
target_id
;
/* SCSI Target ID (SCSI Only) */
u8
target_lun
;
/* SCSI Log. Unit (SCSI Only) */
u8
identify_msg
;
...
...
@@ -390,20 +385,17 @@ struct AdapterCtlBlk {
u16
IOPortBase
;
struct
DeviceCtlBlk
*
link_dcb
;
struct
DeviceCtlBlk
*
last_dcb
;
struct
list_head
dcb_list
;
/* head of going dcb list */
struct
DeviceCtlBlk
*
dcb_run_robin
;
struct
DeviceCtlBlk
*
active_dcb
;
struct
ScsiReqBlk
*
free_srb
;
struct
list_head
srb_free_list
;
/* head of free srb list */
struct
ScsiReqBlk
*
tmp_srb
;
struct
timer_list
waiting_timer
;
struct
timer_list
selto_timer
;
u16
srb_count
;
u8
dcb_count
;
u8
sel_timeout
;
u8
irq_level
;
...
...
@@ -824,6 +816,60 @@ void __init eeprom_override(struct NvRamType *eeprom)
/*---------------------------------------------------------------------------
---------------------------------------------------------------------------*/
/**
* list_size - Returns the size (in number of entries) of the
* supplied list.
*
* @head: The pointer to the head of the list to count the items in.
**/
unsigned
int
list_size
(
struct
list_head
*
head
)
{
unsigned
int
count
=
0
;
struct
list_head
*
pos
;
list_for_each
(
pos
,
head
)
count
++
;
return
count
;
}
/**
* dcb_get_next - Given a dcb return the next dcb in the list of
* dcb's, wrapping back to the start of the dcb list if required.
* Returns the supplied dcb if there is only one dcb in the list.
*
* @head: The pointer to the head of the list to count the items in.
* @pos: The pointer the dcb for which we are searching for the
* following dcb.
**/
struct
DeviceCtlBlk
*
dcb_get_next
(
struct
list_head
*
head
,
struct
DeviceCtlBlk
*
pos
)
{
int
use_next
=
0
;
struct
DeviceCtlBlk
*
next
=
NULL
;
struct
DeviceCtlBlk
*
i
;
if
(
list_empty
(
head
))
return
NULL
;
/* find supplied dcb and then select the next one */
list_for_each_entry
(
i
,
head
,
list
)
if
(
use_next
)
{
next
=
i
;
break
;
}
else
if
(
i
==
pos
)
{
use_next
=
1
;
}
/* if no next one take the head one (ie, wraparound) */
if
(
!
next
)
list_for_each_entry
(
i
,
head
,
list
)
{
next
=
i
;
break
;
}
return
next
;
}
/*
* Queueing philosphy:
...
...
@@ -851,200 +897,153 @@ void free_tag(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb)
/* Find cmd in SRB list */
inline
static
struct
ScsiReqBlk
*
find_cmd
(
Scsi_Cmnd
*
cmd
,
struct
ScsiReqBlk
*
start
)
struct
ScsiReqBlk
*
find_cmd
(
Scsi_Cmnd
*
cmd
,
struct
list_head
*
head
)
{
struct
ScsiReqBlk
*
psrb
=
start
;
if
(
!
start
)
return
0
;
do
{
if
(
psrb
->
cmd
==
cmd
)
return
psrb
;
psrb
=
psrb
->
next
;
}
while
(
psrb
&&
psrb
!=
start
);
return
0
;
struct
ScsiReqBlk
*
i
;
list_for_each_entry
(
i
,
head
,
list
)
if
(
i
->
cmd
==
cmd
)
return
i
;
return
NULL
;
}
/* Return next free SRB */
static
inline
struct
ScsiReqBlk
*
get_srb_free
(
struct
AdapterCtlBlk
*
acb
)
/*
* srb_get_free - Return a free srb from the list of free SRBs that
* is stored with the acb.
*/
static
struct
ScsiReqBlk
*
srb_get_free
(
struct
AdapterCtlBlk
*
acb
)
{
struct
list_head
*
head
=
&
acb
->
srb_free_list
;
struct
ScsiReqBlk
*
srb
;
/*DC395x_Free_integrity (acb); */
srb
=
acb
->
free_srb
;
if
(
!
srb
)
if
(
!
list_empty
(
head
))
{
srb
=
list_entry
(
head
->
next
,
struct
ScsiReqBlk
,
list
);
list_del
(
head
->
next
);
dprintkdbg
(
DBG_0
,
"srb_get_free: got srb %p
\n
"
,
srb
);
}
else
{
srb
=
NULL
;
dprintkl
(
KERN_ERR
,
"Out of Free SRBs :-(
\n
"
);
if
(
srb
)
{
acb
->
free_srb
=
srb
->
next
;
srb
->
next
=
NULL
;
}
return
srb
;
}
/* Insert SRB oin top of free list */
static
inline
void
insert_srb_free
(
struct
AdapterCtlBlk
*
acb
,
struct
ScsiReqBlk
*
srb
)
/*
* srb_free_insert - Insert an srb to the head of the free list
* stored in the acb.
*/
static
void
srb_free_insert
(
struct
AdapterCtlBlk
*
acb
,
struct
ScsiReqBlk
*
srb
)
{
dprintkdbg
(
DBG_0
,
"Free SRB %p
\n
"
,
srb
);
srb
->
next
=
acb
->
free_srb
;
acb
->
free_srb
=
srb
;
dprintkdbg
(
DBG_0
,
"srb_free_insert: put srb %p
\n
"
,
srb
);
list_add_tail
(
&
srb
->
list
,
&
acb
->
srb_free_list
);
}
/* Inserts a SRB to the top of the Waiting list */
static
inline
void
insert_srb_waiting
(
struct
DeviceCtlBlk
*
dcb
,
struct
ScsiReqBlk
*
srb
)
/*
* srb_waiting_insert - Insert an srb to the head of the wiating list
* stored in the dcb.
*/
static
void
srb_waiting_insert
(
struct
DeviceCtlBlk
*
dcb
,
struct
ScsiReqBlk
*
srb
)
{
dprintkdbg
(
DBG_0
,
"Insert srb %p cmd %li to Waiting
\n
"
,
srb
,
srb
->
cmd
->
pid
);
srb
->
next
=
dcb
->
waiting_srb
;
if
(
!
dcb
->
waiting_srb
)
dcb
->
wait_list
=
srb
;
dcb
->
waiting_srb
=
srb
;
dcb
->
waiting_srb_count
++
;
dprintkdbg
(
DBG_0
,
"srb_waiting_insert: srb %p cmd %li
\n
"
,
srb
,
srb
->
cmd
->
pid
);
list_add
(
&
srb
->
list
,
&
dcb
->
srb_waiting_list
);
}
/* Queue SRB to waiting list */
/*
* srb_waiting_append - Append an srb to the tail of the waiting list
* stored in the dcb.
*/
static
inline
void
append_srb_waiting
(
struct
DeviceCtlBlk
*
dcb
,
struct
ScsiReqBlk
*
srb
)
void
srb_waiting_append
(
struct
DeviceCtlBlk
*
dcb
,
struct
ScsiReqBlk
*
srb
)
{
dprintkdbg
(
DBG_0
,
"Append srb %p cmd %li to Waiting
\n
"
,
srb
,
srb
->
cmd
->
pid
);
if
(
dcb
->
waiting_srb
)
dcb
->
wait_list
->
next
=
srb
;
else
dcb
->
waiting_srb
=
srb
;
dcb
->
wait_list
=
srb
;
/* No next one in waiting list */
srb
->
next
=
NULL
;
dcb
->
waiting_srb_count
++
;
dprintkdbg
(
DBG_0
,
"srb_waiting_append: srb %p cmd %li
\n
"
,
srb
,
srb
->
cmd
->
pid
);
list_add_tail
(
&
srb
->
list
,
&
dcb
->
srb_waiting_list
);
}
/*
* srb_going_append - Append an srb to the tail of the going list
* stored in the dcb.
*/
static
inline
void
append_srb_going
(
struct
DeviceCtlBlk
*
dcb
,
struct
ScsiReqBlk
*
srb
)
void
srb_going_append
(
struct
DeviceCtlBlk
*
dcb
,
struct
ScsiReqBlk
*
srb
)
{
dprintkdbg
(
DBG_0
,
"Append SRB %p to Going
\n
"
,
srb
);
/* Append to the list of Going commands */
if
(
dcb
->
going_srb
)
dcb
->
going_last
->
next
=
srb
;
else
dcb
->
going_srb
=
srb
;
dcb
->
going_last
=
srb
;
/* No next one in sent list */
srb
->
next
=
NULL
;
dcb
->
going_srb_count
++
;
dprintkdbg
(
DBG_0
,
"srb_going_append: srb %p
\n
"
,
srb
);
list_add_tail
(
&
srb
->
list
,
&
dcb
->
srb_going_list
);
}
/* Find predecessor SRB */
inline
static
struct
ScsiReqBlk
*
find_srb_prev
(
struct
ScsiReqBlk
*
srb
,
struct
ScsiReqBlk
*
start
)
{
struct
ScsiReqBlk
*
p
=
start
;
if
(
!
start
)
return
0
;
do
{
if
(
p
->
next
==
srb
)
return
p
;
p
=
p
->
next
;
}
while
(
p
&&
p
!=
start
);
return
0
;
}
/* Remove SRB from SRB queue */
inline
static
struct
ScsiReqBlk
*
remove_srb
(
struct
ScsiReqBlk
*
srb
,
struct
ScsiReqBlk
*
pre
)
/*
* srb_going_remove - Remove an srb from the going list stored in the
* dcb.
*/
static
void
srb_going_remove
(
struct
DeviceCtlBlk
*
dcb
,
struct
ScsiReqBlk
*
srb
)
{
if
(
pre
->
next
!=
srb
)
pre
=
find_srb_prev
(
srb
,
pre
);
if
(
!
pre
)
{
dprintkl
(
KERN_ERR
,
"Internal ERROR: SRB to rmv not found in Q!
\n
"
);
return
0
;
struct
ScsiReqBlk
*
i
;
struct
ScsiReqBlk
*
tmp
;
dprintkdbg
(
DBG_0
,
"srb_going_remove: srb %p
\n
"
,
srb
);
list_for_each_entry_safe
(
i
,
tmp
,
&
dcb
->
srb_going_list
,
list
)
if
(
i
==
srb
)
{
list_del
(
&
srb
->
list
);
break
;
}
pre
->
next
=
srb
->
next
;
/*srb->next = NULL; */
return
pre
;
}
/* Remove SRB from Going queue */
/*
* srb_waiting_remove - Remove an srb from the waiting list stored in the
* dcb.
*/
static
void
remove_srb_going
(
struct
DeviceCtlBlk
*
dcb
,
struct
ScsiReqBlk
*
srb
,
struct
ScsiReqBlk
*
hint
)
void
srb_waiting_remove
(
struct
DeviceCtlBlk
*
dcb
,
struct
ScsiReqBlk
*
srb
)
{
struct
ScsiReqBlk
*
pre
=
NULL
;
dprintkdbg
(
DBG_0
,
"Remove SRB %p from Going
\n
"
,
srb
);
if
(
!
srb
)
dprintkl
(
KERN_ERR
,
"Going_remove %p!
\n
"
,
srb
);
if
(
srb
==
dcb
->
going_srb
)
dcb
->
going_srb
=
srb
->
next
;
else
if
(
hint
&&
hint
->
next
==
srb
)
pre
=
remove_srb
(
srb
,
hint
);
else
pre
=
remove_srb
(
srb
,
dcb
->
going_srb
);
if
(
srb
==
dcb
->
going_last
)
dcb
->
going_last
=
pre
;
dcb
->
going_srb_count
--
;
}
struct
ScsiReqBlk
*
i
;
struct
ScsiReqBlk
*
tmp
;
dprintkdbg
(
DBG_0
,
"srb_waiting_remove: srb %p
\n
"
,
srb
);
/* Remove SRB from Waiting queue */
static
void
remove_srb_waiting
(
struct
DeviceCtlBlk
*
dcb
,
struct
ScsiReqBlk
*
srb
,
struct
ScsiReqBlk
*
hint
)
{
struct
ScsiReqBlk
*
pre
=
NULL
;
dprintkdbg
(
DBG_0
,
"Remove SRB %p from Waiting
\n
"
,
srb
);
if
(
!
srb
)
dprintkl
(
KERN_ERR
,
"Waiting_remove %p!
\n
"
,
srb
);
if
(
srb
==
dcb
->
waiting_srb
)
dcb
->
waiting_srb
=
srb
->
next
;
else
if
(
hint
&&
hint
->
next
==
srb
)
pre
=
remove_srb
(
srb
,
hint
);
else
pre
=
remove_srb
(
srb
,
dcb
->
waiting_srb
);
if
(
srb
==
dcb
->
wait_list
)
dcb
->
wait_list
=
pre
;
dcb
->
waiting_srb_count
--
;
list_for_each_entry_safe
(
i
,
tmp
,
&
dcb
->
srb_waiting_list
,
list
)
if
(
i
==
srb
)
{
list_del
(
&
srb
->
list
);
break
;
}
}
/* Moves SRB from Going list to the top of Waiting list */
/*
* srb_going_to_waiting_move - Remove an srb from the going list in
* the dcb and insert it at the head of the waiting list in the dcb.
*/
static
void
move_srb_going_to_waiting
(
struct
DeviceCtlBlk
*
dcb
,
void
srb_going_to_waiting_move
(
struct
DeviceCtlBlk
*
dcb
,
struct
ScsiReqBlk
*
srb
)
{
dprintkdbg
(
DBG_0
,
"Going_to_Waiting (SRB %p) pid = %li
\n
"
,
srb
,
srb
->
cmd
->
pid
);
/* Remove SRB from Going */
remove_srb_going
(
dcb
,
srb
,
0
);
TRACEPRINTF
(
"GtW *"
);
/* Insert on top of Waiting */
insert_srb_waiting
(
dcb
,
srb
);
/* Tag Mask must be freed elsewhere ! (KG, 99/06/18) */
dprintkdbg
(
DBG_0
,
"srb_going_waiting_move: srb %p, pid = %li
\n
"
,
srb
,
srb
->
cmd
->
pid
);
list_move
(
&
srb
->
list
,
&
dcb
->
srb_waiting_list
);
}
/* Moves first SRB from Waiting list to Going list */
static
inline
void
move_srb_waiting_to_going
(
struct
DeviceCtlBlk
*
dcb
,
/*
* srb_waiting_to_going_move - Remove an srb from the waiting list in
* the dcb and insert it at the head of the going list in the dcb.
*/
static
void
srb_waiting_to_going_move
(
struct
DeviceCtlBlk
*
dcb
,
struct
ScsiReqBlk
*
srb
)
{
/* Remove from waiting list */
dprintkdbg
(
DBG_0
,
"Remove SRB %p from head of Waiting
\n
"
,
srb
);
remove_srb_waiting
(
dcb
,
srb
,
0
);
dprintkdbg
(
DBG_0
,
"srb_waiting_to_going: srb %p
\n
"
,
srb
);
TRACEPRINTF
(
"WtG *"
);
append_srb_going
(
dcb
,
srb
);
list_move
(
&
srb
->
list
,
&
dcb
->
srb_going_list
);
}
...
...
@@ -1070,39 +1069,66 @@ void waiting_set_timer(struct AdapterCtlBlk *acb, unsigned long to)
static
void
waiting_process_next
(
struct
AdapterCtlBlk
*
acb
)
{
struct
DeviceCtlBlk
*
ptr
;
struct
DeviceCtlBlk
*
ptr1
;
struct
DeviceCtlBlk
*
start
=
NULL
;
struct
DeviceCtlBlk
*
pos
;
struct
DeviceCtlBlk
*
dcb
;
struct
ScsiReqBlk
*
srb
;
struct
list_head
*
dcb_list_head
=
&
acb
->
dcb_list
;
if
((
acb
->
active_dcb
)
||
(
acb
->
acb_flag
&
(
RESET_DETECT
+
RESET_DONE
+
RESET_DEV
)))
return
;
if
(
timer_pending
(
&
acb
->
waiting_timer
))
del_timer
(
&
acb
->
waiting_timer
);
ptr
=
acb
->
dcb_run_robin
;
if
(
!
ptr
)
{
/* This can happen! */
ptr
=
acb
->
link_dcb
;
acb
->
dcb_run_robin
=
ptr
;
}
ptr1
=
ptr
;
if
(
!
ptr1
)
if
(
list_empty
(
dcb_list_head
))
return
;
/*
* Find the starting dcb. Need to find it again in the list
* since the list may have changed since we set the ptr to it
*/
list_for_each_entry
(
dcb
,
dcb_list_head
,
list
)
if
(
dcb
==
acb
->
dcb_run_robin
)
{
start
=
dcb
;
break
;
}
if
(
!
start
)
{
/* This can happen! */
start
=
list_entry
(
dcb_list_head
->
next
,
typeof
(
*
start
),
list
);
acb
->
dcb_run_robin
=
start
;
}
/*
* Loop over the dcb, but we start somewhere (potentially) in
* the middle of the loop so we need to manully do this.
*/
pos
=
start
;
do
{
struct
list_head
*
waiting_list_head
=
&
pos
->
srb_waiting_list
;
/* Make sure, the next another device gets scheduled ... */
acb
->
dcb_run_robin
=
ptr1
->
next
;
if
(
!
(
srb
=
ptr1
->
waiting_srb
)
||
(
ptr1
->
max_command
<=
ptr1
->
going_srb_count
))
ptr1
=
ptr1
->
next
;
else
{
acb
->
dcb_run_robin
=
dcb_get_next
(
dcb_list_head
,
acb
->
dcb_run_robin
);
if
(
list_empty
(
waiting_list_head
)
||
pos
->
max_command
<=
list_size
(
&
pos
->
srb_going_list
))
{
/* move to next dcb */
pos
=
dcb_get_next
(
dcb_list_head
,
pos
);
}
else
{
srb
=
list_entry
(
waiting_list_head
->
next
,
struct
ScsiReqBlk
,
list
);
/* Try to send to the bus */
if
(
!
start_scsi
(
acb
,
p
tr1
,
srb
))
move_srb_waiting_to_going
(
ptr1
,
srb
);
if
(
!
start_scsi
(
acb
,
p
os
,
srb
))
srb_waiting_to_going_move
(
pos
,
srb
);
else
waiting_set_timer
(
acb
,
HZ
/
50
);
waiting_set_timer
(
acb
,
HZ
/
50
);
break
;
}
}
while
(
ptr1
!=
ptr
);
return
;
}
while
(
pos
!=
start
);
}
...
...
@@ -1141,30 +1167,18 @@ void send_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
struct
DeviceCtlBlk
*
dcb
;
dcb
=
srb
->
dcb
;
if
(
(
dcb
->
max_command
<=
dcb
->
going_srb_coun
t
)
||
(
acb
->
active_dcb
)
||
if
(
dcb
->
max_command
<=
list_size
(
&
dcb
->
srb_going_lis
t
)
||
acb
->
active_dcb
||
(
acb
->
acb_flag
&
(
RESET_DETECT
+
RESET_DONE
+
RESET_DEV
)))
{
append_srb_waiting
(
dcb
,
srb
);
srb_waiting_append
(
dcb
,
srb
);
waiting_process_next
(
acb
);
return
;
}
#if 0
if (dcb->waiting_srb) {
append_srb_waiting(dcb, srb);
/* srb = waiting_srb_get(dcb); *//* non-existent */
srb = dcb->waiting_srb;
/* Remove from waiting list */
dcb->waiting_srb = srb->next;
srb->next = NULL;
if (!dcb->waiting_srb)
dcb->wait_list = NULL;
}
#endif
if
(
!
start_scsi
(
acb
,
dcb
,
srb
))
append_srb_going
(
dcb
,
srb
);
else
{
insert_srb_waiting
(
dcb
,
srb
);
if
(
!
start_scsi
(
acb
,
dcb
,
srb
))
{
srb_going_append
(
dcb
,
srb
);
}
else
{
srb_waiting_insert
(
dcb
,
srb
);
waiting_set_timer
(
acb
,
HZ
/
50
);
}
}
...
...
@@ -1391,7 +1405,7 @@ dc395x_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
cmd
->
result
=
0
;
/* get a free SRB */
srb
=
get_srb
_free
(
acb
);
srb
=
srb_get
_free
(
acb
);
if
(
!
srb
)
{
/*
...
...
@@ -1405,9 +1419,9 @@ dc395x_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
/* build srb for the command */
build_srb
(
cmd
,
dcb
,
srb
);
if
(
dcb
->
waiting_srb
)
{
if
(
!
list_empty
(
&
dcb
->
srb_waiting_list
)
)
{
/* append to waiting queue */
append_srb_waiting
(
dcb
,
srb
);
srb_waiting_append
(
dcb
,
srb
);
waiting_process_next
(
acb
);
}
else
{
/* process immediately */
...
...
@@ -1609,17 +1623,13 @@ static inline void clear_fifo(struct AdapterCtlBlk *acb, char *txt)
*/
static
void
reset_dev_param
(
struct
AdapterCtlBlk
*
acb
)
{
struct
DeviceCtlBlk
*
dcb
=
acb
->
link_dcb
;
struct
DeviceCtlBlk
*
dcb_temp
;
struct
DeviceCtlBlk
*
dcb
;
struct
NvRamType
*
eeprom
=
&
acb
->
eeprom
;
u8
period_index
;
dprintkdbg
(
DBG_0
,
"reset_dev_param..............
\n
"
);
if
(
dcb
==
NULL
)
return
;
list_for_each_entry
(
dcb
,
&
acb
->
dcb_list
,
list
)
{
u8
period_index
;
dcb_temp
=
dcb
;
do
{
dcb
->
sync_mode
&=
~
(
SYNC_NEGO_DONE
+
WIDE_NEGO_DONE
);
dcb
->
sync_period
=
0
;
dcb
->
sync_offset
=
0
;
...
...
@@ -1631,10 +1641,7 @@ static void reset_dev_param(struct AdapterCtlBlk *acb)
if
(
!
(
dcb
->
dev_mode
&
NTC_DO_WIDE_NEGO
)
||
!
(
acb
->
config
&
HCC_WIDE_CARD
))
dcb
->
sync_mode
&=
~
WIDE_NEGO_ENABLE
;
dcb
=
dcb
->
next
;
}
while
(
dcb_temp
!=
dcb
&&
dcb
!=
NULL
);
}
...
...
@@ -1729,18 +1736,18 @@ static int dc395x_eh_abort(Scsi_Cmnd * cmd)
return
FAILED
;
}
srb
=
find_cmd
(
cmd
,
dcb
->
waiting_srb
);
srb
=
find_cmd
(
cmd
,
&
dcb
->
srb_waiting_list
);
if
(
srb
)
{
remove_srb_waiting
(
dcb
,
srb
,
0
);
srb_waiting_remove
(
dcb
,
srb
);
pci_unmap_srb_sense
(
acb
,
srb
);
pci_unmap_srb
(
acb
,
srb
);
free_tag
(
dcb
,
srb
);
insert_srb_free
(
acb
,
srb
);
srb_free_insert
(
acb
,
srb
);
dprintkl
(
KERN_DEBUG
,
"abort - command found in waiting commands queue"
);
cmd
->
result
=
DID_ABORT
<<
16
;
return
SUCCESS
;
}
srb
=
find_cmd
(
cmd
,
dcb
->
going_srb
);
srb
=
find_cmd
(
cmd
,
&
dcb
->
srb_going_list
);
if
(
srb
)
{
dprintkl
(
KERN_DEBUG
,
"abort - command currently in progress"
);
/* XXX: Should abort the command here */
...
...
@@ -3322,23 +3329,27 @@ struct ScsiReqBlk *msgin_qtag(struct AdapterCtlBlk *acb,
struct
DeviceCtlBlk
*
dcb
,
u8
tag
)
{
struct
ScsiReqBlk
*
last_srb
=
dcb
->
going_last
;
struct
ScsiReqBlk
*
srb
=
dcb
->
going_srb
;
struct
ScsiReqBlk
*
srb
=
NULL
;
struct
ScsiReqBlk
*
i
;
dprintkdbg
(
DBG_0
,
"QTag Msg (SRB %p): %i
\n
"
,
srb
,
tag
);
if
(
!
(
dcb
->
tag_mask
&
(
1
<<
tag
)))
dprintkl
(
KERN_DEBUG
,
"MsgIn_QTag: tag_mask (%08x) does not reserve tag %i!
\n
"
,
dcb
->
tag_mask
,
tag
);
if
(
!
srb
)
if
(
list_empty
(
&
dcb
->
srb_going_list
)
)
goto
mingx0
;
while
(
srb
)
{
if
(
srb
->
tag_number
==
tag
)
list_for_each_entry
(
i
,
&
dcb
->
srb_going_list
,
list
)
{
if
(
i
->
tag_number
==
tag
)
{
srb
=
i
;
break
;
if
(
srb
==
last_srb
)
goto
mingx0
;
srb
=
srb
->
next
;
}
}
if
(
!
srb
)
goto
mingx0
;
dprintkdbg
(
DBG_0
,
"pid %li (%i-%i)
\n
"
,
srb
->
cmd
->
pid
,
srb
->
dcb
->
target_id
,
srb
->
dcb
->
target_lun
);
if
(
dcb
->
flag
&
ABORT_DEV_
)
{
...
...
@@ -3350,13 +3361,18 @@ struct ScsiReqBlk *msgin_qtag(struct AdapterCtlBlk *acb,
goto
mingx0
;
/* Tag found */
{
struct
ScsiReqBlk
*
last_srb
;
TRACEPRINTF
(
"[%s]*"
,
dcb
->
active_srb
->
debugtrace
);
TRACEPRINTF
(
"RTag*"
);
/* Just for debugging ... */
last_srb
=
srb
;
srb
=
dcb
->
active_srb
;
TRACEPRINTF
(
"Found.*"
);
srb
=
last_srb
;
}
memcpy
(
srb
->
msgin_buf
,
dcb
->
active_srb
->
msgin_buf
,
acb
->
msg_len
);
srb
->
state
|=
dcb
->
active_srb
->
state
;
...
...
@@ -3774,36 +3790,26 @@ void nop1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
static
void
set_xfer_rate
(
struct
AdapterCtlBlk
*
acb
,
struct
DeviceCtlBlk
*
dcb
)
{
u8
bval
;
u16
cnt
,
i
;
struct
DeviceCtlBlk
*
dcb_temp
;
struct
DeviceCtlBlk
*
i
;
/*
*
*
set all lun device's period , offset
* set all lun device's period , offset
*/
if
(
!
(
dcb
->
identify_msg
&
0x07
))
{
if
(
acb
->
scan_devices
)
if
(
dcb
->
identify_msg
&
0x07
)
return
;
if
(
acb
->
scan_devices
)
{
current_sync_offset
=
dcb
->
sync_offset
;
else
{
dcb_temp
=
acb
->
link_dcb
;
cnt
=
acb
->
dcb_count
;
bval
=
dcb
->
target_id
;
for
(
i
=
0
;
i
<
cnt
;
i
++
)
{
if
(
dcb_temp
->
target_id
==
bval
)
{
dcb_temp
->
sync_period
=
dcb
->
sync_period
;
dcb_temp
->
sync_offset
=
dcb
->
sync_offset
;
dcb_temp
->
sync_mode
=
dcb
->
sync_mode
;
dcb_temp
->
min_nego_period
=
dcb
->
min_nego_period
;
}
dcb_temp
=
dcb_temp
->
next
;
}
return
;
}
list_for_each_entry
(
i
,
&
acb
->
dcb_list
,
list
)
if
(
i
->
target_id
==
dcb
->
target_id
)
{
i
->
sync_period
=
dcb
->
sync_period
;
i
->
sync_offset
=
dcb
->
sync_offset
;
i
->
sync_mode
=
dcb
->
sync_mode
;
i
->
min_nego_period
=
dcb
->
min_nego_period
;
}
return
;
}
...
...
@@ -3882,7 +3888,7 @@ static void disconnect(struct AdapterCtlBlk *acb)
goto
disc1
;
}
free_tag
(
dcb
,
srb
);
move_srb_going_to_waiting
(
dcb
,
srb
);
srb_going_to_waiting_move
(
dcb
,
srb
);
dprintkdbg
(
DBG_KG
,
"Retry pid %li ...
\n
"
,
srb
->
cmd
->
pid
);
waiting_set_timer
(
acb
,
HZ
/
20
);
...
...
@@ -3964,7 +3970,7 @@ static void reselect(struct AdapterCtlBlk *acb)
srb
->
state
=
SRB_READY
;
free_tag
(
dcb
,
srb
);
move_srb_going_to_waiting
(
dcb
,
srb
);
srb_going_to_waiting_move
(
dcb
,
srb
);
waiting_set_timer
(
acb
,
HZ
/
20
);
/* return; */
...
...
@@ -4049,43 +4055,32 @@ static void reselect(struct AdapterCtlBlk *acb)
static
void
remove_dev
(
struct
AdapterCtlBlk
*
acb
,
struct
DeviceCtlBlk
*
dcb
)
{
struct
DeviceCtlBlk
*
pPrevDCB
=
acb
->
link_dcb
;
struct
DeviceCtlBlk
*
i
;
struct
DeviceCtlBlk
*
tmp
;
dprintkdbg
(
DBG_0
,
"remove_dev
\n
"
);
if
(
dcb
->
going_srb_count
>
1
)
{
if
(
list_size
(
&
dcb
->
srb_going_list
)
>
1
)
{
dprintkdbg
(
DBG_DCB
,
"Driver won't free DCB (ID %i, LUN %i): 0x%08x because of SRBCnt %i
\n
"
,
dcb
->
target_id
,
dcb
->
target_lun
,
(
int
)
dcb
,
dcb
->
going_srb_count
);
list_size
(
&
dcb
->
srb_going_list
)
);
return
;
}
acb
->
dcb_map
[
dcb
->
target_id
]
&=
~
(
1
<<
dcb
->
target_lun
);
acb
->
children
[
dcb
->
target_id
][
dcb
->
target_lun
]
=
NULL
;
/* The first one */
if
(
dcb
==
acb
->
link_dcb
)
{
/* The last one */
if
(
acb
->
last_dcb
==
dcb
)
{
dcb
->
next
=
NULL
;
acb
->
last_dcb
=
NULL
;
list_for_each_entry_safe
(
i
,
tmp
,
&
acb
->
dcb_list
,
list
)
{
if
(
dcb
==
i
)
{
list_del
(
&
i
->
list
);
break
;
}
acb
->
link_dcb
=
dcb
->
next
;
}
else
{
while
(
pPrevDCB
->
next
!=
dcb
)
pPrevDCB
=
pPrevDCB
->
next
;
pPrevDCB
->
next
=
dcb
->
next
;
if
(
dcb
==
acb
->
last_dcb
)
acb
->
last_dcb
=
pPrevDCB
;
}
dprintkdbg
(
DBG_DCB
,
"Driver about to free DCB (ID %i, LUN %i): %p
\n
"
,
dcb
->
target_id
,
dcb
->
target_lun
,
dcb
);
if
(
dcb
==
acb
->
active_dcb
)
acb
->
active_dcb
=
NULL
;
if
(
dcb
==
acb
->
link_dcb
)
acb
->
link_dcb
=
dcb
->
next
;
if
(
dcb
==
acb
->
dcb_run_robin
)
acb
->
dcb_run_robin
=
dcb
->
next
;
acb
->
dcb_count
--
;
acb
->
dcb_run_robin
=
dcb_get_next
(
&
acb
->
dcb_list
,
dcb
);
dc395x_kfree
(
dcb
);
}
...
...
@@ -4320,7 +4315,7 @@ void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
request_sense
(
acb
,
dcb
,
srb
);
return
;
}
else
if
(
status_byte
(
status
)
==
QUEUE_FULL
)
{
tempcnt
=
(
u8
)
dcb
->
going_srb_count
;
tempcnt
=
(
u8
)
list_size
(
&
dcb
->
srb_going_list
)
;
printk
(
"
\n
DC395x: QUEUE_FULL for dev %02i-%i with %i cmnds
\n
"
,
dcb
->
target_id
,
dcb
->
target_lun
,
tempcnt
);
...
...
@@ -4328,7 +4323,7 @@ void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
tempcnt
--
;
dcb
->
max_command
=
tempcnt
;
free_tag
(
dcb
,
srb
);
move_srb_going_to_waiting
(
dcb
,
srb
);
srb_going_to_waiting_move
(
dcb
,
srb
);
waiting_set_timer
(
acb
,
HZ
/
20
);
srb
->
adapter_status
=
0
;
srb
->
target_status
=
0
;
...
...
@@ -4409,12 +4404,12 @@ void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
cmd
->
device
->
lun
,
srb
->
total_xfer_length
);
}
remove_srb_going
(
dcb
,
srb
,
0
);
srb_going_remove
(
dcb
,
srb
);
/* Add to free list */
if
(
srb
==
acb
->
tmp_srb
)
dprintkl
(
KERN_ERR
,
"ERROR! Completed Cmnd with tmp_srb!
\n
"
);
else
insert_srb_free
(
acb
,
srb
);
srb_free_insert
(
acb
,
srb
);
dprintkdbg
(
DBG_0
,
"SRBdone: done pid %li
\n
"
,
cmd
->
pid
);
if
(
debug_enabled
(
DBG_KG
))
{
...
...
@@ -4444,30 +4439,21 @@ void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
Scsi_Cmnd
*
cmd
,
u8
force
)
{
struct
DeviceCtlBlk
*
dcb
;
dprintkl
(
KERN_INFO
,
"doing_srb_done: pids "
);
list_for_each_entry
(
dcb
,
&
acb
->
dcb_list
,
list
)
{
struct
ScsiReqBlk
*
srb
;
struct
ScsiReqBlk
*
srb_temp
;
u16
cnt
;
struct
ScsiReqBlk
*
tmp
;
Scsi_Cmnd
*
p
;
dcb
=
acb
->
link_dcb
;
if
(
!
dcb
)
return
;
dprintkl
(
KERN_INFO
,
"doing_srb_done: pids "
);
do
{
/* As the ML may queue cmnds again, cache old values */
struct
ScsiReqBlk
*
waiting_srb
=
dcb
->
waiting_srb
;
/*struct ScsiReqBlk* wait_list = dcb->wait_list; */
u16
waiting_srb_count
=
dcb
->
waiting_srb_count
;
/* Going queue */
cnt
=
dcb
->
going_srb_count
;
srb
=
dcb
->
going_srb
;
while
(
cnt
--
)
{
list_for_each_entry_safe
(
srb
,
tmp
,
&
dcb
->
srb_going_list
,
list
)
{
int
result
;
int
dir
;
srb_temp
=
srb
->
next
;
p
=
srb
->
cmd
;
dir
=
scsi_to_pci_dma_dir
(
p
->
sc_data_direction
);
result
=
MK_RES
(
0
,
did_flag
,
0
,
0
);
/*result = MK_RES(0,DID_RESET,0,0); */
TRACEPRINTF
(
"Reset(%li):%08x*"
,
jiffies
,
result
);
printk
(
" (G)"
);
...
...
@@ -4476,12 +4462,10 @@ void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
p
->
device
->
id
,
p
->
device
->
lun
);
#endif
TRACEOUT
(
"%s
\n
"
,
srb
->
debugtrace
);
dcb
->
going_srb
=
srb_temp
;
dcb
->
going_srb_count
--
;
if
(
!
srb_temp
)
dcb
->
going_last
=
NULL
;
srb_going_remove
(
dcb
,
srb
);
free_tag
(
dcb
,
srb
);
insert_srb_free
(
acb
,
srb
);
srb_free_insert
(
acb
,
srb
);
p
->
result
=
result
;
pci_unmap_srb_sense
(
acb
,
srb
);
pci_unmap_srb
(
acb
,
srb
);
...
...
@@ -4490,9 +4474,8 @@ void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
* as they all complete or all time out */
p
->
scsi_done
(
p
);
}
srb
=
srb_temp
;
}
if
(
dcb
->
going_srb
)
if
(
!
list_empty
(
&
dcb
->
srb_going_list
)
)
dprintkl
(
KERN_DEBUG
,
"How could the ML send cmnds to the Going queue? (%02i-%i)!!
\n
"
,
dcb
->
target_id
,
dcb
->
target_lun
);
...
...
@@ -4501,16 +4484,12 @@ void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
"tag_mask for %02i-%i should be empty, is %08x!
\n
"
,
dcb
->
target_id
,
dcb
->
target_lun
,
dcb
->
tag_mask
);
/*dcb->going_srb_count = 0;; */
/*dcb->going_srb = NULL; dcb->going_last = NULL; */
/* Waiting queue */
cnt
=
waiting_srb_count
;
srb
=
waiting_srb
;
while
(
cnt
--
)
{
list_for_each_entry_safe
(
srb
,
tmp
,
&
dcb
->
srb_waiting_list
,
list
)
{
int
result
;
srb_temp
=
srb
->
next
;
p
=
srb
->
cmd
;
result
=
MK_RES
(
0
,
did_flag
,
0
,
0
);
TRACEPRINTF
(
"Reset(%li):%08x*"
,
jiffies
,
result
);
printk
(
" (W)"
);
...
...
@@ -4519,11 +4498,8 @@ void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
p
->
device
->
lun
);
#endif
TRACEOUT
(
"%s
\n
"
,
srb
->
debugtrace
);
dcb
->
waiting_srb
=
srb_temp
;
dcb
->
waiting_srb_count
--
;
if
(
!
srb_temp
)
dcb
->
wait_list
=
NULL
;
insert_srb_free
(
acb
,
srb
);
srb_waiting_remove
(
dcb
,
srb
);
srb_free_insert
(
acb
,
srb
);
p
->
result
=
result
;
pci_unmap_srb_sense
(
acb
,
srb
);
...
...
@@ -4532,21 +4508,16 @@ void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
/* For new EH, we normally don't need to give commands back,
* as they all complete or all time out */
cmd
->
scsi_done
(
cmd
);
srb
=
srb_temp
;
}
}
if
(
dcb
->
waiting_srb_count
)
if
(
!
list_empty
(
&
dcb
->
srb_waiting_list
)
)
printk
(
"
\n
DC395x: Debug: ML queued %i cmnds again to %02i-%i
\n
"
,
dcb
->
waiting_srb_count
,
dcb
->
target_id
,
list_size
(
&
dcb
->
srb_waiting_list
)
,
dcb
->
target_id
,
dcb
->
target_lun
);
/* The ML could have queued the cmnds again! */
/*dcb->waiting_srb_count = 0;; */
/*dcb->waiting_srb = NULL; dcb->wait_list = NULL; */
dcb
->
flag
&=
~
ABORT_DEV_
;
dcb
=
dcb
->
next
;
}
while
(
dcb
!=
acb
->
link_dcb
&&
dcb
);
printk
(
"
\n
"
);
}
...
...
@@ -4703,7 +4674,7 @@ void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
"Request Sense failed for pid %li (%02i-%i)!
\n
"
,
srb
->
cmd
->
pid
,
dcb
->
target_id
,
dcb
->
target_lun
);
TRACEPRINTF
(
"?*"
);
move_srb_going_to_waiting
(
dcb
,
srb
);
srb_going_to_waiting_move
(
dcb
,
srb
);
waiting_set_timer
(
acb
,
HZ
/
100
);
}
TRACEPRINTF
(
".*"
);
...
...
@@ -4736,26 +4707,17 @@ void init_dcb(struct AdapterCtlBlk *acb, struct DeviceCtlBlk **pdcb,
if
(
!
dcb
)
return
;
if
(
acb
->
dcb_count
==
0
)
{
acb
->
link_dcb
=
dcb
;
INIT_LIST_HEAD
(
&
dcb
->
srb_waiting_list
);
INIT_LIST_HEAD
(
&
dcb
->
srb_going_list
);
if
(
list_empty
(
&
acb
->
dcb_list
))
acb
->
dcb_run_robin
=
dcb
;
}
else
{
acb
->
last_dcb
->
next
=
dcb
;
}
acb
->
dcb_count
++
;
dcb
->
next
=
acb
->
link_dcb
;
acb
->
last_dcb
=
dcb
;
list_add_tail
(
&
dcb
->
list
,
&
acb
->
dcb_list
);
/* $$$$$$$ */
dcb
->
acb
=
acb
;
dcb
->
target_id
=
target
;
dcb
->
target_lun
=
lun
;
/* $$$$$$$ */
dcb
->
waiting_srb
=
NULL
;
dcb
->
going_srb
=
NULL
;
dcb
->
going_srb_count
=
0
;
dcb
->
waiting_srb_count
=
0
;
dcb
->
active_srb
=
NULL
;
/* $$$$$$$ */
dcb
->
tag_mask
=
0
;
...
...
@@ -4792,9 +4754,10 @@ void init_dcb(struct AdapterCtlBlk *acb, struct DeviceCtlBlk **pdcb,
/* $$$$$$$ */
if
(
dcb
->
target_lun
!=
0
)
{
/* Copy settings */
struct
DeviceCtlBlk
*
prevDCB
=
acb
->
link_dcb
;
while
(
prevDCB
->
target_id
!=
dcb
->
target_id
)
prevDCB
=
prevDCB
->
next
;
struct
DeviceCtlBlk
*
prevDCB
;
list_for_each_entry
(
prevDCB
,
&
acb
->
dcb_list
,
list
)
if
(
prevDCB
->
target_id
==
dcb
->
target_id
)
break
;
dprintkdbg
(
DBG_KG
,
"Copy settings from %02i-%02i to %02i-%02i
\n
"
,
prevDCB
->
target_id
,
prevDCB
->
target_lun
,
...
...
@@ -4924,9 +4887,7 @@ static void __init link_srb(struct AdapterCtlBlk *acb)
int
i
;
for
(
i
=
0
;
i
<
acb
->
srb_count
-
1
;
i
++
)
acb
->
srb_array
[
i
].
next
=
&
acb
->
srb_array
[
i
+
1
];
acb
->
srb_array
[
i
].
next
=
NULL
;
/*DC395x_Free_integrity (acb); */
srb_free_insert
(
acb
,
&
acb
->
srb_array
[
i
]);
}
...
...
@@ -4974,14 +4935,12 @@ int __init init_acb(struct Scsi_Host *host, u32 io_port, u8 irq)
*/
acb
->
scsi_host
=
host
;
acb
->
IOPortBase
=
(
u16
)
io_port
;
acb
->
link_dcb
=
NULL
;
acb
->
dcb_run_robin
=
NULL
;
acb
->
active_dcb
=
NULL
;
acb
->
srb_count
=
DC395x_MAX_SRB_CNT
;
acb
->
scsi_host
->
this_id
=
eeprom
->
scsi_id
;
acb
->
hostid_bit
=
(
1
<<
acb
->
scsi_host
->
this_id
);
/*acb->scsi_host->this_lun = 0; */
acb
->
dcb_count
=
0
;
acb
->
irq_level
=
irq
;
acb
->
tag_max_num
=
1
<<
eeprom
->
max_tag
;
if
(
acb
->
tag_max_num
>
30
)
...
...
@@ -5006,14 +4965,14 @@ int __init init_acb(struct Scsi_Host *host, u32 io_port, u8 irq)
return
1
;
}
#endif
INIT_LIST_HEAD
(
&
acb
->
dcb_list
);
INIT_LIST_HEAD
(
&
acb
->
srb_free_list
);
link_srb
(
acb
);
acb
->
free_srb
=
acb
->
srb_array
;
/*
* temp SRB for Q tag used or abort command used
*/
acb
->
tmp_srb
=
&
acb
->
srb
;
acb
->
srb
.
dcb
=
NULL
;
acb
->
srb
.
next
=
NULL
;
init_timer
(
&
acb
->
waiting_timer
);
for
(
i
=
0
;
i
<
DC395x_MAX_SCSI_ID
;
i
++
)
...
...
@@ -5550,10 +5509,11 @@ int dc395x_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t o
int
inout
)
{
struct
AdapterCtlBlk
*
acb
=
(
struct
AdapterCtlBlk
*
)
host
->
hostdata
;
int
dev
,
spd
,
spd1
;
int
spd
,
spd1
;
char
*
pos
=
buffer
;
struct
DeviceCtlBlk
*
dcb
;
unsigned
long
flags
;
int
dev
;
if
(
inout
)
/* Has data been written to the file ? */
return
-
EPERM
;
...
...
@@ -5580,7 +5540,7 @@ int dc395x_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t o
SPRINTF
(
", DelayReset %is
\n
"
,
acb
->
eeprom
.
delay_time
);
/*SPRINTF("\n"); */
SPRINTF
(
"Nr of DCBs: %i
\n
"
,
acb
->
dcb_count
);
SPRINTF
(
"Nr of DCBs: %i
\n
"
,
list_size
(
&
acb
->
dcb_list
)
);
SPRINTF
(
"Map of attached LUNs: %02x %02x %02x %02x %02x %02x %02x %02x
\n
"
,
acb
->
dcb_map
[
0
],
acb
->
dcb_map
[
1
],
acb
->
dcb_map
[
2
],
...
...
@@ -5595,8 +5555,8 @@ int dc395x_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t o
SPRINTF
(
"Un ID LUN Prty Sync Wide DsCn SndS TagQ nego_period SyncFreq SyncOffs MaxCmd
\n
"
);
d
cb
=
acb
->
link_dcb
;
for
(
dev
=
0
;
dev
<
acb
->
dcb_count
;
dev
++
)
{
d
ev
=
0
;
list_for_each_entry
(
dcb
,
&
acb
->
dcb_list
,
list
)
{
int
nego_period
;
SPRINTF
(
"%02i %02i %02i "
,
dev
,
dcb
->
target_id
,
dcb
->
target_lun
);
...
...
@@ -5606,8 +5566,7 @@ int dc395x_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t o
YESNO
(
dcb
->
dev_mode
&
NTC_DO_DISCONNECT
);
YESNO
(
dcb
->
dev_mode
&
NTC_DO_SEND_START
);
YESNO
(
dcb
->
sync_mode
&
EN_TAG_QUEUEING
);
nego_period
=
clock_period
[
dcb
->
sync_period
&
0x07
]
<<
2
;
nego_period
=
clock_period
[
dcb
->
sync_period
&
0x07
]
<<
2
;
if
(
dcb
->
sync_offset
)
SPRINTF
(
" %03i ns "
,
nego_period
);
else
...
...
@@ -5624,45 +5583,42 @@ int dc395x_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t o
/* Add more info ... */
SPRINTF
(
" %02i
\n
"
,
dcb
->
max_command
);
d
cb
=
dcb
->
next
;
d
ev
++
;
}
if
(
timer_pending
(
&
acb
->
waiting_timer
))
SPRINTF
(
"Waiting queue timer running
\n
"
);
else
SPRINTF
(
"
\n
"
);
dcb
=
acb
->
link_dcb
;
for
(
dev
=
0
;
dev
<
acb
->
dcb_count
;
dev
++
)
{
list_for_each_entry
(
dcb
,
&
acb
->
dcb_list
,
list
)
{
struct
ScsiReqBlk
*
srb
;
if
(
dcb
->
waiting_srb_count
)
if
(
!
list_empty
(
&
dcb
->
srb_waiting_list
)
)
SPRINTF
(
"DCB (%02i-%i): Waiting: %i:"
,
dcb
->
target_id
,
dcb
->
target_lun
,
dcb
->
waiting_srb_count
);
for
(
srb
=
dcb
->
waiting_srb
;
srb
;
srb
=
srb
->
nex
t
)
list_size
(
&
dcb
->
srb_waiting_list
)
);
list_for_each_entry
(
srb
,
&
dcb
->
srb_waiting_list
,
lis
t
)
SPRINTF
(
" %li"
,
srb
->
cmd
->
pid
);
if
(
dcb
->
going_srb_count
)
if
(
!
list_empty
(
&
dcb
->
srb_going_list
)
)
SPRINTF
(
"
\n
DCB (%02i-%i): Going : %i:"
,
dcb
->
target_id
,
dcb
->
target_lun
,
dcb
->
going_srb_count
);
for
(
srb
=
dcb
->
going_srb
;
srb
;
srb
=
srb
->
nex
t
)
list_size
(
&
dcb
->
srb_going_list
)
);
list_for_each_entry
(
srb
,
&
dcb
->
srb_going_list
,
lis
t
)
#if debug_enabled(DBG_TRACE|DBG_TRACEALL)
SPRINTF
(
"
\n
%s"
,
srb
->
debugtrace
);
#else
SPRINTF
(
" %li"
,
srb
->
cmd
->
pid
);
#endif
if
(
dcb
->
waiting_srb_count
||
dcb
->
going_srb_count
)
if
(
!
list_empty
(
&
dcb
->
srb_waiting_list
)
||
!
list_empty
(
&
dcb
->
srb_going_list
)
)
SPRINTF
(
"
\n
"
);
dcb
=
dcb
->
next
;
}
if
(
debug_enabled
(
DBG_DCB
))
{
SPRINTF
(
"DCB list for ACB %p:
\n
"
,
acb
);
dcb
=
acb
->
link_dcb
;
SPRINTF
(
"%p"
,
dcb
);
for
(
dev
=
0
;
dev
<
acb
->
dcb_count
;
dev
++
,
dcb
=
dcb
->
next
)
SPRINTF
(
"->%p"
,
dcb
->
next
);
SPRINTF
(
"
\n
"
);
list_for_each_entry
(
dcb
,
&
acb
->
dcb_list
,
list
)
{
SPRINTF
(
"%p -> "
,
dcb
);
}
SPRINTF
(
"END
\n
"
);
}
*
start
=
buffer
+
offset
;
...
...
@@ -5721,19 +5677,13 @@ static
void
free_dcbs
(
struct
AdapterCtlBlk
*
acb
)
{
struct
DeviceCtlBlk
*
dcb
;
struct
DeviceCtlBlk
*
dcb_next
;
struct
DeviceCtlBlk
*
tmp
;
dprintkdbg
(
DBG_DCB
,
"Free %i DCBs
\n
"
,
acb
->
dcb_count
);
dprintkdbg
(
DBG_DCB
,
"Free %i DCBs
\n
"
,
list_size
(
&
acb
->
dcb_list
)
);
for
(
dcb
=
acb
->
link_dcb
;
dcb
!=
NULL
;
dcb
=
dcb_next
)
{
dcb_next
=
dcb
->
next
;
list_for_each_entry_safe
(
dcb
,
tmp
,
&
acb
->
dcb_list
,
list
)
{
dprintkdbg
(
DBG_DCB
,
"Free DCB (ID %i, LUN %i): %p
\n
"
,
dcb
->
target_id
,
dcb
->
target_lun
,
dcb
);
/*
* Free the DCB. This removes the entry from the
* link_dcb list and decrements the count in dcb_count
*/
remove_dev
(
acb
,
dcb
);
}
}
...
...
drivers/scsi/hosts.c
View file @
ab2d582d
...
...
@@ -40,6 +40,16 @@
static
int
scsi_host_next_hn
;
/* host_no for next new host */
static
void
scsi_host_cls_release
(
struct
class_device
*
class_dev
)
{
put_device
(
&
class_to_shost
(
class_dev
)
->
shost_gendev
);
}
static
struct
class
shost_class
=
{
.
name
=
"scsi_host"
,
.
release
=
scsi_host_cls_release
,
};
/**
* scsi_host_cancel - cancel outstanding IO to this host
* @shost: pointer to struct Scsi_Host
...
...
@@ -64,10 +74,18 @@ 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
);
scsi_sysfs_remove_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
);
}
/**
...
...
@@ -89,21 +107,45 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
if
(
!
shost
->
can_queue
)
{
printk
(
KERN_ERR
"%s: can_queue = 0 no longer supported
\n
"
,
sht
->
name
);
error
=
-
EINVAL
;
return
-
EINVAL
;
}
error
=
scsi_sysfs_add_host
(
shost
,
dev
);
if
(
!
error
)
if
(
!
shost
->
shost_gendev
.
parent
)
shost
->
shost_gendev
.
parent
=
dev
?
dev
:
&
legacy_bus
;
error
=
device_add
(
&
shost
->
shost_gendev
);
if
(
error
)
goto
out
;
set_bit
(
SHOST_ADD
,
&
shost
->
shost_state
);
get_device
(
shost
->
shost_gendev
.
parent
);
error
=
class_device_add
(
&
shost
->
shost_classdev
);
if
(
error
)
goto
out_del_gendev
;
get_device
(
&
shost
->
shost_gendev
);
error
=
scsi_sysfs_add_host
(
shost
);
if
(
error
)
goto
out_del_classdev
;
scsi_proc_host_add
(
shost
);
return
error
;
out_del_classdev:
class_device_del
(
&
shost
->
shost_classdev
);
out_del_gendev:
device_del
(
&
shost
->
shost_gendev
);
out:
return
error
;
}
/**
* scsi_free_sdev - free a scsi hosts resources
* @shost: scsi host to free
**/
void
scsi_free_shost
(
struct
Scsi_Host
*
shost
)
static
void
scsi_host_dev_release
(
struct
device
*
dev
)
{
struct
Scsi_Host
*
shost
=
dev_to_shost
(
dev
);
struct
device
*
parent
=
dev
->
parent
;
if
(
shost
->
ehandler
)
{
DECLARE_COMPLETION
(
sem
);
shost
->
eh_notify
=
&
sem
;
...
...
@@ -115,6 +157,8 @@ void scsi_free_shost(struct Scsi_Host *shost)
scsi_proc_hostdir_rm
(
shost
->
hostt
);
scsi_destroy_command_freelist
(
shost
);
put_device
(
parent
);
kfree
(
shost
);
}
...
...
@@ -214,7 +258,16 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
if
(
rval
)
goto
fail
;
scsi_sysfs_init_host
(
shost
);
device_initialize
(
&
shost
->
shost_gendev
);
snprintf
(
shost
->
shost_gendev
.
bus_id
,
BUS_ID_SIZE
,
"host%d"
,
shost
->
host_no
);
shost
->
shost_gendev
.
release
=
scsi_host_dev_release
;
class_device_initialize
(
&
shost
->
shost_classdev
);
shost
->
shost_classdev
.
dev
=
&
shost
->
shost_gendev
;
shost
->
shost_classdev
.
class
=
&
shost_class
;
snprintf
(
shost
->
shost_classdev
.
class_id
,
BUS_ID_SIZE
,
"host%d"
,
shost
->
host_no
);
shost
->
eh_notify
=
&
complete
;
/* XXX(hch): handle error return */
...
...
@@ -299,3 +352,13 @@ void scsi_host_put(struct Scsi_Host *shost)
{
put_device
(
&
shost
->
shost_gendev
);
}
int
scsi_init_hosts
(
void
)
{
return
class_register
(
&
shost_class
);
}
void
scsi_exit_hosts
(
void
)
{
class_unregister
(
&
shost_class
);
}
drivers/scsi/ips.c
View file @
ab2d582d
This source diff could not be displayed because it is too large. You can
view the blob
instead.
drivers/scsi/ips.h
View file @
ab2d582d
...
...
@@ -106,8 +106,10 @@
#define IPS_REMOVE_HOST(shost)
#define IPS_SCSI_SET_DEVICE(sh,ha) scsi_set_pci_device(sh, (ha)->pcidev)
#define IPS_PRINTK(level, pcidev, format, arg...) \
printk(level "%s %s:" format , (pcidev)->driver->name , \
pci_name(pcidev) , ## arg)
printk(level "%s %s:" format , "ips" , \
(pcidev)->slot_name , ## arg)
#define scsi_host_alloc(sh,size) scsi_register(sh,size)
#define scsi_host_put(sh) scsi_unregister(sh)
#else
#define IPS_REGISTER_HOSTS(SHT) (!ips_detect(SHT))
#define IPS_UNREGISTER_HOSTS(SHT)
...
...
@@ -126,22 +128,13 @@
#define min(x,y) ((x) < (y) ? x : y)
#endif
#define pci_dma_hi32(a) ((a >> 16) >> 16)
#define pci_dma_lo32(a) (a & 0xffffffff)
#if (BITS_PER_LONG > 32) || (defined CONFIG_HIGHMEM64G && defined IPS_HIGHIO)
#define IPS_ENABLE_DMA64 (1)
#define pci_dma_hi32(a) (a >> 32)
#else
#define IPS_ENABLE_DMA64 (0)
#define pci_dma_hi32(a) (0)
#endif
#if defined(__ia64__)
#define IPS_ATOMIC_GFP (GFP_DMA | GFP_ATOMIC)
#define IPS_INIT_GFP GFP_DMA
#else
#define IPS_ATOMIC_GFP GFP_ATOMIC
#define IPS_INIT_GFP GFP_KERNEL
#endif
/*
...
...
@@ -451,9 +444,11 @@
* Scsi_Host Template
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
static
int
ips_proc24_info
(
char
*
,
char
**
,
off_t
,
int
,
int
,
int
);
static
void
ips_select_queue_depth
(
struct
Scsi_Host
*
,
Scsi_Device
*
);
static
int
ips_biosparam
(
Disk
*
disk
,
kdev_t
dev
,
int
geom
[]);
#else
int
ips_proc_info
(
struct
Scsi_Host
*
,
char
*
,
char
**
,
off_t
,
int
,
int
);
static
int
ips_biosparam
(
struct
scsi_device
*
sdev
,
struct
block_device
*
bdev
,
sector_t
capacity
,
int
geom
[]);
int
ips_slave_configure
(
Scsi_Device
*
SDptr
);
...
...
@@ -1106,7 +1101,8 @@ typedef struct ips_ha {
uint16_t
device_id
;
/* PCI device ID */
uint8_t
slot_num
;
/* PCI Slot Number */
uint16_t
subdevice_id
;
/* Subsystem device ID */
uint8_t
ioctl_order
;
/* Number of pages in ioctl */
int
ioctl_len
;
/* size of ioctl buffer */
dma_addr_t
ioctl_busaddr
;
/* dma address of ioctl buffer*/
uint8_t
bios_version
[
8
];
/* BIOS Revision */
uint32_t
mem_addr
;
/* Memory mapped address */
uint32_t
io_len
;
/* Size of IO Address */
...
...
@@ -1116,8 +1112,10 @@ typedef struct ips_ha {
ips_hw_func_t
func
;
/* hw function pointers */
struct
pci_dev
*
pcidev
;
/* PCI device handle */
char
*
flash_data
;
/* Save Area for flash data */
u8
flash_order
;
/* Save Area for flash size order
*/
int
flash_len
;
/* length of flash buffer
*/
u32
flash_datasize
;
/* Save Area for flash data size */
dma_addr_t
flash_busaddr
;
/* dma address of flash buffer*/
dma_addr_t
enq_busaddr
;
/* dma address of enq struct */
uint8_t
requires_esl
;
/* Requires an EraseStripeLock */
}
ips_ha_t
;
...
...
@@ -1203,25 +1201,29 @@ typedef struct {
*
*************************************************************************/
#define IPS_VER_MAJOR 5
#define IPS_VER_MAJOR_STRING "5"
#define IPS_VER_MINOR 99
#define IPS_VER_MINOR_STRING "99"
#define IPS_VER_BUILD 00
#define IPS_VER_BUILD_STRING "00"
#define IPS_VER_STRING "5.99.00"
#define IPS_BUILD_IDENT 1132
#define IPS_VER_MAJOR 6
#define IPS_VER_MAJOR_STRING "6"
#define IPS_VER_MINOR 10
#define IPS_VER_MINOR_STRING "10"
#define IPS_VER_BUILD 90
#define IPS_VER_BUILD_STRING "90"
#define IPS_VER_STRING "6.10.90"
#define IPS_RELEASE_ID 0x00010000
#define IPS_BUILD_IDENT 364
#define IPS_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2003. All Rights Reserved."
#define IPS_ADAPTECCOPYRIGHT_STRING "(c) Copyright Adaptec, Inc. 2002 to present. All Rights Reserved."
#define IPS_NT_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2003."
/* Version numbers for various adapters */
#define IPS_VER_SERVERAID1 "2.25.01"
#define IPS_VER_SERVERAID2 "2.88.13"
#define IPS_VER_NAVAJO "2.88.13"
#define IPS_VER_SERVERAID3 "
5.11.05
"
#define IPS_VER_SERVERAID4H "
5.11.05
"
#define IPS_VER_SERVERAID4MLx "
5.11.05
"
#define IPS_VER_SARASOTA "
5.11.05
"
#define IPS_VER_MARCO "
0.00.00
"
#define IPS_VER_SEBRING "
0.00.00
"
#define IPS_VER_SERVERAID3 "
6.10.24
"
#define IPS_VER_SERVERAID4H "
6.10.24
"
#define IPS_VER_SERVERAID4MLx "
6.10.24
"
#define IPS_VER_SARASOTA "
6.10.24
"
#define IPS_VER_MARCO "
6.10.24
"
#define IPS_VER_SEBRING "
6.10.24
"
/* Compatability IDs for various adapters */
#define IPS_COMPAT_UNKNOWN ""
...
...
@@ -1230,17 +1232,17 @@ typedef struct {
#define IPS_COMPAT_SERVERAID2 "2.88.13"
#define IPS_COMPAT_NAVAJO "2.88.13"
#define IPS_COMPAT_KIOWA "2.88.13"
#define IPS_COMPAT_SERVERAID3H "S
A5
10"
#define IPS_COMPAT_SERVERAID3L "S
A5
10"
#define IPS_COMPAT_SERVERAID4H "S
A5
10"
#define IPS_COMPAT_SERVERAID4M "S
A5
10"
#define IPS_COMPAT_SERVERAID4L "S
A5
10"
#define IPS_COMPAT_SERVERAID4Mx "S
A5
10"
#define IPS_COMPAT_SERVERAID4Lx "S
A5
10"
#define IPS_COMPAT_SARASOTA "S
A5
10"
#define IPS_COMPAT_MARCO "S
A00
0"
#define IPS_COMPAT_SEBRING "S
A00
0"
#define IPS_COMPAT_BIOS "S
A5
10"
#define IPS_COMPAT_SERVERAID3H "S
B6
10"
#define IPS_COMPAT_SERVERAID3L "S
B6
10"
#define IPS_COMPAT_SERVERAID4H "S
B6
10"
#define IPS_COMPAT_SERVERAID4M "S
B6
10"
#define IPS_COMPAT_SERVERAID4L "S
B6
10"
#define IPS_COMPAT_SERVERAID4Mx "S
B6
10"
#define IPS_COMPAT_SERVERAID4Lx "S
B6
10"
#define IPS_COMPAT_SARASOTA "S
B6
10"
#define IPS_COMPAT_MARCO "S
B61
0"
#define IPS_COMPAT_SEBRING "S
B61
0"
#define IPS_COMPAT_BIOS "S
B6
10"
#define IPS_COMPAT_MAX_ADAPTER_TYPE 16
#define IPS_COMPAT_ID_LENGTH 8
...
...
drivers/scsi/lasi700.c
View file @
ab2d582d
...
...
@@ -86,14 +86,10 @@ lasi700_driver_callback(struct parisc_device *dev)
struct
NCR_700_Host_Parameters
*
hostdata
;
struct
Scsi_Host
*
host
;
snprintf
(
dev
->
dev
.
name
,
sizeof
(
dev
->
dev
.
name
),
"%s"
,
(
dev
->
id
.
sversion
==
LASI_700_SVERSION
)
?
"lasi700"
:
"lasi710"
);
hostdata
=
kmalloc
(
sizeof
(
*
hostdata
),
GFP_KERNEL
);
if
(
!
hostdata
)
{
printk
(
KERN_ERR
"%s: Failed to allocate host data
\n
"
,
dev
->
dev
.
name
);
dev
->
dev
.
bus_id
);
return
1
;
}
memset
(
hostdata
,
0
,
sizeof
(
struct
NCR_700_Host_Parameters
));
...
...
@@ -121,9 +117,9 @@ lasi700_driver_callback(struct parisc_device *dev)
host
->
irq
=
dev
->
irq
;
if
(
request_irq
(
dev
->
irq
,
NCR_700_intr
,
SA_SHIRQ
,
dev
->
dev
.
name
,
host
))
{
dev
->
dev
.
bus_id
,
host
))
{
printk
(
KERN_ERR
"%s: irq problem, detaching
\n
"
,
dev
->
dev
.
name
);
dev
->
dev
.
bus_id
);
goto
out_put_host
;
}
...
...
drivers/scsi/pcmcia/aha152x_stub.c
View file @
ab2d582d
...
...
@@ -177,13 +177,8 @@ static void aha152x_detach(dev_link_t *link)
if
(
*
linkp
==
NULL
)
return
;
if
(
link
->
state
&
DEV_CONFIG
)
{
if
(
link
->
state
&
DEV_CONFIG
)
aha152x_release_cs
(
link
);
if
(
link
->
state
&
DEV_STALE_CONFIG
)
{
link
->
state
|=
DEV_STALE_LINK
;
return
;
}
}
if
(
link
->
handle
)
CardServices
(
DeregisterClient
,
link
->
handle
);
...
...
@@ -302,9 +297,6 @@ static void aha152x_release_cs(dev_link_t *link)
link
->
state
&=
~
DEV_CONFIG
;
scsi_unregister
(
info
->
host
);
if
(
link
->
state
&
DEV_STALE_LINK
)
aha152x_detach
(
link
);
}
static
int
aha152x_event
(
event_t
event
,
int
priority
,
...
...
drivers/scsi/pcmcia/fdomain_stub.c
View file @
ab2d582d
...
...
@@ -166,13 +166,8 @@ static void fdomain_detach(dev_link_t *link)
if
(
*
linkp
==
NULL
)
return
;
if
(
link
->
state
&
DEV_CONFIG
)
{
if
(
link
->
state
&
DEV_CONFIG
)
fdomain_release
(
link
);
if
(
link
->
state
&
DEV_STALE_CONFIG
)
{
link
->
state
|=
DEV_STALE_LINK
;
return
;
}
}
if
(
link
->
handle
)
CardServices
(
DeregisterClient
,
link
->
handle
);
...
...
@@ -283,9 +278,7 @@ static void fdomain_release(dev_link_t *link)
scsi_unregister
(
info
->
host
);
link
->
state
&=
~
DEV_CONFIG
;
if
(
link
->
state
&
DEV_STALE_LINK
)
fdomain_detach
(
link
);
}
/* fdomain_release */
}
/*====================================================================*/
...
...
drivers/scsi/pcmcia/nsp_cs.c
View file @
ab2d582d
...
...
@@ -1553,18 +1553,12 @@ static void nsp_cs_detach(dev_link_t *link)
return
;
}
if
(
link
->
state
&
DEV_CONFIG
)
{
if
(
link
->
state
&
DEV_CONFIG
)
nsp_cs_release
(
link
);
if
(
link
->
state
&
DEV_STALE_CONFIG
)
{
link
->
state
|=
DEV_STALE_LINK
;
return
;
}
}
/* Break the link with Card Services */
if
(
link
->
handle
)
{
if
(
link
->
handle
)
CardServices
(
DeregisterClient
,
link
->
handle
);
}
/* Unlink device structure, free bits */
*
linkp
=
link
->
next
;
...
...
@@ -1792,17 +1786,6 @@ static void nsp_cs_release(dev_link_t *link)
DEBUG
(
0
,
"%s(0x%p)
\n
"
,
__FUNCTION__
,
link
);
/*
* If the device is currently in use, we won't release until it
* is actually closed.
*/
if
(
link
->
open
)
{
DEBUG
(
1
,
"nsp_cs: release postponed, '%s' still open
\n
"
,
link
->
dev
->
dev_name
);
link
->
state
|=
DEV_STALE_CONFIG
;
return
;
}
/* Unlink the device chain */
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,2))
scsi_unregister_module
(
MODULE_SCSI_HA
,
&
nsp_driver_template
);
...
...
@@ -1824,11 +1807,7 @@ static void nsp_cs_release(dev_link_t *link)
CardServices
(
ReleaseIRQ
,
link
->
handle
,
&
link
->
irq
);
}
link
->
state
&=
~
DEV_CONFIG
;
if
(
link
->
state
&
DEV_STALE_LINK
)
{
nsp_cs_detach
(
link
);
}
}
/* nsp_cs_release */
}
/*======================================================================
...
...
drivers/scsi/pcmcia/qlogic_stub.c
View file @
ab2d582d
...
...
@@ -165,13 +165,8 @@ static void qlogic_detach(dev_link_t * link)
if
(
*
linkp
==
NULL
)
return
;
if
(
link
->
state
&
DEV_CONFIG
)
{
if
(
link
->
state
&
DEV_CONFIG
)
qlogic_release
(
link
);
if
(
link
->
state
&
DEV_STALE_CONFIG
)
{
link
->
state
|=
DEV_STALE_LINK
;
return
;
}
}
if
(
link
->
handle
)
CardServices
(
DeregisterClient
,
link
->
handle
);
...
...
@@ -296,9 +291,7 @@ static void qlogic_release(dev_link_t *link)
scsi_unregister
(
info
->
host
);
link
->
state
&=
~
DEV_CONFIG
;
if
(
link
->
state
&
DEV_STALE_LINK
)
qlogic_detach
(
link
);
}
/* qlogic_release */
}
/*====================================================================*/
...
...
drivers/scsi/ppa.c
View file @
ab2d582d
...
...
@@ -76,6 +76,7 @@ int ppa_release(struct Scsi_Host *host)
int
host_no
=
host
->
unique_id
;
printk
(
"Releasing ppa%i
\n
"
,
host_no
);
scsi_unregister
(
host
);
parport_unregister_device
(
ppa_hosts
[
host_no
].
dev
);
return
0
;
}
...
...
drivers/scsi/qla1280.c
View file @
ab2d582d
...
...
@@ -16,9 +16,11 @@
* General Public License for more details.
*
******************************************************************************/
#define QLA1280_VERSION "3.23.3
4
"
#define QLA1280_VERSION "3.23.3
5
"
/*****************************************************************************
Revision History:
Rev 3.23.35 August 14, 2003, Jes Sorensen
- Build against 2.6
Rev 3.23.34 July 23, 2003, Jes Sorensen
- Remove pointless TRUE/FALSE macros
- Clean up vchan handling
...
...
@@ -296,14 +298,12 @@
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/proc_fs.h>
#include <linux/blk.h>
#include <linux/stat.h>
#include <linux/slab.h>
#include <linux/pci_ids.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/byteorder.h>
...
...
@@ -312,7 +312,10 @@
#include <asm/system.h>
#if LINUX_VERSION_CODE < 0x020545
#include <linux/blk.h>
#include "sd.h"
#else
#include <scsi/scsi_host.h>
#endif
#include "scsi.h"
#include "hosts.h"
...
...
@@ -634,11 +637,14 @@ static int ql_debug_level = 1;
*************************************************************************/
#define PROC_BUF &qla1280_buffer[len]
int
qla1280_proc_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
,
#if LINUX_VERSION_CODE < 0x020600
int
qla1280_proc_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
,
int
hostno
,
int
inout
)
#else
int
qla1280_proc_info
(
struct
Scsi_Host
*
host
,
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
,
int
inout
)
#endif
{
struct
Scsi_Host
*
host
;
struct
scsi_qla_host
*
ha
;
int
size
=
0
;
int
len
=
0
;
...
...
@@ -647,7 +653,10 @@ qla1280_proc_info(char *buffer, char **start, off_t offset, int length,
struct
scsi_lu
*
up
;
uint32_t
b
,
t
,
l
;
#endif
#if LINUX_VERSION_CODE >= 0x020600
ha
=
(
struct
scsi_qla_host
*
)
host
->
hostdata
;
#else
struct
Scsi_Host
*
host
;
/* Find the host that was specified */
for
(
ha
=
qla1280_hostlist
;
(
ha
!=
NULL
)
&&
ha
->
host
->
host_no
!=
hostno
;
ha
=
ha
->
next
)
;
...
...
@@ -664,6 +673,7 @@ qla1280_proc_info(char *buffer, char **start, off_t offset, int length,
}
host
=
ha
->
host
;
#endif
if
(
inout
)
return
-
ENOSYS
;
...
...
@@ -1828,7 +1838,7 @@ qla1280_done(struct scsi_qla_host *ha, struct srb ** done_q_first,
CMD_HANDLE
(
sp
->
cmd
)
=
(
unsigned
char
*
)
INVALID_HANDLE
;
ha
->
actthreads
--
;
#if LINUX_
KERNEL_VERSION
< 0x020500
#if LINUX_
VERSION_CODE
< 0x020500
if
(
cmd
->
cmnd
[
0
]
==
INQUIRY
)
qla1280_get_target_options
(
cmd
,
ha
);
#endif
...
...
@@ -4497,7 +4507,7 @@ qla1280_rst_aen(struct scsi_qla_host *ha)
}
#if LINUX_
KERNEL_VERSION
< 0x020500
#if LINUX_
VERSION_CODE
< 0x020500
/*
*
*/
...
...
drivers/scsi/qla1280.h
View file @
ab2d582d
...
...
@@ -1111,7 +1111,11 @@ struct scsi_qla_host {
/*
* Linux - SCSI Driver Interface Function Prototypes.
*/
#if LINUX_VERSION_CODE < 0x020600
int
qla1280_proc_info
(
char
*
,
char
**
,
off_t
,
int
,
int
,
int
);
#else
int
qla1280_proc_info
(
struct
Scsi_Host
*
,
char
*
,
char
**
,
off_t
,
int
,
int
);
#endif
const
char
*
qla1280_info
(
struct
Scsi_Host
*
host
);
int
qla1280_detect
(
Scsi_Host_Template
*
);
int
qla1280_release
(
struct
Scsi_Host
*
);
...
...
@@ -1147,8 +1151,6 @@ int qla1280_eh_adapter_reset(struct scsi_cmnd *cmd);
.detect = qla1280_detect, \
.release = qla1280_release, \
.info = qla1280_info, \
.ioctl = NULL, \
.command = NULL, \
.queuecommand = qla1280_queuecommand, \
.eh_strategy_handler = NULL, \
.eh_abort_handler = qla1280_eh_abort, \
...
...
drivers/scsi/scsi.c
View file @
ab2d582d
...
...
@@ -1003,9 +1003,12 @@ static int __init init_scsi(void)
error
=
scsi_init_devinfo
();
if
(
error
)
goto
cleanup_procfs
;
error
=
scsi_
sysfs_register
();
error
=
scsi_
init_hosts
();
if
(
error
)
goto
cleanup_devlist
;
error
=
scsi_sysfs_register
();
if
(
error
)
goto
cleanup_hosts
;
for
(
i
=
0
;
i
<
NR_CPUS
;
i
++
)
INIT_LIST_HEAD
(
&
done_q
[
i
]);
...
...
@@ -1015,6 +1018,8 @@ static int __init init_scsi(void)
printk
(
KERN_NOTICE
"SCSI subsystem initialized
\n
"
);
return
0
;
cleanup_hosts:
scsi_exit_hosts
();
cleanup_devlist:
scsi_exit_devinfo
();
cleanup_procfs:
...
...
@@ -1029,6 +1034,7 @@ static int __init init_scsi(void)
static
void
__exit
exit_scsi
(
void
)
{
scsi_sysfs_unregister
();
scsi_exit_hosts
();
scsi_exit_devinfo
();
devfs_remove
(
"scsi"
);
scsi_exit_procfs
();
...
...
drivers/scsi/scsi_error.c
View file @
ab2d582d
...
...
@@ -1285,7 +1285,12 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
maybe_retry:
if
((
++
scmd
->
retries
)
<
scmd
->
allowed
)
{
/* we requeue for retry because the error was retryable, and
* the request was not marked fast fail. Note that above,
* even if the request is marked fast fail, we still requeue
* for queue congestion conditions (QUEUE_FULL or BUSY) */
if
((
++
scmd
->
retries
)
<
scmd
->
allowed
&&
!
blk_noretry_request
(
scmd
->
request
))
{
return
NEEDS_RETRY
;
}
else
{
/*
...
...
drivers/scsi/scsi_lib.c
View file @
ab2d582d
...
...
@@ -502,15 +502,23 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate,
* to queue the remainder of them.
*/
if
(
end_that_request_first
(
req
,
uptodate
,
sectors
))
{
if
(
requeue
)
{
int
leftover
=
req
->
hard_nr_sectors
-
sectors
;
/* kill remainder if no retrys */
if
(
!
uptodate
&&
blk_noretry_request
(
req
))
end_that_request_first
(
req
,
0
,
leftover
);
else
{
if
(
requeue
)
/*
* Bleah. Leftovers again. Stick the leftovers in
* the front of the queue, and goose the queue again.
* Bleah. Leftovers again. Stick the
* leftovers in the front of the
* queue, and goose the queue again.
*/
scsi_requeue_command
(
q
,
cmd
);
}
return
cmd
;
}
}
add_disk_randomness
(
req
->
rq_disk
);
...
...
drivers/scsi/scsi_priv.h
View file @
ab2d582d
...
...
@@ -41,6 +41,12 @@
#define SCSI_SENSE_VALID(scmd) \
(((scmd)->sense_buffer[0] & 0x70) == 0x70)
/*
* Special value for scanning to specify scanning or rescanning of all
* possible channels, (target) ids, or luns on a given shost.
*/
#define SCAN_WILD_CARD ~0
/*
* scsi_target: representation of a scsi target, for now, this is only
* used for single_lun devices. If no one has active IO to the target,
...
...
@@ -51,6 +57,9 @@ struct scsi_target {
unsigned
int
starget_refcnt
;
};
/* hosts.c */
extern
int
scsi_init_hosts
(
void
);
extern
void
scsi_exit_hosts
(
void
);
/* scsi.c */
extern
int
scsi_dispatch_cmd
(
struct
scsi_cmnd
*
cmd
);
...
...
@@ -106,20 +115,18 @@ extern void scsi_exit_procfs(void);
#endif
/* CONFIG_PROC_FS */
/* scsi_scan.c */
int
scsi_scan_host_selected
(
struct
Scsi_Host
*
,
unsigned
int
,
unsigned
int
,
unsigned
int
,
int
);
extern
void
scsi_forget_host
(
struct
Scsi_Host
*
);
extern
void
scsi_free_sdev
(
struct
scsi_device
*
);
extern
void
scsi_free_shost
(
struct
Scsi_Host
*
);
extern
void
scsi_rescan_device
(
struct
device
*
);
/* scsi_sysfs.c */
extern
int
scsi_device_register
(
struct
scsi_device
*
);
extern
void
scsi_sysfs_init_host
(
struct
Scsi_Host
*
);
extern
int
scsi_sysfs_add_host
(
struct
Scsi_Host
*
,
struct
device
*
);
extern
void
scsi_sysfs_remove_host
(
struct
Scsi_Host
*
);
extern
int
scsi_sysfs_add_host
(
struct
Scsi_Host
*
);
extern
int
scsi_sysfs_register
(
void
);
extern
void
scsi_sysfs_unregister
(
void
);
extern
struct
class
shost_class
;
extern
struct
class
sdev_class
;
extern
struct
bus_type
scsi_bus_type
;
...
...
drivers/scsi/scsi_proc.c
View file @
ab2d582d
...
...
@@ -81,6 +81,9 @@ static int proc_scsi_write_proc(struct file *file, const char *buf,
void
scsi_proc_hostdir_add
(
struct
scsi_host_template
*
sht
)
{
if
(
!
sht
->
proc_info
)
return
;
down
(
&
global_host_template_sem
);
if
(
!
sht
->
present
++
)
{
sht
->
proc_dir
=
proc_mkdir
(
sht
->
proc_name
,
proc_scsi
);
...
...
@@ -96,6 +99,9 @@ void scsi_proc_hostdir_add(struct scsi_host_template *sht)
void
scsi_proc_hostdir_rm
(
struct
scsi_host_template
*
sht
)
{
if
(
!
sht
->
proc_info
)
return
;
down
(
&
global_host_template_sem
);
if
(
!--
sht
->
present
&&
sht
->
proc_dir
)
{
remove_proc_entry
(
sht
->
proc_name
,
proc_scsi
);
...
...
@@ -189,21 +195,13 @@ static int proc_print_scsidevice(struct device *dev, void *data)
static
int
scsi_add_single_device
(
uint
host
,
uint
channel
,
uint
id
,
uint
lun
)
{
struct
Scsi_Host
*
shost
;
struct
scsi_device
*
sdev
;
int
error
=
-
ENXIO
;
shost
=
scsi_host_lookup
(
host
);
if
(
IS_ERR
(
shost
))
return
PTR_ERR
(
shost
);
if
(
!
scsi_find_device
(
shost
,
channel
,
id
,
lun
))
{
sdev
=
scsi_add_device
(
shost
,
channel
,
id
,
lun
);
if
(
IS_ERR
(
sdev
))
error
=
PTR_ERR
(
sdev
);
else
error
=
0
;
}
error
=
scsi_scan_host_selected
(
shost
,
channel
,
id
,
lun
,
1
);
scsi_host_put
(
shost
);
return
error
;
}
...
...
drivers/scsi/scsi_scan.c
View file @
ab2d582d
...
...
@@ -656,13 +656,32 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags)
**/
static
int
scsi_probe_and_add_lun
(
struct
Scsi_Host
*
host
,
uint
channel
,
uint
id
,
uint
lun
,
int
*
bflagsp
,
struct
scsi_device
**
sdevp
)
struct
scsi_device
**
sdevp
,
int
rescan
)
{
struct
scsi_device
*
sdev
;
struct
scsi_request
*
sreq
;
unsigned
char
*
result
;
int
bflags
,
res
=
SCSI_SCAN_NO_RESPONSE
;
/*
* The rescan flag is used as an optimization, the first scan of a
* host adapter calls into here with rescan == 0.
*/
if
(
rescan
)
{
sdev
=
scsi_find_device
(
host
,
channel
,
id
,
lun
);
if
(
sdev
)
{
SCSI_LOG_SCAN_BUS
(
3
,
printk
(
KERN_INFO
"scsi scan: device exists on <%d:%d:%d:%d>
\n
"
,
host
->
host_no
,
channel
,
id
,
lun
));
if
(
sdevp
)
*
sdevp
=
sdev
;
if
(
bflagsp
)
*
bflagsp
=
scsi_get_device_flags
(
sdev
->
vendor
,
sdev
->
model
);
return
SCSI_SCAN_LUN_PRESENT
;
}
}
sdev
=
scsi_alloc_sdev
(
host
,
channel
,
id
,
lun
);
if
(
!
sdev
)
goto
out
;
...
...
@@ -737,7 +756,7 @@ static int scsi_probe_and_add_lun(struct Scsi_Host *host,
* Modifies sdevscan->lun.
**/
static
void
scsi_sequential_lun_scan
(
struct
Scsi_Host
*
shost
,
uint
channel
,
uint
id
,
int
bflags
,
int
lun0_res
,
int
scsi_level
)
uint
id
,
int
bflags
,
int
lun0_res
,
int
scsi_level
,
int
rescan
)
{
unsigned
int
sparse_lun
,
lun
,
max_dev_lun
;
...
...
@@ -806,7 +825,8 @@ static void scsi_sequential_lun_scan(struct Scsi_Host *shost, uint channel,
*/
for
(
lun
=
1
;
lun
<
max_dev_lun
;
++
lun
)
if
((
scsi_probe_and_add_lun
(
shost
,
channel
,
id
,
lun
,
NULL
,
NULL
)
!=
SCSI_SCAN_LUN_PRESENT
)
&&
!
sparse_lun
)
NULL
,
NULL
,
rescan
)
!=
SCSI_SCAN_LUN_PRESENT
)
&&
!
sparse_lun
)
return
;
}
...
...
@@ -857,7 +877,8 @@ static int scsilun_to_int(struct scsi_lun *scsilun)
* 0: scan completed (or no memory, so further scanning is futile)
* 1: no report lun scan, or not configured
**/
static
int
scsi_report_lun_scan
(
struct
scsi_device
*
sdev
,
int
bflags
)
static
int
scsi_report_lun_scan
(
struct
scsi_device
*
sdev
,
int
bflags
,
int
rescan
)
{
char
devname
[
64
];
unsigned
char
scsi_cmd
[
MAX_COMMAND_SIZE
];
...
...
@@ -1011,7 +1032,7 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags)
int
res
;
res
=
scsi_probe_and_add_lun
(
sdev
->
host
,
sdev
->
channel
,
sdev
->
id
,
lun
,
NULL
,
NULL
);
sdev
->
id
,
lun
,
NULL
,
NULL
,
rescan
);
if
(
res
==
SCSI_SCAN_NO_RESPONSE
)
{
/*
* Got some results, but now none, abort.
...
...
@@ -1037,7 +1058,7 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags)
return
0
;
}
#else
# define scsi_report_lun_scan(sdev, blags) (1)
# define scsi_report_lun_scan(sdev, blags
, rescan
) (1)
#endif
/* CONFIG_SCSI_REPORT_LUNS */
struct
scsi_device
*
scsi_add_device
(
struct
Scsi_Host
*
shost
,
...
...
@@ -1046,7 +1067,7 @@ struct scsi_device *scsi_add_device(struct Scsi_Host *shost,
struct
scsi_device
*
sdev
;
int
res
;
res
=
scsi_probe_and_add_lun
(
shost
,
channel
,
id
,
lun
,
NULL
,
&
sdev
);
res
=
scsi_probe_and_add_lun
(
shost
,
channel
,
id
,
lun
,
NULL
,
&
sdev
,
1
);
if
(
res
!=
SCSI_SCAN_LUN_PRESENT
)
sdev
=
ERR_PTR
(
-
ENODEV
);
return
sdev
;
...
...
@@ -1083,7 +1104,7 @@ void scsi_rescan_device(struct device *dev)
* sequential scan of LUNs on the target id.
**/
static
void
scsi_scan_target
(
struct
Scsi_Host
*
shost
,
unsigned
int
channel
,
unsigned
int
id
)
unsigned
int
id
,
unsigned
int
lun
,
int
rescan
)
{
int
bflags
=
0
;
int
res
;
...
...
@@ -1095,19 +1116,29 @@ static void scsi_scan_target(struct Scsi_Host *shost, unsigned int channel,
*/
return
;
if
(
lun
!=
SCAN_WILD_CARD
)
{
/*
* Scan for a specific host/chan/id/lun.
*/
scsi_probe_and_add_lun
(
shost
,
channel
,
id
,
lun
,
NULL
,
NULL
,
rescan
);
return
;
}
/*
* Scan LUN 0, if there is some response, scan further. Ideally, we
* would not configure LUN 0 until all LUNs are scanned.
*/
res
=
scsi_probe_and_add_lun
(
shost
,
channel
,
id
,
0
,
&
bflags
,
&
sdev
);
res
=
scsi_probe_and_add_lun
(
shost
,
channel
,
id
,
0
,
&
bflags
,
&
sdev
,
rescan
);
if
(
res
==
SCSI_SCAN_LUN_PRESENT
)
{
if
(
scsi_report_lun_scan
(
sdev
,
bflags
)
!=
0
)
if
(
scsi_report_lun_scan
(
sdev
,
bflags
,
rescan
)
!=
0
)
/*
* The REPORT LUN did not scan the target,
* do a sequential scan.
*/
scsi_sequential_lun_scan
(
shost
,
channel
,
id
,
bflags
,
res
,
sdev
->
scsi_level
);
res
,
sdev
->
scsi_level
,
rescan
);
}
else
if
(
res
==
SCSI_SCAN_TARGET_PRESENT
)
{
/*
* There's a target here, but lun 0 is offline so we
...
...
@@ -1116,27 +1147,17 @@ static void scsi_scan_target(struct Scsi_Host *shost, unsigned int channel,
* a default scsi level of SCSI_2
*/
scsi_sequential_lun_scan
(
shost
,
channel
,
id
,
BLIST_SPARSELUN
,
SCSI_SCAN_TARGET_PRESENT
,
SCSI_2
);
SCSI_SCAN_TARGET_PRESENT
,
SCSI_2
,
rescan
);
}
}
/**
* scsi_scan_host - scan the given adapter
* @shost: adapter to scan
*
* Description:
* Iterate and call scsi_scan_target to scan all possible target id's
* on all possible channels.
**/
void
scsi_scan_host
(
struct
Scsi_Host
*
shost
)
static
void
scsi_scan_channel
(
struct
Scsi_Host
*
shost
,
unsigned
int
channel
,
unsigned
int
id
,
unsigned
int
lun
,
int
rescan
)
{
uint
channel
,
id
,
order_id
;
uint
order_id
;
/*
* The sdevscan host, channel, id and lun are filled in as
* needed to scan.
*/
for
(
channel
=
0
;
channel
<=
shost
->
max_channel
;
channel
++
)
{
if
(
id
==
SCAN_WILD_CARD
)
for
(
id
=
0
;
id
<
shost
->
max_id
;
++
id
)
{
/*
* XXX adapter drivers when possible (FCP, iSCSI)
* could modify max_id to match the current max,
...
...
@@ -1146,7 +1167,6 @@ void scsi_scan_host(struct Scsi_Host *shost)
* the FC ID can be the same as a target id
* without a huge overhead of sparse id's.
*/
for
(
id
=
0
;
id
<
shost
->
max_id
;
++
id
)
{
if
(
shost
->
reverse_ordering
)
/*
* Scan from high to low id.
...
...
@@ -1154,9 +1174,39 @@ void scsi_scan_host(struct Scsi_Host *shost)
order_id
=
shost
->
max_id
-
id
-
1
;
else
order_id
=
id
;
scsi_scan_target
(
shost
,
channel
,
order_id
);
}
scsi_scan_target
(
shost
,
channel
,
order_id
,
lun
,
rescan
);
}
else
scsi_scan_target
(
shost
,
channel
,
id
,
lun
,
rescan
);
}
int
scsi_scan_host_selected
(
struct
Scsi_Host
*
shost
,
unsigned
int
channel
,
unsigned
int
id
,
unsigned
int
lun
,
int
rescan
)
{
SCSI_LOG_SCAN_BUS
(
3
,
printk
(
KERN_INFO
"%s: <%u:%u:%u:%u>
\n
"
,
__FUNCTION__
,
shost
->
host_no
,
channel
,
id
,
lun
));
if
(((
channel
!=
SCAN_WILD_CARD
)
&&
(
channel
>
shost
->
max_channel
))
||
((
id
!=
SCAN_WILD_CARD
)
&&
(
id
>
shost
->
max_id
))
||
((
lun
!=
SCAN_WILD_CARD
)
&&
(
lun
>
shost
->
max_lun
)))
return
-
EINVAL
;
if
(
channel
==
SCAN_WILD_CARD
)
for
(
channel
=
0
;
channel
<=
shost
->
max_channel
;
channel
++
)
scsi_scan_channel
(
shost
,
channel
,
id
,
lun
,
rescan
);
else
scsi_scan_channel
(
shost
,
channel
,
id
,
lun
,
rescan
);
return
0
;
}
/**
* scsi_scan_host - scan the given adapter
* @shost: adapter to scan
**/
void
scsi_scan_host
(
struct
Scsi_Host
*
shost
)
{
scsi_scan_host_selected
(
shost
,
SCAN_WILD_CARD
,
SCAN_WILD_CARD
,
SCAN_WILD_CARD
,
0
);
}
void
scsi_forget_host
(
struct
Scsi_Host
*
shost
)
...
...
drivers/scsi/scsi_sysfs.c
View file @
ab2d582d
...
...
@@ -15,6 +15,43 @@
#include "hosts.h"
#include "scsi_priv.h"
#include "scsi_logging.h"
static
int
check_set
(
unsigned
int
*
val
,
char
*
src
)
{
char
*
last
;
if
(
strncmp
(
src
,
"-"
,
20
)
==
0
)
{
*
val
=
SCAN_WILD_CARD
;
}
else
{
/*
* Doesn't check for int overflow
*/
*
val
=
simple_strtoul
(
src
,
&
last
,
0
);
if
(
*
last
!=
'\0'
)
return
1
;
}
return
0
;
}
static
int
scsi_scan
(
struct
Scsi_Host
*
shost
,
const
char
*
str
)
{
char
s1
[
15
],
s2
[
15
],
s3
[
15
],
junk
;
unsigned
int
channel
,
id
,
lun
;
int
res
;
res
=
sscanf
(
str
,
"%10s %10s %10s %c"
,
s1
,
s2
,
s3
,
&
junk
);
if
(
res
!=
3
)
return
-
EINVAL
;
if
(
check_set
(
&
channel
,
s1
))
return
-
EINVAL
;
if
(
check_set
(
&
id
,
s2
))
return
-
EINVAL
;
if
(
check_set
(
&
lun
,
s3
))
return
-
EINVAL
;
res
=
scsi_scan_host_selected
(
shost
,
channel
,
id
,
lun
,
1
);
return
res
;
}
/*
* shost_show_function: macro to create an attr function that can be used to
...
...
@@ -39,6 +76,20 @@ static CLASS_DEVICE_ATTR(field, S_IRUGO, show_##field, NULL)
/*
* Create the actual show/store functions and data structures.
*/
static
ssize_t
store_scan
(
struct
class_device
*
class_dev
,
const
char
*
buf
,
size_t
count
)
{
struct
Scsi_Host
*
shost
=
class_to_shost
(
class_dev
);
int
res
;
res
=
scsi_scan
(
shost
,
buf
);
if
(
res
==
0
)
res
=
count
;
return
res
;
};
static
CLASS_DEVICE_ATTR
(
scan
,
S_IWUSR
,
NULL
,
store_scan
);
shost_rd_attr
(
unique_id
,
"%u
\n
"
);
shost_rd_attr
(
host_busy
,
"%hu
\n
"
);
shost_rd_attr
(
cmd_per_lun
,
"%hd
\n
"
);
...
...
@@ -51,33 +102,10 @@ static struct class_device_attribute *scsi_sysfs_shost_attrs[] = {
&
class_device_attr_cmd_per_lun
,
&
class_device_attr_sg_tablesize
,
&
class_device_attr_unchecked_isa_dma
,
&
class_device_attr_scan
,
NULL
};
static
void
scsi_host_cls_release
(
struct
class_device
*
class_dev
)
{
struct
Scsi_Host
*
shost
;
shost
=
class_to_shost
(
class_dev
);
put_device
(
&
shost
->
shost_gendev
);
}
static
void
scsi_host_dev_release
(
struct
device
*
dev
)
{
struct
Scsi_Host
*
shost
;
struct
device
*
parent
;
parent
=
dev
->
parent
;
shost
=
dev_to_shost
(
dev
);
scsi_free_shost
(
shost
);
put_device
(
parent
);
}
struct
class
shost_class
=
{
.
name
=
"scsi_host"
,
.
release
=
scsi_host_cls_release
,
};
static
void
scsi_device_cls_release
(
struct
class_device
*
class_dev
)
{
struct
scsi_device
*
sdev
;
...
...
@@ -113,33 +141,23 @@ struct bus_type scsi_bus_type = {
.
match
=
scsi_bus_match
,
};
int
scsi_sysfs_register
(
void
)
{
int
error
;
error
=
bus_register
(
&
scsi_bus_type
);
if
(
error
)
return
error
;
error
=
class_register
(
&
shost_class
);
if
(
error
)
goto
bus_unregister
;
if
(
!
error
)
{
error
=
class_register
(
&
sdev_class
);
if
(
error
)
goto
class_unregister
;
return
0
;
class_unregister:
class_unregister
(
&
shost_class
);
bus_unregister:
bus_unregister
(
&
scsi_bus_type
);
}
return
error
;
}
void
scsi_sysfs_unregister
(
void
)
{
class_unregister
(
&
sdev_class
);
class_unregister
(
&
shost_class
);
bus_unregister
(
&
scsi_bus_type
);
}
...
...
@@ -243,6 +261,24 @@ store_rescan_field (struct device *dev, const char *buf, size_t 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
);
int
res
=
count
;
if
(
sdev
->
access_count
)
/*
* FIXME and scsi_proc.c: racey use of access_count,
* possibly add a new arg to scsi_remove_device.
*/
res
=
-
EBUSY
;
else
scsi_remove_device
(
sdev
);
return
res
;
};
static
DEVICE_ATTR
(
delete
,
S_IWUSR
,
NULL
,
sdev_store_delete
);
/* Default template for device attributes. May NOT be modified */
static
struct
device_attribute
*
scsi_sysfs_sdev_attrs
[]
=
{
&
dev_attr_device_blocked
,
...
...
@@ -255,6 +291,7 @@ static struct device_attribute *scsi_sysfs_sdev_attrs[] = {
&
dev_attr_rev
,
&
dev_attr_online
,
&
dev_attr_rescan
,
&
dev_attr_delete
,
NULL
};
...
...
@@ -403,20 +440,6 @@ int scsi_register_interface(struct class_interface *intf)
}
void
scsi_sysfs_init_host
(
struct
Scsi_Host
*
shost
)
{
device_initialize
(
&
shost
->
shost_gendev
);
snprintf
(
shost
->
shost_gendev
.
bus_id
,
BUS_ID_SIZE
,
"host%d"
,
shost
->
host_no
);
shost
->
shost_gendev
.
release
=
scsi_host_dev_release
;
class_device_initialize
(
&
shost
->
shost_classdev
);
shost
->
shost_classdev
.
dev
=
&
shost
->
shost_gendev
;
shost
->
shost_classdev
.
class
=
&
shost_class
;
snprintf
(
shost
->
shost_classdev
.
class_id
,
BUS_ID_SIZE
,
"host%d"
,
shost
->
host_no
);
}
static
struct
class_device_attribute
*
class_attr_overridden
(
struct
class_device_attribute
**
attrs
,
struct
class_device_attribute
*
attr
)
...
...
@@ -459,31 +482,16 @@ static int class_attr_add(struct class_device *classdev,
* @shost: scsi host struct to add to subsystem
* @dev: parent struct device pointer
**/
int
scsi_sysfs_add_host
(
struct
Scsi_Host
*
shost
,
struct
device
*
dev
)
int
scsi_sysfs_add_host
(
struct
Scsi_Host
*
shost
)
{
int
error
,
i
;
if
(
!
shost
->
shost_gendev
.
parent
)
shost
->
shost_gendev
.
parent
=
dev
?
dev
:
&
legacy_bus
;
error
=
device_add
(
&
shost
->
shost_gendev
);
if
(
error
)
return
error
;
set_bit
(
SHOST_ADD
,
&
shost
->
shost_state
);
get_device
(
shost
->
shost_gendev
.
parent
);
error
=
class_device_add
(
&
shost
->
shost_classdev
);
if
(
error
)
goto
clean_device
;
get_device
(
&
shost
->
shost_gendev
);
if
(
shost
->
hostt
->
shost_attrs
)
{
for
(
i
=
0
;
shost
->
hostt
->
shost_attrs
[
i
];
i
++
)
{
error
=
class_attr_add
(
&
shost
->
shost_classdev
,
shost
->
hostt
->
shost_attrs
[
i
]);
if
(
error
)
goto
clean_class
;
return
error
;
}
}
...
...
@@ -493,31 +501,9 @@ int scsi_sysfs_add_host(struct Scsi_Host *shost, struct device *dev)
error
=
class_device_create_file
(
&
shost
->
shost_classdev
,
scsi_sysfs_shost_attrs
[
i
]);
if
(
error
)
goto
clean_class
;
return
error
;
}
}
return
error
;
clean_class:
class_device_del
(
&
shost
->
shost_classdev
);
clean_device:
device_del
(
&
shost
->
shost_gendev
);
return
error
;
}
/**
* scsi_sysfs_remove_host - remove scsi host from subsystem
* @shost: scsi host to remove from subsystem
**/
void
scsi_sysfs_remove_host
(
struct
Scsi_Host
*
shost
)
{
unsigned
long
flags
;
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
);
return
0
;
}
drivers/scsi/sd.c
View file @
ab2d582d
...
...
@@ -308,6 +308,8 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
SCpnt
->
cmnd
[
4
]
=
(
unsigned
char
)
this_count
;
SCpnt
->
cmnd
[
5
]
=
0
;
}
SCpnt
->
request_bufflen
=
SCpnt
->
bufflen
=
this_count
*
sdp
->
sector_size
;
/*
* We shouldn't disconnect in the middle of a sector, so with a dumb
...
...
@@ -1353,10 +1355,14 @@ static int sd_remove(struct device *dev)
static
void
sd_shutdown
(
struct
device
*
dev
)
{
struct
scsi_device
*
sdp
=
to_scsi_device
(
dev
);
struct
scsi_disk
*
sdkp
=
dev_get_drvdata
(
dev
)
;
struct
scsi_disk
*
sdkp
;
struct
scsi_request
*
sreq
;
int
retries
,
res
;
sdkp
=
dev_get_drvdata
(
dev
);
if
(
!
sdkp
)
return
;
/* this can happen */
if
(
!
sdp
->
online
||
!
sdkp
->
WCE
)
return
;
...
...
drivers/scsi/sr.c
View file @
ab2d582d
...
...
@@ -340,6 +340,20 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
return
0
;
}
{
struct
scatterlist
*
sg
=
SCpnt
->
request_buffer
;
int
i
,
size
=
0
;
for
(
i
=
0
;
i
<
SCpnt
->
use_sg
;
i
++
)
size
+=
sg
[
i
].
length
;
if
(
size
!=
SCpnt
->
request_bufflen
&&
SCpnt
->
use_sg
)
{
printk
(
KERN_ERR
"sr: mismatch count %d, bytes %d
\n
"
,
size
,
SCpnt
->
request_bufflen
);
if
(
SCpnt
->
request_bufflen
>
size
)
SCpnt
->
request_bufflen
=
SCpnt
->
bufflen
=
size
;
}
}
/*
* request doesn't start on hw block boundary, add scatter pads
*/
...
...
@@ -361,8 +375,11 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
SCpnt
->
cmnd
[
1
]
=
0
;
block
=
(
unsigned
int
)
SCpnt
->
request
->
sector
/
(
s_size
>>
9
);
if
(
this_count
>
0xffff
)
if
(
this_count
>
0xffff
)
{
this_count
=
0xffff
;
SCpnt
->
request_bufflen
=
SCpnt
->
bufflen
=
this_count
*
s_size
;
}
SCpnt
->
cmnd
[
2
]
=
(
unsigned
char
)
(
block
>>
24
)
&
0xff
;
SCpnt
->
cmnd
[
3
]
=
(
unsigned
char
)
(
block
>>
16
)
&
0xff
;
...
...
@@ -390,18 +407,6 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
*/
SCpnt
->
done
=
rw_intr
;
{
struct
scatterlist
*
sg
=
SCpnt
->
request_buffer
;
int
i
,
size
=
0
;
for
(
i
=
0
;
i
<
SCpnt
->
use_sg
;
i
++
)
size
+=
sg
[
i
].
length
;
if
(
size
!=
SCpnt
->
request_bufflen
&&
SCpnt
->
use_sg
)
{
printk
(
"sr: mismatch count %d, bytes %d
\n
"
,
size
,
SCpnt
->
request_bufflen
);
SCpnt
->
request_bufflen
=
size
;
}
}
/*
* This indicates that the command is ready from our end to be
* queued.
...
...
drivers/scsi/sym53c8xx_2/sym_glue.c
View file @
ab2d582d
...
...
@@ -2029,7 +2029,7 @@ sym_attach (struct scsi_host_template *tpnt, int unit, sym_device *dev)
printf_info
(
"%s: giving up ...
\n
"
,
sym_name
(
np
));
if
(
np
)
sym_free_resources
(
np
);
scsi_
unregister
(
instance
);
scsi_
host_put
(
instance
);
return
-
1
;
}
...
...
drivers/scsi/sym53c8xx_2/sym_hipd.c
View file @
ab2d582d
...
...
@@ -5942,14 +5942,7 @@ int sym_hcb_attach(hcb_p np, struct sym_fw *fw)
*/
return
0
;
/*
* We have failed.
* We will try to free all the resources we have
* allocated, but if we are a boot device, this
* will not help that much.;)
*/
attach_failed:
sym_hcb_free
(
np
);
return
-
ENXIO
;
}
...
...
drivers/scsi/zalon.c
View file @
ab2d582d
...
...
@@ -135,11 +135,9 @@ zalon_scsi_callback(struct parisc_device *dev)
if
(
!
host
)
goto
fail
;
strlcpy
(
dev
->
dev
.
name
,
"zalon7xx"
,
sizeof
(
dev
->
dev
.
name
));
if
(
request_irq
(
irq
,
ncr53c8xx_intr
,
SA_SHIRQ
,
dev
->
dev
.
name
,
host
))
{
if
(
request_irq
(
irq
,
ncr53c8xx_intr
,
SA_SHIRQ
,
dev
->
dev
.
bus_id
,
host
))
{
printk
(
KERN_ERR
"%s: irq problem with %d, detaching
\n
"
,
dev
->
dev
.
name
,
irq
);
dev
->
dev
.
bus_id
,
irq
);
goto
fail
;
}
...
...
include/scsi/scsi.h
View file @
ab2d582d
...
...
@@ -16,6 +16,8 @@
*/
#include <linux/types.h>
/*
* SCSI command lengths
*/
...
...
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