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
8b0f29fb
Commit
8b0f29fb
authored
Feb 21, 2003
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
http://linux-scsi.bkbits.net/scsi-for-linus-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
parents
227b2020
6fe854d9
Changes
23
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
874 additions
and
950 deletions
+874
-950
Documentation/scsi/scsi_mid_low_api.txt
Documentation/scsi/scsi_mid_low_api.txt
+79
-11
drivers/scsi/53c700.c
drivers/scsi/53c700.c
+22
-0
drivers/scsi/53c700.h
drivers/scsi/53c700.h
+7
-48
drivers/scsi/Kconfig
drivers/scsi/Kconfig
+1
-0
drivers/scsi/eata.c
drivers/scsi/eata.c
+0
-3
drivers/scsi/eata_pio.c
drivers/scsi/eata_pio.c
+119
-36
drivers/scsi/eata_pio.h
drivers/scsi/eata_pio.h
+0
-25
drivers/scsi/eata_pio_proc.c
drivers/scsi/eata_pio_proc.c
+0
-128
drivers/scsi/hosts.c
drivers/scsi/hosts.c
+4
-16
drivers/scsi/hosts.h
drivers/scsi/hosts.h
+1
-3
drivers/scsi/pluto.c
drivers/scsi/pluto.c
+1
-1
drivers/scsi/scsi.c
drivers/scsi/scsi.c
+98
-38
drivers/scsi/scsi.h
drivers/scsi/scsi.h
+7
-4
drivers/scsi/scsi_error.c
drivers/scsi/scsi_error.c
+428
-433
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_lib.c
+1
-18
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_scan.c
+2
-0
drivers/scsi/scsi_syms.c
drivers/scsi/scsi_syms.c
+1
-2
drivers/scsi/scsi_sysfs.c
drivers/scsi/scsi_sysfs.c
+56
-9
drivers/scsi/sg.c
drivers/scsi/sg.c
+0
-88
drivers/scsi/sim710.c
drivers/scsi/sim710.c
+7
-13
drivers/scsi/u14-34f.c
drivers/scsi/u14-34f.c
+0
-3
drivers/scsi/wd7000.c
drivers/scsi/wd7000.c
+40
-7
drivers/scsi/wd7000.h
drivers/scsi/wd7000.h
+0
-64
No files found.
Documentation/scsi/scsi_mid_low_api.txt
View file @
8b0f29fb
...
...
@@ -22,13 +22,28 @@ has its own PCI device address. [The one-to-one correspondance between
a SCSI host and a PCI device is common but not required (e.g. with
ISA or MCA adapters).]
This version of the document roughly matches linux kernel version 2.5.63 .
Documentation
=============
There is a SCSI documentation directory within the kernel source tree.
That directory is typically /usr/src/linux/Documentation/scsi . Most
documents are in plain (i.e. ASCII) text. This file can be found in that
directory, named scsi_mid_low_api.txt . Many LLDs are documented there
(e.g. aic7xxx.txt). The SCSI mid-level is briefly described in scsi.txt
(with a url to a document describing the SCSI subsystem in the lk 2.4
series). Two upper level drivers have documents in that directory:
st.txt (SCSI tape driver) and scsi-generic.txt .
Some documentation (or urls) for LLDs may be in the C source code or
in the same directory. For example to find a url about the USB mass
storage driver see the /usr/src/linux/drivers/usb/storage directory.
The Linux kernel source Documentation/DocBook/scsidrivers.tmpl file
refers to this file. With the appropriate DocBook toolset, this permits
users to generate html, ps and pdf renderings of information within this
file (e.g. the interface functions).
This version of the document roughly matches lk 2.5.50 .
Driver structure
================
Traditionally a LLD for the SCSI subsystem has been at least two files in
...
...
@@ -100,12 +115,11 @@ the stability of the kernel (specifically the block and SCSI subsystems)
since the effected disk can be "cleaned up" the next time it is seen.
During LLD initialization the driver should register itself with the
appropriate IO bus that it expects to find HBA(s) (e.g. the PCI bus). This
can probably be done via sysfs (formerly known as driverfs). Any driver
parameters (especially those that are writeable after the driver is
loaded) could also be registered with sysfs at this point. At the end of
driver initialization the SCSI mid level is typically not aware of its
presence.
appropriate IO bus on which it expects to find HBA(s) (e.g. the PCI bus).
This can probably be done via sysfs. Any driver parameters (especially
those that are writeable after the driver is loaded) could also be
registered with sysfs at this point. At the end of driver initialization
the SCSI mid level is typically not aware of its presence.
At some later time, the LLD becomes aware of a HBA and what follows
is a typical sequence of calls between the LLD and the mid level.
...
...
@@ -149,7 +163,7 @@ It is practical for a LLD to keep track of struct Scsi_Host instances
(a pointer is returned by scsi_register() ) and struct scsi_device
instances (a pointer is passed as the parameter to slave_alloc() and
slave_configure() ). Both classes of instances are "owned" by the
mid-level. struct scsi_device
s
instances are freed after slave_destroy().
mid-level. struct scsi_device instances are freed after slave_destroy().
struct Scsi_Host instances are freed after scsi_unregister().
...
...
@@ -249,6 +263,8 @@ names all start with "scsi_".
/**
* scsi_add_host - perform sysfs registration and SCSI bus scan.
* @shost: pointer to scsi host instance
* @dev: pointer to struct device host instance of class type scsi
* (or related)
*
* Returns 0 on success, negative errno of failure (e.g. -ENOMEM)
*
...
...
@@ -256,7 +272,24 @@ names all start with "scsi_".
* successful call to scsi_register().
* Defined in drivers/scsi/hosts.c
**/
int scsi_add_host(struct Scsi_Host *shost)
int scsi_add_host(struct Scsi_Host *shost, struct device * dev)
/**
* scsi_add_timer - (re-)start timer on a SCSI command.
* @scmd: pointer to scsi command instance
* @timeout: duration of timeout in "jiffies"
* @complete: pointer to function to call if timeout expires
*
* Returns nothing
*
* Notes: All commands issued by upper levels already have a timeout
* associated with them. A LLD can use this function to change
* the existing timeout value.
* Defined in drivers/scsi/scsi_error.c
**/
void scsi_add_timer(Scsi_Cmnd *scmd, int timeout, void (*complete)
(Scsi_Cmnd *))
/**
...
...
@@ -321,6 +354,21 @@ unsigned char *scsi_bios_ptable(struct block_device *dev)
void scsi_block_requests(struct Scsi_Host * SHpnt)
/**
* scsi_delete_timer - cancel timer on a SCSI command.
* @scmd: pointer to scsi command instance
*
* Returns 1 if able to cancel timer else 0 (i.e. too late or already
* cancelled).
*
* Notes: All commands issued by upper levels already have a timeout
* associated with them. A LLD can use this function to cancel the
* timer.
* Defined in drivers/scsi/scsi_error.c
**/
int scsi_delete_timer(Scsi_Cmnd *scmd)
/**
* scsi_partsize - parse partition table into cylinders, heads + sectors
* @buf: pointer to partition table
...
...
@@ -429,6 +477,26 @@ void scsi_set_device(struct Scsi_Host * shost, struct device * dev)
int scsi_to_pci_dma_dir(unsigned char scsi_data_direction)
/**
* scsi_track_queue_full - track successive QUEUE_FULL events on given
* device to determine if and when there is a need
* to adjust the queue depth on the device.
* @SDptr: pointer to SCSI device instance
* @depth: Current number of outstanding SCSI commands on this device,
* not counting the one returned as QUEUE_FULL.
*
* Returns 0 - no change needed
* >0 - adjust queue depth to this new depth
* -1 - drop back to untagged operation using host->cmd_per_lun
* as the untagged command depth
*
* Notes: LLDs may call this at any time and we will do "The Right
* Thing"; interrupt context safe.
* Defined in drivers/scsi/scsi.c .
**/
int scsi_track_queue_full(Scsi_Device *SDptr, int depth)
/**
* scsi_unblock_requests - allow further commands to be queued to given host
*
...
...
@@ -1008,4 +1076,4 @@ The following people have contributed to this document:
Douglas Gilbert
dgilbert@interlog.com
2
9th November 2002
2
1st February 2003
drivers/scsi/53c700.c
View file @
8b0f29fb
...
...
@@ -122,6 +122,7 @@
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
#include <asm/dma.h>
...
...
@@ -325,6 +326,7 @@ NCR_700_detect(Scsi_Host_Template *tpnt,
host
->
max_lun
=
NCR_700_MAX_LUNS
;
host
->
unique_id
=
hostdata
->
base
;
host
->
base
=
hostdata
->
base
;
hostdata
->
eh_complete
=
NULL
;
host
->
hostdata
[
0
]
=
(
unsigned
long
)
hostdata
;
/* kick the chip */
NCR_700_writeb
(
0xff
,
host
,
CTEST9_REG
);
...
...
@@ -1525,6 +1527,9 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs)
hostdata
->
state
=
NCR_700_HOST_FREE
;
hostdata
->
cmd
=
NULL
;
/* signal back if this was an eh induced reset */
if
(
hostdata
->
eh_complete
!=
NULL
)
complete
(
hostdata
->
eh_complete
);
goto
out_unlock
;
}
else
if
(
sstat0
&
SELECTION_TIMEOUT
)
{
DEBUG
((
"scsi%d: (%d:%d) selection timeout
\n
"
,
...
...
@@ -1949,10 +1954,27 @@ NCR_700_abort(Scsi_Cmnd * SCp)
STATIC
int
NCR_700_bus_reset
(
Scsi_Cmnd
*
SCp
)
{
DECLARE_COMPLETION
(
complete
);
struct
NCR_700_Host_Parameters
*
hostdata
=
(
struct
NCR_700_Host_Parameters
*
)
SCp
->
device
->
host
->
hostdata
[
0
];
printk
(
KERN_INFO
"scsi%d (%d:%d) New error handler wants BUS reset, cmd %p
\n\t
"
,
SCp
->
device
->
host
->
host_no
,
SCp
->
device
->
id
,
SCp
->
device
->
lun
,
SCp
);
print_command
(
SCp
->
cmnd
);
/* In theory, eh_complete should always be null because the
* eh is single threaded, but just in case we're handling a
* reset via sg or something */
while
(
hostdata
->
eh_complete
!=
NULL
)
{
spin_unlock_irq
(
SCp
->
device
->
host
->
host_lock
);
schedule_timeout
(
HZ
/
10
);
spin_lock_irq
(
SCp
->
device
->
host
->
host_lock
);
}
hostdata
->
eh_complete
=
&
complete
;
NCR_700_internal_bus_reset
(
SCp
->
device
->
host
);
spin_unlock_irq
(
SCp
->
device
->
host
->
host_lock
);
wait_for_completion
(
&
complete
);
spin_lock_irq
(
SCp
->
device
->
host
->
host_lock
);
hostdata
->
eh_complete
=
NULL
;
return
SUCCESS
;
}
...
...
drivers/scsi/53c700.h
View file @
8b0f29fb
...
...
@@ -136,38 +136,6 @@ NCR_700_clear_flag(Scsi_Device *SDp, __u32 flag)
((
unsigned
long
)
SDp
->
hostdata
)
&=
~
(
flag
&
0xffff0000
);
}
/* These represent the Nexus hashing functions. A Nexus in SCSI terms
* just means the identification of an outstanding command, by ITL
* (Initiator Target Lun) or ITLQ (Initiator Target Lun Tag). I'm not
* very keen on XOR based hashes, so these are based on number theory
* instead. All you need to do is to fix your hash bucket size and
* then choose reasonable strides which are coprime with the chosen
* bucket size
*
* Note: this mathematical hash can be made very efficient, if the
* compiler is good at optimising: Choose the number of buckets to be
* 2^n and the modulo becomes a logical and with (2^n-1).
* Additionally, if you chose the coprimes of the form 2^n-2^n the
* multiplication can be done by a shift and an addition. */
#define MAX_ITL_HASH_BUCKETS 16
#define ITL_HASH_PRIME 7
#define MAX_ITLQ_HASH_BUCKETS 64
#define ITLQ_PUN_PRIME 7
#define ITLQ_LUN_PRIME 3
static
inline
int
hash_ITL
(
__u8
pun
,
__u8
lun
)
{
return
(
pun
*
ITL_HASH_PRIME
+
lun
)
%
MAX_ITL_HASH_BUCKETS
;
}
static
inline
int
hash_ITLQ
(
__u8
pun
,
__u8
lun
,
__u8
tag
)
{
return
(
pun
*
ITLQ_PUN_PRIME
+
lun
*
ITLQ_LUN_PRIME
+
tag
)
%
MAX_ITLQ_HASH_BUCKETS
;
}
struct
NCR_700_command_slot
{
struct
NCR_700_SG_List
SG
[
NCR_700_SG_SEGMENTS
+
1
];
struct
NCR_700_SG_List
*
pSG
;
...
...
@@ -186,12 +154,8 @@ struct NCR_700_command_slot {
/* if this command is a pci_single mapping, holds the dma address
* for later unmapping in the done routine */
dma_addr_t
dma_handle
;
/* Doubly linked ITL/ITLQ list kept in strict time order
* (latest at the back) */
/* historical remnant, now used to link free commands */
struct
NCR_700_command_slot
*
ITL_forw
;
struct
NCR_700_command_slot
*
ITL_back
;
struct
NCR_700_command_slot
*
ITLQ_forw
;
struct
NCR_700_command_slot
*
ITLQ_back
;
};
struct
NCR_700_Host_Parameters
{
...
...
@@ -238,20 +202,15 @@ struct NCR_700_Host_Parameters {
__u8
tag_negotiated
;
__u8
rev
;
__u8
reselection_id
;
/* flags for the host */
/* ITL list. ALL outstanding commands are hashed here in strict
* order, latest at the back */
struct
NCR_700_command_slot
*
ITL_Hash_forw
[
MAX_ITL_HASH_BUCKETS
];
struct
NCR_700_command_slot
*
ITL_Hash_back
[
MAX_ITL_HASH_BUCKETS
];
/* Only tagged outstanding commands are hashed here (also latest
* at the back) */
struct
NCR_700_command_slot
*
ITLQ_Hash_forw
[
MAX_ITLQ_HASH_BUCKETS
];
struct
NCR_700_command_slot
*
ITLQ_Hash_back
[
MAX_ITLQ_HASH_BUCKETS
];
/* Free list, singly linked by ITL_forw elements */
struct
NCR_700_command_slot
*
free_list
;
/* Completion for waited for ops, like reset, abort or
* device reset.
*
* NOTE: relies on single threading in the error handler to
* have only one outstanding at once */
struct
completion
*
eh_complete
;
};
/*
...
...
drivers/scsi/Kconfig
View file @
8b0f29fb
...
...
@@ -129,6 +129,7 @@ config SCSI_MULTI_LUN
config SCSI_REPORT_LUNS
bool "Build with SCSI REPORT LUNS support"
depends on SCSI
default y
help
If you want to build with SCSI REPORT LUNS support in the kernel, say Y here.
The REPORT LUNS command is useful for devices (such as disk arrays) with
...
...
drivers/scsi/eata.c
View file @
8b0f29fb
...
...
@@ -1228,7 +1228,6 @@ static int port_detect \
sh
[
j
]
->
unchecked_isa_dma
=
FALSE
;
else
{
unsigned
long
flags
;
scsi_register_blocked_host
(
sh
[
j
]);
sh
[
j
]
->
unchecked_isa_dma
=
TRUE
;
flags
=
claim_dma_lock
();
...
...
@@ -2353,8 +2352,6 @@ static int eata2x_release(struct Scsi_Host *shpnt) {
if
(
sh
[
j
]
==
NULL
)
panic
(
"%s: release, invalid Scsi_Host pointer.
\n
"
,
driver_name
);
if
(
sh
[
j
]
->
unchecked_isa_dma
)
scsi_deregister_blocked_host
(
sh
[
j
]);
for
(
i
=
0
;
i
<
sh
[
j
]
->
can_queue
;
i
++
)
if
((
&
HD
(
j
)
->
cp
[
i
])
->
sglist
)
kfree
((
&
HD
(
j
)
->
cp
[
i
])
->
sglist
);
...
...
drivers/scsi/eata_pio.c
View file @
8b0f29fb
...
...
@@ -46,10 +46,7 @@
* last change: 2002/11/02 OS: Linux 2.5.45 *
************************************************************/
/* Look in eata_pio.h for configuration information */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
...
...
@@ -59,15 +56,19 @@
#include <linux/pci.h>
#include <linux/proc_fs.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include "eata_pio.h"
#include "eata_dma_proc.h"
#include "scsi.h"
#include <linux/stat.h>
#include <linux/config.h>
/* for CONFIG_PCI */
#include <linux/config.h>
#include <linux/blk.h>
#include <linux/spinlock.h>
#include <asm/io.h>
#include "scsi.h"
#include "hosts.h"
#include <scsi/scsicam.h>
#include "eata_generic.h"
#include "eata_pio.h"
static
uint
ISAbases
[
MAXISA
]
=
{
0x1F0
,
0x170
,
0x330
,
0x230
...
...
@@ -82,16 +83,106 @@ static unsigned char EISAbases[] = {
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
};
static
uint
registered_HBAs
=
0
;
static
uint
registered_HBAs
;
static
struct
Scsi_Host
*
last_HBA
;
static
struct
Scsi_Host
*
first_HBA
;
static
unsigned
char
reg_IRQ
[];
static
unsigned
char
reg_IRQL
[];
static
unsigned
char
reg_IRQ
[
16
];
static
unsigned
char
reg_IRQL
[
16
];
static
unsigned
long
int_counter
;
static
unsigned
long
queue_counter
;
static
unsigned
long
int_counter
=
0
;
static
unsigned
long
queue_counter
=
0
;
/*
* eata_proc_info
* inout : decides on the direction of the dataflow and the meaning of the
* variables
* buffer: If inout==FALSE data is being written to it else read from it
* *start: If inout==FALSE start of the valid data in the buffer
* offset: If inout==FALSE offset from the beginning of the imaginary file
* from which we start writing into the buffer
* length: If inout==FALSE max number of bytes to be written into the buffer
* else number of bytes in the buffer
*/
static
int
eata_pio_proc_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
,
int
hostno
,
int
rw
)
{
struct
Scsi_Host
*
shost
;
struct
scsi_device
*
sdev
;
static
u8
buff
[
512
];
int
size
,
len
=
0
;
off_t
begin
=
0
,
pos
=
0
;
if
(
rw
)
return
-
ENOSYS
;
shost
=
scsi_host_hn_get
(
hostno
);
if
(
!
shost
)
return
-
EINVAL
;
if
(
offset
==
0
)
memset
(
buff
,
0
,
sizeof
(
buff
));
#include "eata_pio_proc.c"
size
=
sprintf
(
buffer
+
len
,
"EATA (Extended Attachment) PIO driver version: "
"%d.%d%s
\n
"
,
VER_MAJOR
,
VER_MINOR
,
VER_SUB
);
len
+=
size
;
pos
=
begin
+
len
;
size
=
sprintf
(
buffer
+
len
,
"queued commands: %10ld
\n
"
"processed interrupts:%10ld
\n
"
,
queue_counter
,
int_counter
);
len
+=
size
;
pos
=
begin
+
len
;
size
=
sprintf
(
buffer
+
len
,
"
\n
scsi%-2d: HBA %.10s
\n
"
,
shost
->
host_no
,
SD
(
shost
)
->
name
);
len
+=
size
;
pos
=
begin
+
len
;
size
=
sprintf
(
buffer
+
len
,
"Firmware revision: v%s
\n
"
,
SD
(
shost
)
->
revision
);
len
+=
size
;
pos
=
begin
+
len
;
size
=
sprintf
(
buffer
+
len
,
"IO: PIO
\n
"
);
len
+=
size
;
pos
=
begin
+
len
;
size
=
sprintf
(
buffer
+
len
,
"Base IO : %#.4x
\n
"
,
(
u32
)
shost
->
base
);
len
+=
size
;
pos
=
begin
+
len
;
size
=
sprintf
(
buffer
+
len
,
"Host Bus: %s
\n
"
,
(
SD
(
shost
)
->
bustype
==
'P'
)
?
"PCI "
:
(
SD
(
shost
)
->
bustype
==
'E'
)
?
"EISA"
:
"ISA "
);
len
+=
size
;
pos
=
begin
+
len
;
if
(
pos
<
offset
)
{
len
=
0
;
begin
=
pos
;
}
if
(
pos
>
offset
+
length
)
goto
stop_output
;
size
=
sprintf
(
buffer
+
len
,
"Attached devices: %s
\n
"
,
(
!
list_empty
(
&
shost
->
my_devices
))
?
""
:
"none"
);
len
+=
size
;
pos
=
begin
+
len
;
list_for_each_entry
(
sdev
,
&
shost
->
my_devices
,
siblings
)
{
proc_print_scsidevice
(
sdev
,
buffer
,
&
size
,
len
);
len
+=
size
;
pos
=
begin
+
len
;
if
(
pos
<
offset
)
{
len
=
0
;
begin
=
pos
;
}
if
(
pos
>
offset
+
length
)
goto
stop_output
;
}
stop_output:
DBG
(
DBG_PROC
,
printk
(
"2pos: %ld offset: %ld len: %d
\n
"
,
pos
,
offset
,
len
));
*
start
=
buffer
+
(
offset
-
begin
);
/* Start of wanted data */
len
-=
(
offset
-
begin
);
/* Start slop */
if
(
len
>
length
)
len
=
length
;
/* Ending slop */
DBG
(
DBG_PROC
,
printk
(
"3pos: %ld offset: %ld len: %d
\n
"
,
pos
,
offset
,
len
));
return
(
len
);
}
static
int
eata_pio_release
(
struct
Scsi_Host
*
sh
)
{
...
...
@@ -895,27 +986,19 @@ static int eata_pio_detect(Scsi_Host_Template * tpnt)
return
(
registered_HBAs
);
}
/* Eventually this will go into an include file, but this will be later */
static
Scsi_Host_Template
driver_template
=
EATA_PIO
;
static
Scsi_Host_Template
driver_template
=
{
.
proc_info
=
eata_pio_proc_info
,
.
name
=
"EATA (Extended Attachment) PIO driver"
,
.
detect
=
eata_pio_detect
,
.
release
=
eata_pio_release
,
.
queuecommand
=
eata_pio_queue
,
.
eh_abort_handler
=
eata_pio_abort
,
.
eh_host_reset_handler
=
eata_pio_host_reset
,
.
use_clustering
=
ENABLE_CLUSTERING
,
};
#include "scsi_module.c"
MODULE_AUTHOR
(
"Michael Neuffer, Alfred Arnold"
);
MODULE_DESCRIPTION
(
"EATA SCSI PIO driver"
);
MODULE_LICENSE
(
"GPL"
);
/*
* Overrides for Emacs so that we almost follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-indent-level: 4
* c-brace-imaginary-offset: 0
* c-brace-offset: -4
* c-argdecl-indent: 4
* c-label-offset: -4
* c-continued-statement-offset: 4
* c-continued-brace-offset: 0
* indent-tabs-mode: nil
* tab-width: 8
* End:
*/
#include "scsi_module.c"
drivers/scsi/eata_pio.h
View file @
8b0f29fb
...
...
@@ -9,13 +9,6 @@
#ifndef _EATA_PIO_H
#define _EATA_PIO_H
#include <linux/blk.h>
#include "scsi.h"
#include "hosts.h"
#include <scsi/scsicam.h>
#include "eata_generic.h"
#define VER_MAJOR 0
#define VER_MINOR 0
#define VER_SUB "1b"
...
...
@@ -57,22 +50,4 @@
#define DBG(x, y)
#endif
static
int
eata_pio_detect
(
Scsi_Host_Template
*
);
static
int
eata_pio_queue
(
Scsi_Cmnd
*
,
void
(
*
done
)
(
Scsi_Cmnd
*
));
static
int
eata_pio_abort
(
Scsi_Cmnd
*
);
static
int
eata_pio_host_reset
(
Scsi_Cmnd
*
);
static
int
eata_pio_proc_info
(
char
*
,
char
**
,
off_t
,
int
,
int
,
int
);
static
int
eata_pio_release
(
struct
Scsi_Host
*
);
#define EATA_PIO { \
.proc_info = eata_pio_proc_info,
/* procinfo */
\
.name = "EATA (Extended Attachment) PIO driver",\
.detect = eata_pio_detect, \
.release = eata_pio_release, \
.queuecommand = eata_pio_queue, \
.eh_abort_handler = eata_pio_abort, \
.eh_host_reset_handler = eata_pio_host_reset, \
.use_clustering = ENABLE_CLUSTERING \
}
#endif
/* _EATA_PIO_H */
drivers/scsi/eata_pio_proc.c
deleted
100644 → 0
View file @
227b2020
/*
* eata_set_info
* buffer : pointer to the data that has been written to the hostfile
* length : number of bytes written to the hostfile
* HBA_ptr: pointer to the Scsi_Host struct
*/
int
eata_pio_set_info
(
char
*
buffer
,
int
length
,
struct
Scsi_Host
*
HBA_ptr
)
{
DBG
(
DBG_PROC_WRITE
,
printk
(
"%s
\n
"
,
buffer
));
return
(
-
ENOSYS
);
/* Currently this is a no-op */
}
/*
* eata_proc_info
* inout : decides on the direction of the dataflow and the meaning of the
* variables
* buffer: If inout==FALSE data is being written to it else read from it
* *start: If inout==FALSE start of the valid data in the buffer
* offset: If inout==FALSE offset from the beginning of the imaginary file
* from which we start writing into the buffer
* length: If inout==FALSE max number of bytes to be written into the buffer
* else number of bytes in the buffer
*/
int
eata_pio_proc_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
,
int
hostno
,
int
inout
)
{
Scsi_Device
*
scd
;
struct
Scsi_Host
*
HBA_ptr
;
static
u8
buff
[
512
];
int
i
;
int
size
,
len
=
0
;
off_t
begin
=
0
;
off_t
pos
=
0
;
HBA_ptr
=
first_HBA
;
for
(
i
=
1
;
i
<=
registered_HBAs
;
i
++
)
{
if
(
HBA_ptr
->
host_no
==
hostno
)
break
;
HBA_ptr
=
SD
(
HBA_ptr
)
->
next
;
}
if
(
inout
==
TRUE
)
/* Has data been written to the file ? */
return
(
eata_pio_set_info
(
buffer
,
length
,
HBA_ptr
));
if
(
offset
==
0
)
memset
(
buff
,
0
,
sizeof
(
buff
));
size
=
sprintf
(
buffer
+
len
,
"EATA (Extended Attachment) PIO driver version: "
"%d.%d%s
\n
"
,
VER_MAJOR
,
VER_MINOR
,
VER_SUB
);
len
+=
size
;
pos
=
begin
+
len
;
size
=
sprintf
(
buffer
+
len
,
"queued commands: %10ld
\n
"
"processed interrupts:%10ld
\n
"
,
queue_counter
,
int_counter
);
len
+=
size
;
pos
=
begin
+
len
;
size
=
sprintf
(
buffer
+
len
,
"
\n
scsi%-2d: HBA %.10s
\n
"
,
HBA_ptr
->
host_no
,
SD
(
HBA_ptr
)
->
name
);
len
+=
size
;
pos
=
begin
+
len
;
size
=
sprintf
(
buffer
+
len
,
"Firmware revision: v%s
\n
"
,
SD
(
HBA_ptr
)
->
revision
);
len
+=
size
;
pos
=
begin
+
len
;
size
=
sprintf
(
buffer
+
len
,
"IO: PIO
\n
"
);
len
+=
size
;
pos
=
begin
+
len
;
size
=
sprintf
(
buffer
+
len
,
"Base IO : %#.4x
\n
"
,
(
u32
)
HBA_ptr
->
base
);
len
+=
size
;
pos
=
begin
+
len
;
size
=
sprintf
(
buffer
+
len
,
"Host Bus: %s
\n
"
,
(
SD
(
HBA_ptr
)
->
bustype
==
'P'
)
?
"PCI "
:
(
SD
(
HBA_ptr
)
->
bustype
==
'E'
)
?
"EISA"
:
"ISA "
);
len
+=
size
;
pos
=
begin
+
len
;
if
(
pos
<
offset
)
{
len
=
0
;
begin
=
pos
;
}
if
(
pos
>
offset
+
length
)
goto
stop_output
;
size
=
sprintf
(
buffer
+
len
,
"Attached devices: %s
\n
"
,
(
!
list_empty
(
&
HBA_ptr
->
my_devices
))
?
""
:
"none"
);
len
+=
size
;
pos
=
begin
+
len
;
list_for_each_entry
(
scd
,
&
HBA_ptr
->
my_devices
,
siblings
)
{
proc_print_scsidevice
(
scd
,
buffer
,
&
size
,
len
);
len
+=
size
;
pos
=
begin
+
len
;
if
(
pos
<
offset
)
{
len
=
0
;
begin
=
pos
;
}
if
(
pos
>
offset
+
length
)
goto
stop_output
;
}
stop_output:
DBG
(
DBG_PROC
,
printk
(
"2pos: %ld offset: %ld len: %d
\n
"
,
pos
,
offset
,
len
));
*
start
=
buffer
+
(
offset
-
begin
);
/* Start of wanted data */
len
-=
(
offset
-
begin
);
/* Start slop */
if
(
len
>
length
)
len
=
length
;
/* Ending slop */
DBG
(
DBG_PROC
,
printk
(
"3pos: %ld offset: %ld len: %d
\n
"
,
pos
,
offset
,
len
));
return
(
len
);
}
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-indent-level: 4
* c-brace-imaginary-offset: 0
* c-brace-offset: -4
* c-argdecl-indent: 4
* c-label-offset: -4
* c-continued-statement-offset: 4
* c-continued-brace-offset: 0
* tab-width: 8
* End:
*/
drivers/scsi/hosts.c
View file @
8b0f29fb
...
...
@@ -397,6 +397,7 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template *shost_tp, int xtr_bytes)
spin_lock_init
(
&
shost
->
default_lock
);
scsi_assign_lock
(
shost
,
&
shost
->
default_lock
);
INIT_LIST_HEAD
(
&
shost
->
my_devices
);
INIT_LIST_HEAD
(
&
shost
->
eh_cmd_q
);
init_waitqueue_head
(
&
shost
->
host_wait
);
shost
->
dma_channel
=
0xff
;
...
...
@@ -634,22 +635,9 @@ void scsi_host_busy_dec_and_test(struct Scsi_Host *shost, Scsi_Device *sdev)
spin_lock_irqsave
(
shost
->
host_lock
,
flags
);
shost
->
host_busy
--
;
sdev
->
device_busy
--
;
if
(
shost
->
in_recovery
&&
(
shost
->
host_busy
==
shost
->
host_failed
))
{
up
(
shost
->
eh_wait
);
SCSI_LOG_ERROR_RECOVERY
(
5
,
printk
(
"Waking error handler"
" thread
\n
"
));
}
spin_unlock_irqrestore
(
shost
->
host_lock
,
flags
);
}
void
scsi_host_failed_inc_and_test
(
struct
Scsi_Host
*
shost
)
{
unsigned
long
flags
;
spin_lock_irqsave
(
shost
->
host_lock
,
flags
);
shost
->
in_recovery
=
1
;
shost
->
host_failed
++
;
if
(
shost
->
host_busy
==
shost
->
host_failed
)
{
if
(
shost
->
in_recovery
&&
shost
->
host_failed
&&
(
shost
->
host_busy
==
shost
->
host_failed
))
{
up
(
shost
->
eh_wait
);
SCSI_LOG_ERROR_RECOVERY
(
5
,
printk
(
"Waking error handler"
" thread
\n
"
));
...
...
drivers/scsi/hosts.h
View file @
8b0f29fb
...
...
@@ -384,6 +384,7 @@ struct Scsi_Host
spinlock_t
default_lock
;
spinlock_t
*
host_lock
;
struct
list_head
eh_cmd_q
;
struct
task_struct
*
ehandler
;
/* Error recovery thread. */
struct
semaphore
*
eh_wait
;
/* The error recovery thread waits on
this. */
...
...
@@ -514,8 +515,6 @@ extern Scsi_Device * scsi_get_host_dev(struct Scsi_Host *);
extern
void
scsi_unblock_requests
(
struct
Scsi_Host
*
);
extern
void
scsi_block_requests
(
struct
Scsi_Host
*
);
extern
void
scsi_report_bus_reset
(
struct
Scsi_Host
*
,
int
);
extern
void
scsi_register_blocked_host
(
struct
Scsi_Host
*
);
extern
void
scsi_deregister_blocked_host
(
struct
Scsi_Host
*
);
static
inline
void
scsi_assign_lock
(
struct
Scsi_Host
*
shost
,
spinlock_t
*
lock
)
{
...
...
@@ -587,7 +586,6 @@ extern void scsi_host_init(void);
*/
extern
void
scsi_host_busy_inc
(
struct
Scsi_Host
*
,
Scsi_Device
*
);
extern
void
scsi_host_busy_dec_and_test
(
struct
Scsi_Host
*
,
Scsi_Device
*
);
extern
void
scsi_host_failed_inc_and_test
(
struct
Scsi_Host
*
);
/**
* scsi_find_device - find a device given the host
...
...
drivers/scsi/pluto.c
View file @
8b0f29fb
...
...
@@ -287,7 +287,7 @@ int pluto_release(struct Scsi_Host *host)
struct
pluto
*
pluto
=
(
struct
pluto
*
)
host
->
hostdata
;
fc_channel
*
fc
=
pluto
->
fc
;
if
(
fc
->
module
)
__MOD_DEC_USE_COUNT
(
fc
->
module
);
module_put
(
fc
->
module
);
fc
->
fcp_register
(
fc
,
TYPE_SCSI_FCP
,
1
);
PLND
((
" releasing pluto.
\n
"
));
...
...
drivers/scsi/scsi.c
View file @
8b0f29fb
...
...
@@ -36,9 +36,6 @@
* out_of_space hacks, D. Gilbert (dpg) 990608
*/
#define REVISION "Revision: 1.00"
#define VERSION "Id: scsi.c 1.00 2000/09/26"
#include <linux/config.h>
#include <linux/module.h>
...
...
@@ -790,13 +787,9 @@ static void scsi_softirq(struct softirq_action *h)
if
((
status_byte
(
SCpnt
->
result
)
&
CHECK_CONDITION
)
!=
0
)
{
SCSI_LOG_MLCOMPLETE
(
3
,
print_sense
(
"bh"
,
SCpnt
));
}
if
(
SCpnt
->
device
->
host
->
eh_wait
!=
NULL
)
{
scsi_eh_eflags_set
(
SCpnt
,
SCSI_EH_CMD_FAILED
|
SCSI_EH_CMD_ERR
);
SCpnt
->
owner
=
SCSI_OWNER_ERROR_HANDLER
;
SCpnt
->
state
=
SCSI_STATE_FAILED
;
scsi_host_failed_inc_and_test
(
SCpnt
->
device
->
host
);
}
else
{
if
(
!
scsi_eh_scmd_add
(
SCpnt
,
0
))
{
/*
* We only get here if the error
* recovery thread has died.
...
...
@@ -1147,29 +1140,6 @@ int scsi_dev_info_list_add_str (char *dev_list)
return
res
;
}
/**
* scsi_dev_list_init: set up the dynamic device list.
* @dev_list: string of device flags to add
*
* Description:
* Add command line @dev_list entries, then add
* scsi_static_device_list entries to the scsi device info list.
**/
static
void
scsi_dev_info_list_init
(
char
*
dev_list
)
{
int
i
;
if
(
scsi_dev_info_list_add_str
(
dev_list
)
==
-
ENOMEM
)
return
;
for
(
i
=
0
;
scsi_static_device_list
[
i
].
vendor
!=
NULL
;
i
++
)
if
(
scsi_dev_info_list_add
(
1
/* compatibile */
,
scsi_static_device_list
[
i
].
vendor
,
scsi_static_device_list
[
i
].
model
,
NULL
,
scsi_static_device_list
[
i
].
flags
)
==
-
ENOMEM
)
return
;
}
/**
* scsi_dev_info_list_delete: called from scsi.c:exit_scsi to remove
* the scsi_dev_info_list.
...
...
@@ -1186,6 +1156,37 @@ static void scsi_dev_info_list_delete (void)
}
}
/**
* scsi_dev_list_init: set up the dynamic device list.
* @dev_list: string of device flags to add
*
* Description:
* Add command line @dev_list entries, then add
* scsi_static_device_list entries to the scsi device info list.
**/
static
int
scsi_dev_info_list_init
(
char
*
dev_list
)
{
int
error
,
i
;
error
=
scsi_dev_info_list_add_str
(
dev_list
);
if
(
error
)
return
error
;
for
(
i
=
0
;
scsi_static_device_list
[
i
].
vendor
!=
NULL
;
i
++
)
{
error
=
scsi_dev_info_list_add
(
1
/* compatibile */
,
scsi_static_device_list
[
i
].
vendor
,
scsi_static_device_list
[
i
].
model
,
NULL
,
scsi_static_device_list
[
i
].
flags
);
if
(
error
)
break
;
}
if
(
error
)
scsi_dev_info_list_delete
();
return
error
;
}
/**
* get_device_flags - get device specific flags from the dynamic device
* list. Called during scan time.
...
...
@@ -1298,6 +1299,44 @@ void scsi_device_put(struct scsi_device *sdev)
module_put
(
sdev
->
host
->
hostt
->
module
);
}
/**
* scsi_set_device_offline - set scsi_device offline
* @sdev: pointer to struct scsi_device to offline.
*
* Locks: host_lock held on entry.
**/
void
scsi_set_device_offline
(
struct
scsi_device
*
sdev
)
{
struct
scsi_cmnd
*
scmd
;
int
cmds_active
=
0
;
unsigned
long
flags
;
sdev
->
online
=
FALSE
;
spin_lock_irqsave
(
&
sdev
->
list_lock
,
flags
);
list_for_each_entry
(
scmd
,
&
sdev
->
cmd_list
,
list
)
{
if
(
scmd
->
request
&&
scmd
->
request
->
rq_status
!=
RQ_INACTIVE
)
{
/*
* If we are unable to remove the timer, it means
* that the command has already timed out or
* finished.
*/
if
(
!
scsi_delete_timer
(
scmd
))
{
continue
;
}
++
cmds_active
;
scsi_eh_scmd_add
(
scmd
,
SCSI_EH_CANCEL_CMD
);
}
}
spin_unlock_irqrestore
(
&
sdev
->
list_lock
,
flags
);
if
(
!
cmds_active
)
{
/* FIXME: Send online state change hotplug event */
}
}
/*
* Function: scsi_slave_attach()
*
...
...
@@ -1437,17 +1476,38 @@ __setup("scsi_default_dev_flags=", setup_scsi_default_dev_flags);
#endif
/* FIXME(hch): add proper error handling */
static
int
__init
init_scsi
(
void
)
{
scsi_init_queue
();
scsi_init_procfs
();
devfs_mk_dir
(
NULL
,
"scsi"
,
NULL
);
int
error
;
error
=
scsi_init_queue
();
if
(
error
)
return
error
;
error
=
scsi_init_procfs
();
if
(
error
)
goto
cleanup_queue
;
error
=
scsi_dev_info_list_init
(
scsi_dev_flags
);
if
(
error
)
goto
cleanup_procfs
;
error
=
scsi_sysfs_register
();
if
(
error
)
goto
cleanup_devlist
;
scsi_host_init
();
scsi_dev_info_list_init
(
scsi_dev_flags
);
scsi_sysfs_register
();
devfs_mk_dir
(
NULL
,
"scsi"
,
NULL
);
open_softirq
(
SCSI_SOFTIRQ
,
scsi_softirq
,
NULL
);
printk
(
KERN_NOTICE
"SCSI subsystem initialized
\n
"
);
return
0
;
cleanup_devlist:
scsi_dev_info_list_delete
();
cleanup_procfs:
scsi_exit_procfs
();
cleanup_queue:
scsi_exit_queue
();
printk
(
KERN_ERR
"SCSI subsystem failed to initialize, error = %d
\n
"
,
-
error
);
return
error
;
}
static
void
__exit
exit_scsi
(
void
)
...
...
drivers/scsi/scsi.h
View file @
8b0f29fb
...
...
@@ -455,6 +455,7 @@ extern int scsi_slave_attach(struct scsi_device *);
extern
void
scsi_slave_detach
(
struct
scsi_device
*
);
extern
int
scsi_device_get
(
struct
scsi_device
*
);
extern
void
scsi_device_put
(
struct
scsi_device
*
);
extern
void
scsi_set_device_offline
(
struct
scsi_device
*
);
extern
void
scsi_done
(
Scsi_Cmnd
*
SCpnt
);
extern
void
scsi_finish_command
(
Scsi_Cmnd
*
);
extern
int
scsi_retry_command
(
Scsi_Cmnd
*
);
...
...
@@ -726,6 +727,7 @@ struct scsi_cmnd {
struct
list_head
list
;
/* scsi_cmnd participates in queue lists */
struct
list_head
eh_entry
;
/* entry for the host eh_cmd_q */
int
eh_state
;
/* Used for state tracking in error handlr */
int
eh_eflags
;
/* Used by error handlr */
void
(
*
done
)
(
struct
scsi_cmnd
*
);
/* Mid-level done function */
...
...
@@ -850,6 +852,7 @@ struct scsi_cmnd {
*/
#define SCSI_MLQUEUE_HOST_BUSY 0x1055
#define SCSI_MLQUEUE_DEVICE_BUSY 0x1056
#define SCSI_MLQUEUE_EH_RETRY 0x1057
/*
* old style reset request from external source
...
...
@@ -960,13 +963,13 @@ static inline Scsi_Cmnd *scsi_find_tag(Scsi_Device *SDpnt, int tag) {
/*
* Scsi Error Handler Flags
*/
#define SCSI_EH_CMD_ERR 0x0001
/* Orig cmd error'd */
#define SCSI_EH_CMD_FAILED 0x0002
/* Orig cmd error type failed */
#define SCSI_EH_CMD_TIMEOUT 0x0004
/* Orig cmd error type timeout */
#define SCSI_EH_REC_TIMEOUT 0x0008
/* Recovery cmd timeout */
#define SCSI_EH_CANCEL_CMD 0x0001
/* Cancel this cmd */
#define SCSI_EH_REC_TIMEOUT 0x0002
/* EH retry timed out */
#define SCSI_SENSE_VALID(scmd) ((scmd->sense_buffer[0] & 0x70) == 0x70)
extern
int
scsi_eh_scmd_add
(
struct
scsi_cmnd
*
,
int
);
int
scsi_set_medium_removal
(
Scsi_Device
*
dev
,
char
state
);
extern
int
scsi_device_register
(
struct
scsi_device
*
);
...
...
drivers/scsi/scsi_error.c
View file @
8b0f29fb
This diff is collapsed.
Click to expand it.
drivers/scsi/scsi_lib.c
View file @
8b0f29fb
...
...
@@ -117,7 +117,7 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
*/
if
(
reason
==
SCSI_MLQUEUE_HOST_BUSY
)
host
->
host_blocked
=
host
->
max_host_blocked
;
else
else
if
(
reason
==
SCSI_MLQUEUE_DEVICE_BUSY
)
device
->
device_blocked
=
device
->
max_device_blocked
;
/*
...
...
@@ -1340,23 +1340,6 @@ void scsi_report_bus_reset(struct Scsi_Host *shost, int channel)
}
}
/*
* FIXME(eric) - these are empty stubs for the moment. I need to re-implement
* host blocking from scratch. The theory is that hosts that wish to block
* will register/deregister using these functions instead of the old way
* of setting the wish_block flag.
*
* The details of the implementation remain to be settled, however the
* stubs are here now so that the actual drivers will properly compile.
*/
void
scsi_register_blocked_host
(
struct
Scsi_Host
*
shost
)
{
}
void
scsi_deregister_blocked_host
(
struct
Scsi_Host
*
shost
)
{
}
int
__init
scsi_init_queue
(
void
)
{
int
i
;
...
...
drivers/scsi/scsi_scan.c
View file @
8b0f29fb
...
...
@@ -84,6 +84,7 @@ struct dev_info scsi_static_device_list[] __initdata = {
{
"NEC"
,
"CD-ROM DRIVE:841"
,
"1.0"
,
BLIST_NOLUN
},
/* locks up */
{
"PHILIPS"
,
"PCA80SC"
,
"V4-2"
,
BLIST_NOLUN
},
/* responds to all lun */
{
"RODIME"
,
"RO3000S"
,
"2.33"
,
BLIST_NOLUN
},
/* locks up */
{
"SUN"
,
"SENA"
,
NULL
,
BLIST_NOLUN
},
/* responds to all luns */
/*
* The following causes a failed REQUEST SENSE on lun 1 for
* aha152x controller, which causes SCSI code to reset bus.
...
...
@@ -128,6 +129,7 @@ struct dev_info scsi_static_device_list[] __initdata = {
{
"MITSUMI"
,
"CD-R CR-2201CS"
,
"6119"
,
BLIST_NOLUN
},
/* locks up */
{
"RELISYS"
,
"Scorpio"
,
NULL
,
BLIST_NOLUN
},
/* responds to all lun */
{
"MICROTEK"
,
"ScanMaker II"
,
"5.61"
,
BLIST_NOLUN
},
/* responds to all lun */
{
"NEC"
,
"D3856"
,
"0009"
,
BLIST_NOLUN
},
/*
* Other types of devices that have special flags.
...
...
drivers/scsi/scsi_syms.c
View file @
8b0f29fb
...
...
@@ -74,12 +74,11 @@ EXPORT_SYMBOL(scsi_sleep);
EXPORT_SYMBOL
(
scsi_io_completion
);
EXPORT_SYMBOL
(
scsi_register_blocked_host
);
EXPORT_SYMBOL
(
scsi_deregister_blocked_host
);
EXPORT_SYMBOL
(
scsi_slave_attach
);
EXPORT_SYMBOL
(
scsi_slave_detach
);
EXPORT_SYMBOL
(
scsi_device_get
);
EXPORT_SYMBOL
(
scsi_device_put
);
EXPORT_SYMBOL
(
scsi_set_device_offline
);
/*
* This symbol is for the highlevel drivers (e.g. sg) only.
...
...
drivers/scsi/scsi_sysfs.c
View file @
8b0f29fb
...
...
@@ -14,6 +14,44 @@
#include "scsi.h"
#include "hosts.h"
/*
* shost_show_function: macro to create an attr function that can be used to
* show a non-bit field.
*/
#define shost_show_function(field, format_string) \
static ssize_t \
show_##field (struct device *dev, char *buf) \
{ \
struct Scsi_Host *shost = to_scsi_host(dev); \
return snprintf (buf, 20, format_string, shost->field); \
}
/*
* shost_rd_attr: macro to create a function and attribute variable for a
* read only field.
*/
#define shost_rd_attr(field, format_string) \
shost_show_function(field, format_string) \
static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL)
/*
* Create the actual show/store functions and data structures.
*/
shost_rd_attr
(
unique_id
,
"%u
\n
"
);
shost_rd_attr
(
host_busy
,
"%hu
\n
"
);
shost_rd_attr
(
cmd_per_lun
,
"%hd
\n
"
);
shost_rd_attr
(
sg_tablesize
,
"%hu
\n
"
);
shost_rd_attr
(
unchecked_isa_dma
,
"%d
\n
"
);
static
struct
device_attribute
*
const
shost_attrs
[]
=
{
&
dev_attr_unique_id
,
&
dev_attr_host_busy
,
&
dev_attr_cmd_per_lun
,
&
dev_attr_sg_tablesize
,
&
dev_attr_unchecked_isa_dma
,
};
/**
* scsi_host_class_name_show - copy out the SCSI host name
* @dev: device to check
...
...
@@ -39,12 +77,21 @@ DEVICE_ATTR(class_name, S_IRUGO, scsi_host_class_name_show, NULL);
static
int
scsi_host_class_add_dev
(
struct
device
*
dev
)
{
int
i
;
device_create_file
(
dev
,
&
dev_attr_class_name
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
shost_attrs
);
i
++
)
device_create_file
(
dev
,
shost_attrs
[
i
]);
return
0
;
}
static
void
scsi_host_class_rm_dev
(
struct
device
*
dev
)
{
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
shost_attrs
);
i
++
)
device_remove_file
(
dev
,
shost_attrs
[
i
]);
device_remove_file
(
dev
,
&
dev_attr_class_name
);
}
...
...
@@ -129,10 +176,10 @@ void scsi_upper_driver_unregister(struct Scsi_Device_Template *sdev_tp)
/*
* show_function: macro to create an attr function that can be used to
* s
dev_s
how_function: macro to create an attr function that can be used to
* show a non-bit field.
*/
#define show_function(field, format_string) \
#define s
dev_s
how_function(field, format_string) \
static ssize_t \
show_##field (struct device *dev, char *buf) \
{ \
...
...
@@ -146,7 +193,7 @@ show_##field (struct device *dev, char *buf) \
* read only field.
*/
#define sdev_rd_attr(field, format_string) \
show_function(field, format_string) \
s
dev_s
how_function(field, format_string) \
static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL)
...
...
@@ -155,27 +202,27 @@ static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL)
* read/write field.
*/
#define sdev_rw_attr(field, format_string) \
show_function(field, format_string) \
s
dev_s
how_function(field, format_string) \
\
static ssize_t \
store_##field (struct device *dev, const char *buf, size_t count) \
s
dev_s
tore_##field (struct device *dev, const char *buf, size_t count) \
{ \
struct scsi_device *sdev; \
sdev = to_scsi_device(dev); \
snscanf (buf, 20, format_string, &sdev->field); \
return count; \
} \
static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, show_##field, store_##field)
static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, show_##field, s
dev_s
tore_##field)
/*
* sdev_rd_attr: create a function and attribute variable for a
* read/write bit field.
*/
#define sdev_rw_attr_bit(field) \
show_function(field, "%d\n") \
s
dev_s
how_function(field, "%d\n") \
\
static ssize_t \
store_##field (struct device *dev, const char *buf, size_t count) \
s
dev_s
tore_##field (struct device *dev, const char *buf, size_t count) \
{ \
int ret; \
struct scsi_device *sdev; \
...
...
@@ -187,7 +234,7 @@ store_##field (struct device *dev, const char *buf, size_t count) \
} \
return ret; \
} \
static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, show_##field, store_##field)
static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, show_##field, s
dev_s
tore_##field)
/*
* scsi_sdev_check_buf_bit: return 0 if buf is "0", return 1 if buf is "1",
...
...
drivers/scsi/sg.c
View file @
8b0f29fb
...
...
@@ -2689,18 +2689,6 @@ static int sg_proc_devstrs_read(char *buffer, char **start, off_t offset,
int
size
,
int
*
eof
,
void
*
data
);
static
int
sg_proc_devstrs_info
(
char
*
buffer
,
int
*
len
,
off_t
*
begin
,
off_t
offset
,
int
size
);
static
int
sg_proc_host_read
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
size
,
int
*
eof
,
void
*
data
);
static
int
sg_proc_host_info
(
char
*
buffer
,
int
*
len
,
off_t
*
begin
,
off_t
offset
,
int
size
);
static
int
sg_proc_hosthdr_read
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
size
,
int
*
eof
,
void
*
data
);
static
int
sg_proc_hosthdr_info
(
char
*
buffer
,
int
*
len
,
off_t
*
begin
,
off_t
offset
,
int
size
);
static
int
sg_proc_hoststrs_read
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
size
,
int
*
eof
,
void
*
data
);
static
int
sg_proc_hoststrs_info
(
char
*
buffer
,
int
*
len
,
off_t
*
begin
,
off_t
offset
,
int
size
);
static
int
sg_proc_version_read
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
size
,
int
*
eof
,
void
*
data
);
static
int
sg_proc_version_info
(
char
*
buffer
,
int
*
len
,
off_t
*
begin
,
...
...
@@ -2708,7 +2696,6 @@ static int sg_proc_version_info(char *buffer, int *len, off_t * begin,
static
read_proc_t
*
sg_proc_leaf_reads
[]
=
{
sg_proc_adio_read
,
sg_proc_dressz_read
,
sg_proc_debug_read
,
sg_proc_dev_read
,
sg_proc_devhdr_read
,
sg_proc_devstrs_read
,
sg_proc_host_read
,
sg_proc_hosthdr_read
,
sg_proc_hoststrs_read
,
sg_proc_version_read
};
static
write_proc_t
*
sg_proc_leaf_writes
[]
=
{
...
...
@@ -3033,81 +3020,6 @@ sg_proc_devstrs_info(char *buffer, int *len, off_t * begin,
return
1
;
}
static
int
sg_proc_host_read
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
size
,
int
*
eof
,
void
*
data
)
{
SG_PROC_READ_FN
(
sg_proc_host_info
);
}
static
int
sg_proc_host_info
(
char
*
buffer
,
int
*
len
,
off_t
*
begin
,
off_t
offset
,
int
size
)
{
struct
Scsi_Host
*
shp
;
int
k
;
for
(
k
=
0
,
shp
=
scsi_host_get_next
(
NULL
);
shp
;
shp
=
scsi_host_get_next
(
shp
),
++
k
)
{
for
(;
k
<
shp
->
host_no
;
++
k
)
PRINT_PROC
(
"-1
\t
-1
\t
-1
\t
-1
\t
-1
\t
-1
\n
"
);
PRINT_PROC
(
"%u
\t
%hu
\t
%hd
\t
%hu
\t
%d
\t
%d
\n
"
,
shp
->
unique_id
,
shp
->
host_busy
,
shp
->
cmd_per_lun
,
shp
->
sg_tablesize
,
(
int
)
shp
->
unchecked_isa_dma
,
(
int
)
shp
->
hostt
->
emulated
);
}
return
1
;
}
static
int
sg_proc_hosthdr_read
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
size
,
int
*
eof
,
void
*
data
)
{
SG_PROC_READ_FN
(
sg_proc_hosthdr_info
);
}
static
int
sg_proc_hosthdr_info
(
char
*
buffer
,
int
*
len
,
off_t
*
begin
,
off_t
offset
,
int
size
)
{
PRINT_PROC
(
"uid
\t
busy
\t
cpl
\t
scatg
\t
isa
\t
emul
\n
"
);
return
1
;
}
static
int
sg_proc_hoststrs_read
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
size
,
int
*
eof
,
void
*
data
)
{
SG_PROC_READ_FN
(
sg_proc_hoststrs_info
);
}
#define SG_MAX_HOST_STR_LEN 256
static
int
sg_proc_hoststrs_info
(
char
*
buffer
,
int
*
len
,
off_t
*
begin
,
off_t
offset
,
int
size
)
{
struct
Scsi_Host
*
shp
;
int
k
;
char
buff
[
SG_MAX_HOST_STR_LEN
];
char
*
cp
;
for
(
k
=
0
,
shp
=
scsi_host_get_next
(
NULL
);
shp
;
shp
=
scsi_host_get_next
(
shp
),
++
k
)
{
for
(;
k
<
shp
->
host_no
;
++
k
)
PRINT_PROC
(
"<no active host>
\n
"
);
strncpy
(
buff
,
shp
->
hostt
->
info
?
shp
->
hostt
->
info
(
shp
)
:
(
shp
->
hostt
->
name
?
shp
->
hostt
->
name
:
"<no name>"
),
SG_MAX_HOST_STR_LEN
);
buff
[
SG_MAX_HOST_STR_LEN
-
1
]
=
'\0'
;
for
(
cp
=
buff
;
*
cp
;
++
cp
)
{
if
(
'\n'
==
*
cp
)
*
cp
=
' '
;
/* suppress imbedded newlines */
}
PRINT_PROC
(
"%s
\n
"
,
buff
);
}
return
1
;
}
static
int
sg_proc_version_read
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
size
,
int
*
eof
,
void
*
data
)
...
...
drivers/scsi/sim710.c
View file @
8b0f29fb
...
...
@@ -328,7 +328,7 @@ struct eisa_driver sim710_eisa_driver = {
static
int
__init
sim710_init
(
void
)
{
int
err
=
-
ENODEV
,
err2
;
int
err
=
-
ENODEV
;
#ifdef MODULE
if
(
sim710
)
...
...
@@ -336,23 +336,17 @@ static int __init sim710_init(void)
#endif
#ifdef CONFIG_MCA
if
(
MCA_bus
)
err
=
mca_register_driver
(
&
sim710_mca_driver
);
err
=
mca_register_driver
(
&
sim710_mca_driver
);
#endif
#ifdef CONFIG_EISA
err2
=
eisa_driver_register
(
&
sim710_eisa_driver
);
/*
* The eise_driver_register return values are strange. I have
* no idea why we don't just use river_register directly anyway..
*/
if
(
err2
==
1
)
err2
=
0
;
err
=
eisa_driver_register
(
&
sim710_eisa_driver
);
#endif
/* FIXME: what we'd really like to return here is -ENODEV if
* no devices have actually been found. Instead, the err
* above actually only reports problems with kobject_register,
* so for the moment return success */
if
(
err
<
0
||
err2
<
0
)
return
(
err
<
0
)
?
err
:
err2
;
return
0
;
}
...
...
drivers/scsi/u14-34f.c
View file @
8b0f29fb
...
...
@@ -905,7 +905,6 @@ static int port_detect \
}
else
{
unsigned
long
flags
;
scsi_register_blocked_host
(
sh
[
j
]);
sh
[
j
]
->
unchecked_isa_dma
=
TRUE
;
flags
=
claim_dma_lock
();
...
...
@@ -1911,8 +1910,6 @@ static int u14_34f_release(struct Scsi_Host *shpnt) {
if
(
sh
[
j
]
==
NULL
)
panic
(
"%s: release, invalid Scsi_Host pointer.
\n
"
,
driver_name
);
if
(
sh
[
j
]
->
unchecked_isa_dma
)
scsi_deregister_blocked_host
(
sh
[
j
]);
for
(
i
=
0
;
i
<
sh
[
j
]
->
can_queue
;
i
++
)
if
((
&
HD
(
j
)
->
cp
[
i
])
->
sglist
)
kfree
((
&
HD
(
j
)
->
cp
[
i
])
->
sglist
);
...
...
drivers/scsi/wd7000.c
View file @
8b0f29fb
...
...
@@ -158,6 +158,11 @@
* Clean up delay to udelay, and yielding sleeps
* Make host reset actually reset the card
* Make everything static
*
* 2003/02/12 - Christoph Hellwig <hch@infradead.org>
*
* Cleaned up host template defintion
* Removed now obsolete wd7000.h
*/
#include <linux/module.h>
...
...
@@ -170,8 +175,8 @@
#include <linux/ioport.h>
#include <linux/proc_fs.h>
#include <linux/blk.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/stat.h>
#include <asm/system.h>
#include <asm/dma.h>
...
...
@@ -179,9 +184,9 @@
#include "scsi.h"
#include "hosts.h"
#include <scsi/scsicam.h>
#define ANY2SCSI_INLINE
/* undef this to use old macros */
#undef WD7000_DEBUG
/* general debug */
#ifdef WD7000_DEBUG
...
...
@@ -190,9 +195,6 @@
#define dprintk(format,args...)
#endif
#include "wd7000.h"
#include <linux/stat.h>
/*
* Mailbox structure sizes.
* I prefer to keep the number of ICMBs much larger than the number of
...
...
@@ -211,6 +213,21 @@
*/
#define MAX_SCBS 32
/*
* In this version, sg_tablesize now defaults to WD7000_SG, and will
* be set to SG_NONE for older boards. This is the reverse of the
* previous default, and was changed so that the driver-level
* Scsi_Host_Template would reflect the driver's support for scatter/
* gather.
*
* Also, it has been reported that boards at Revision 6 support scatter/
* gather, so the new definition of an "older" board has been changed
* accordingly.
*/
#define WD7000_Q 16
#define WD7000_SG 16
/*
* WD7000-specific mailbox structure
*
...
...
@@ -1737,7 +1754,23 @@ MODULE_AUTHOR("Thomas Wuensche, John Boyd, Miroslav Zagorac");
MODULE_DESCRIPTION
(
"Driver for the WD7000 series ISA controllers"
);
MODULE_LICENSE
(
"GPL"
);
/* Eventually this will go into an include file, but this will be later */
static
Scsi_Host_Template
driver_template
=
WD7000
;
static
Scsi_Host_Template
driver_template
=
{
.
proc_name
=
"wd7000"
,
.
proc_info
=
wd7000_proc_info
,
.
name
=
"Western Digital WD-7000"
,
.
detect
=
wd7000_detect
,
.
command
=
wd7000_command
,
.
queuecommand
=
wd7000_queuecommand
,
.
eh_bus_reset_handler
=
wd7000_bus_reset
,
.
eh_device_reset_handler
=
wd7000_device_reset
,
.
eh_host_reset_handler
=
wd7000_host_reset
,
.
bios_param
=
wd7000_biosparam
,
.
can_queue
=
WD7000_Q
,
.
this_id
=
7
,
.
sg_tablesize
=
WD7000_SG
,
.
cmd_per_lun
=
1
,
.
unchecked_isa_dma
=
1
,
.
use_clustering
=
ENABLE_CLUSTERING
,
};
#include "scsi_module.c"
drivers/scsi/wd7000.h
deleted
100644 → 0
View file @
227b2020
#ifndef _WD7000_H
/* $Id: $
*
* Header file for the WD-7000 driver for Linux
*
* John Boyd <boyd@cis.ohio-state.edu> Jan 1994:
* This file has been reduced to only the definitions needed for the
* WD7000 host structure.
*
* Revision by Miroslav Zagorac <zaga@fly.cc.fer.hr> Jun 1997.
*/
#include <linux/types.h>
static
int
wd7000_set_info
(
char
*
buffer
,
int
length
,
struct
Scsi_Host
*
host
);
static
int
wd7000_proc_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
,
int
hostno
,
int
inout
);
static
int
wd7000_detect
(
Scsi_Host_Template
*
);
static
int
wd7000_command
(
Scsi_Cmnd
*
);
static
int
wd7000_queuecommand
(
Scsi_Cmnd
*
,
void
(
*
done
)
(
Scsi_Cmnd
*
));
static
int
wd7000_abort
(
Scsi_Cmnd
*
);
static
int
wd7000_bus_reset
(
Scsi_Cmnd
*
);
static
int
wd7000_host_reset
(
Scsi_Cmnd
*
);
static
int
wd7000_device_reset
(
Scsi_Cmnd
*
);
static
int
wd7000_biosparam
(
struct
scsi_device
*
,
struct
block_device
*
,
sector_t
,
int
*
);
#ifndef NULL
#define NULL 0L
#endif
/*
* In this version, sg_tablesize now defaults to WD7000_SG, and will
* be set to SG_NONE for older boards. This is the reverse of the
* previous default, and was changed so that the driver-level
* Scsi_Host_Template would reflect the driver's support for scatter/
* gather.
*
* Also, it has been reported that boards at Revision 6 support scatter/
* gather, so the new definition of an "older" board has been changed
* accordingly.
*/
#define WD7000_Q 16
#define WD7000_SG 16
#define WD7000 { \
.proc_name = "wd7000", \
.proc_info = wd7000_proc_info, \
.name = "Western Digital WD-7000", \
.detect = wd7000_detect, \
.command = wd7000_command, \
.queuecommand = wd7000_queuecommand, \
.eh_bus_reset_handler = wd7000_bus_reset, \
.eh_device_reset_handler = wd7000_device_reset, \
.eh_host_reset_handler = wd7000_host_reset, \
.bios_param = wd7000_biosparam, \
.can_queue = WD7000_Q, \
.this_id = 7, \
.sg_tablesize = WD7000_SG, \
.cmd_per_lun = 1, \
.unchecked_isa_dma = 1, \
.use_clustering = ENABLE_CLUSTERING, \
}
#endif
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