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
3793c9b9
Commit
3793c9b9
authored
Nov 23, 2007
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import 1.2.5
parent
98c4b45f
Changes
22
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
557 additions
and
326 deletions
+557
-326
Makefile
Makefile
+1
-1
README
README
+3
-3
drivers/block/ll_rw_blk.c
drivers/block/ll_rw_blk.c
+30
-22
drivers/char/ChangeLog
drivers/char/ChangeLog
+8
-0
drivers/char/serial.c
drivers/char/serial.c
+26
-7
drivers/net/lance.c
drivers/net/lance.c
+1
-1
drivers/net/ne.c
drivers/net/ne.c
+8
-1
drivers/net/wavelan.c
drivers/net/wavelan.c
+113
-14
drivers/scsi/Makefile
drivers/scsi/Makefile
+3
-1
drivers/scsi/buslogic.c
drivers/scsi/buslogic.c
+133
-172
drivers/scsi/eata_dma.c
drivers/scsi/eata_dma.c
+175
-86
drivers/scsi/eata_dma.h
drivers/scsi/eata_dma.h
+25
-4
drivers/scsi/scsi.c
drivers/scsi/scsi.c
+2
-1
drivers/scsi/scsi.h
drivers/scsi/scsi.h
+11
-0
drivers/scsi/sd.c
drivers/scsi/sd.c
+3
-6
drivers/scsi/st.c
drivers/scsi/st.c
+1
-2
fs/isofs/inode.c
fs/isofs/inode.c
+1
-1
include/linux/major.h
include/linux/major.h
+2
-2
include/linux/serial.h
include/linux/serial.h
+1
-1
include/linux/tqueue.h
include/linux/tqueue.h
+1
-1
kernel/ksyms.c
kernel/ksyms.c
+7
-0
kernel/sched.c
kernel/sched.c
+2
-0
No files found.
Makefile
View file @
3793c9b9
VERSION
=
1
PATCHLEVEL
=
2
SUBLEVEL
=
4
SUBLEVEL
=
5
ARCH
=
i386
...
...
README
View file @
3793c9b9
...
...
@@ -124,15 +124,15 @@ COMPILING the kernel:
floppy.
If you boot Linux from the hard drive, chances are you use LILO which
uses the kernel image as specified in the file /etc/lilo
/config
. The
uses the kernel image as specified in the file /etc/lilo
.conf
. The
kernel image file is usually /vmlinuz, or /zImage, or /etc/zImage.
To use the new kernel, copy the new image over the old one (save a
backup of the original!). Then, you MUST RERUN LILO to update the
loading map!! If you don't, you won't be able to boot the new kernel
image.
Reinstalling LILO is usually a matter of running /
etc/lilo/install
.
You may wish to edit /etc/lilo
/config
to specify an entry for your
Reinstalling LILO is usually a matter of running /
sbin/lilo
.
You may wish to edit /etc/lilo
.conf
to specify an entry for your
old kernel image (say, /vmlinux.old) in case the new one does not
work. See the LILO docs for more information.
...
...
drivers/block/ll_rw_blk.c
View file @
3793c9b9
...
...
@@ -169,20 +169,40 @@ static inline struct request * get_request(int n, int dev)
/*
* wait until a free request in the first N entries is available.
* NOTE: interrupts must be disabled on the way in, and will still
* be disabled on the way out.
*/
static
inline
struct
request
*
get_request_wait
(
int
n
,
int
dev
)
static
struct
request
*
__
get_request_wait
(
int
n
,
int
dev
)
{
register
struct
request
*
req
;
struct
wait_queue
wait
=
{
current
,
NULL
};
while
((
req
=
get_request
(
n
,
dev
))
==
NULL
)
{
add_wait_queue
(
&
wait_for_request
,
&
wait
);
for
(;;)
{
unplug_device
(
MAJOR
(
dev
)
+
blk_dev
);
sleep_on
(
&
wait_for_request
);
current
->
state
=
TASK_UNINTERRUPTIBLE
;
cli
();
req
=
get_request
(
n
,
dev
);
sti
();
if
(
req
)
break
;
schedule
();
}
remove_wait_queue
(
&
wait_for_request
,
&
wait
);
current
->
state
=
TASK_RUNNING
;
return
req
;
}
static
inline
struct
request
*
get_request_wait
(
int
n
,
int
dev
)
{
register
struct
request
*
req
;
cli
();
req
=
get_request
(
n
,
dev
);
sti
();
if
(
req
)
return
req
;
return
__get_request_wait
(
n
,
dev
);
}
/* RO fail safe mechanism */
static
long
ro_bits
[
MAX_BLKDEV
][
8
];
...
...
@@ -303,9 +323,7 @@ static void make_request(int major,int rw, struct buffer_head * bh)
*/
max_req
=
(
rw
==
READ
)
?
NR_REQUEST
:
((
NR_REQUEST
*
2
)
/
3
);
/* big loop: look for a free request. */
repeat:
/* look for a free request. */
cli
();
/* The scsi disk drivers and the IDE driver completely remove the request
...
...
@@ -363,23 +381,17 @@ static void make_request(int major,int rw, struct buffer_head * bh)
/* find an unused request. */
req
=
get_request
(
max_req
,
bh
->
b_dev
);
sti
();
/* if no request available: if rw_ahead, forget it; otherwise try again. */
if
(
!
req
)
{
/* if no request available: if rw_ahead, forget it; otherwise try again
blocking.
. */
if
(
!
req
)
{
if
(
rw_ahead
)
{
sti
();
unlock_buffer
(
bh
);
return
;
}
unplug_device
(
major
+
blk_dev
);
sleep_on
(
&
wait_for_request
);
sti
();
goto
repeat
;
req
=
__get_request_wait
(
max_req
,
bh
->
b_dev
);
}
/* we found a request. */
sti
();
/* fill up the request-info, and add it to the queue */
req
->
cmd
=
rw
;
req
->
errors
=
0
;
...
...
@@ -410,9 +422,7 @@ void ll_rw_page(int rw, int dev, int page, char * buffer)
printk
(
"Can't page to read-only device 0x%X
\n
"
,
dev
);
return
;
}
cli
();
req
=
get_request_wait
(
NR_REQUEST
,
dev
);
sti
();
/* fill up the request-info, and add it to the queue */
req
->
cmd
=
rw
;
req
->
errors
=
0
;
...
...
@@ -533,9 +543,7 @@ void ll_rw_swap_file(int rw, int dev, unsigned int *b, int nb, char *buf)
for
(
i
=
0
;
i
<
nb
;
i
++
,
buf
+=
buffersize
)
{
cli
();
req
=
get_request_wait
(
NR_REQUEST
,
dev
);
sti
();
req
->
cmd
=
rw
;
req
->
errors
=
0
;
req
->
sector
=
(
b
[
i
]
*
buffersize
)
>>
9
;
...
...
drivers/char/ChangeLog
View file @
3793c9b9
Wed Apr 12 08:06:16 1995 Theodore Y. Ts'o <tytso@localhost>
* serial.c (do_serial_hangup, do_softint, check_modem_status,
rs_init): Hangups are now scheduled via a separate tqueue
structure in the async_struct structure, tqueue_hangup.
This task is pushed on to the tq_schedule queue, so that
it is processed syncronously by the scheduler.
Sat Feb 18 12:13:51 1995 Theodore Y. Ts'o (tytso@rt-11)
* tty_io.c (disassociate_ctty, tty_open, tty_ioctl): Clear
...
...
drivers/char/serial.c
View file @
3793c9b9
...
...
@@ -468,7 +468,8 @@ static _INLINE_ void check_modem_status(struct async_struct *info)
#ifdef SERIAL_DEBUG_OPEN
printk
(
"scheduling hangup..."
);
#endif
rs_sched_event
(
info
,
RS_EVENT_HANGUP
);
queue_task_irq_off
(
&
info
->
tqueue_hangup
,
&
tq_scheduler
);
}
}
if
(
info
->
flags
&
ASYNC_CTS_FLOW
)
{
...
...
@@ -722,12 +723,6 @@ static void do_softint(void *private_)
if
(
!
tty
)
return
;
if
(
clear_bit
(
RS_EVENT_HANGUP
,
&
info
->
event
))
{
tty_hangup
(
tty
);
wake_up_interruptible
(
&
info
->
open_wait
);
info
->
flags
&=
~
(
ASYNC_NORMAL_ACTIVE
|
ASYNC_CALLOUT_ACTIVE
);
}
if
(
clear_bit
(
RS_EVENT_WRITE_WAKEUP
,
&
info
->
event
))
{
if
((
tty
->
flags
&
(
1
<<
TTY_DO_WRITE_WAKEUP
))
&&
tty
->
ldisc
.
write_wakeup
)
...
...
@@ -736,6 +731,28 @@ static void do_softint(void *private_)
}
}
/*
* This routine is called from the scheduler tqueue when the interrupt
* routine has signalled that a hangup has occured. The path of
* hangup processing is:
*
* serial interrupt routine -> (scheduler tqueue) ->
* do_serial_hangup() -> tty->hangup() -> rs_hangup()
*
*/
static
void
do_serial_hangup
(
void
*
private_
)
{
struct
async_struct
*
info
=
(
struct
async_struct
*
)
private_
;
struct
tty_struct
*
tty
;
tty
=
info
->
tty
;
if
(
!
tty
)
return
;
tty_hangup
(
tty
);
}
/*
* This subroutine is called when the RS_TIMER goes off. It is used
* by the serial driver to handle ports that do not have an interrupt
...
...
@@ -2615,6 +2632,8 @@ long rs_init(long kmem_start)
info
->
blocked_open
=
0
;
info
->
tqueue
.
routine
=
do_softint
;
info
->
tqueue
.
data
=
info
;
info
->
tqueue_hangup
.
routine
=
do_serial_hangup
;
info
->
tqueue_hangup
.
data
=
info
;
info
->
callout_termios
=
callout_driver
.
init_termios
;
info
->
normal_termios
=
serial_driver
.
init_termios
;
info
->
open_wait
=
0
;
...
...
drivers/net/lance.c
View file @
3793c9b9
...
...
@@ -913,7 +913,7 @@ lance_rx(struct device *dev)
lp
->
rx_ring
[
entry
].
base
&=
0x03ffffff
;
}
else
{
/* Malloc up new buffer, compatible with net-2e. */
short
pkt_len
=
lp
->
rx_ring
[
entry
].
msg_length
;
short
pkt_len
=
(
lp
->
rx_ring
[
entry
].
msg_length
&
0xfff
)
-
4
;
struct
sk_buff
*
skb
;
skb
=
alloc_skb
(
pkt_len
,
GFP_ATOMIC
);
...
...
drivers/net/ne.c
View file @
3793c9b9
#define rw_bugfix
/* ne.c: A general non-shared-memory NS8390 ethernet driver for linux. */
/*
Written 1992-94 by Donald Becker.
...
...
@@ -375,6 +376,7 @@ ne_block_output(struct device *dev, int count,
{
int
retries
=
0
;
int
nic_base
=
NE_BASE
;
unsigned
long
flags
;
/* Round the count up for word writes. Do we need to do this?
What effect will an odd byte count have on the 8390?
...
...
@@ -415,8 +417,13 @@ ne_block_output(struct device *dev, int count,
race condition will munge the remote byte count values, and then
the ne2k will hang the machine by holding I/O CH RDY because it
expects more data. Hopefully fixes the lockups. -- Paul Gortmaker.
Use save_flags/cli/restore_flags rather than cli/sti to avoid risk
of accidentally enabling interrupts which were disabled when we
were entered. Dave Platt <dplatt@3do.com>
*/
save_flags
(
flags
);
cli
();
outb_p
(
count
&
0xff
,
nic_base
+
EN0_RCNTLO
);
outb_p
(
count
>>
8
,
nic_base
+
EN0_RCNTHI
);
...
...
@@ -429,7 +436,7 @@ ne_block_output(struct device *dev, int count,
}
else
{
outsb
(
NE_BASE
+
NE_DATAPORT
,
buf
,
count
);
}
sti
(
);
restore_flags
(
flags
);
#ifdef CONFIG_NE_SANITY
/* This was for the ALPHA version only, but enough people have
...
...
drivers/net/wavelan.c
View file @
3793c9b9
...
...
@@ -71,7 +71,7 @@ struct net_local
extern
int
wavelan_probe
(
device
*
);
/* See Space.c */
static
char
*
version
=
"wavelan.c:v
6 22/2/95
\n
"
;
static
char
*
version
=
"wavelan.c:v
7 95/4/8
\n
"
;
/*
* Entry point forward declarations.
...
...
@@ -508,6 +508,9 @@ wavelan_hardware_reset(device *dev)
ac_cfg_t
cfg
;
ac_ias_t
ias
;
if
(
wavelan_debug
>
0
)
printk
(
"%s: ->wavelan_hardware_reset(dev=0x%x)
\n
"
,
dev
->
name
,
(
unsigned
int
)
dev
);
ioaddr
=
dev
->
base_addr
;
lp
=
(
net_local
*
)
dev
->
priv
;
...
...
@@ -565,7 +568,12 @@ wavelan_hardware_reset(device *dev)
}
if
(
i
<=
0
)
{
printk
(
"%s: wavelan_hardware_reset(): iscp_busy timeout.
\n
"
,
dev
->
name
);
if
(
wavelan_debug
>
0
)
printk
(
"%s: <-wavelan_hardware_reset(): -1
\n
"
,
dev
->
name
);
return
-
1
;
}
for
(
i
=
15
;
i
>
0
;
i
--
)
{
...
...
@@ -578,7 +586,12 @@ wavelan_hardware_reset(device *dev)
}
if
(
i
<=
0
)
{
printk
(
"%s: wavelan_hardware_reset(): status: expected 0x%02x, got 0x%02x.
\n
"
,
dev
->
name
,
SCB_ST_CX
|
SCB_ST_CNA
,
scb
.
scb_status
);
if
(
wavelan_debug
>
0
)
printk
(
"%s: <-wavelan_hardware_reset(): -1
\n
"
,
dev
->
name
);
return
-
1
;
}
wavelan_ack
(
dev
);
...
...
@@ -588,12 +601,18 @@ wavelan_hardware_reset(device *dev)
obram_write
(
ioaddr
,
OFFSET_CU
,
(
unsigned
char
*
)
&
cb
,
sizeof
(
cb
));
if
(
wavelan_synchronous_cmd
(
dev
,
"diag()"
)
==
-
1
)
{
if
(
wavelan_debug
>
0
)
printk
(
"%s: <-wavelan_hardware_reset(): -1
\n
"
,
dev
->
name
);
return
-
1
;
}
obram_read
(
ioaddr
,
OFFSET_CU
,
(
unsigned
char
*
)
&
cb
,
sizeof
(
cb
));
if
(
cb
.
ac_status
&
AC_SFLD_FAIL
)
{
printk
(
"%s: wavelan_hardware_reset(): i82586 Self Test failed.
\n
"
,
dev
->
name
);
if
(
wavelan_debug
>
0
)
printk
(
"%s: <-wavelan_hardware_reset(): -1
\n
"
,
dev
->
name
);
return
-
1
;
}
...
...
@@ -654,7 +673,12 @@ wavelan_hardware_reset(device *dev)
obram_write
(
ioaddr
,
OFFSET_CU
,
(
unsigned
char
*
)
&
cfg
,
sizeof
(
cfg
));
if
(
wavelan_synchronous_cmd
(
dev
,
"reset()-configure"
)
==
-
1
)
{
if
(
wavelan_debug
>
0
)
printk
(
"%s: <-wavelan_hardware_reset(): -1
\n
"
,
dev
->
name
);
return
-
1
;
}
memset
(
&
ias
,
0x00
,
sizeof
(
ias
));
ias
.
ias_h
.
ac_command
=
AC_CFLD_EL
|
(
AC_CFLD_CMD
&
acmd_ia_setup
);
...
...
@@ -663,19 +687,24 @@ wavelan_hardware_reset(device *dev)
obram_write
(
ioaddr
,
OFFSET_CU
,
(
unsigned
char
*
)
&
ias
,
sizeof
(
ias
));
if
(
wavelan_synchronous_cmd
(
dev
,
"reset()-address"
)
==
-
1
)
{
if
(
wavelan_debug
>
0
)
printk
(
"%s: <-wavelan_hardware_reset(): -1
\n
"
,
dev
->
name
);
return
-
1
;
}
wavelan_ints_on
(
dev
);
if
(
wavelan_debug
>
4
)
{
wavelan_scb_show
(
ioaddr
);
printk
(
"%s: Initialized WaveLAN.
\n
"
,
dev
->
name
);
}
wavelan_ru_start
(
dev
);
wavelan_cu_start
(
dev
);
if
(
wavelan_debug
>
0
)
printk
(
"%s: <-wavelan_hardware_reset(): 0
\n
"
,
dev
->
name
);
return
0
;
}
...
...
@@ -708,6 +737,7 @@ int
wavelan_probe
(
device
*
dev
)
{
int
i
;
int
r
;
short
base_addr
;
static
unsigned
short
iobase
[]
=
{
...
...
@@ -721,10 +751,17 @@ wavelan_probe(device *dev)
0x390
,
};
if
(
wavelan_debug
>
0
)
printk
(
"%s: ->wavelan_probe(dev=0x%x (base_addr=0x%x))
\n
"
,
dev
->
name
,
(
unsigned
int
)
dev
,
(
unsigned
int
)
dev
->
base_addr
);
#if STRUCT_CHECK == 1
if
(
wavelan_struct_check
()
!=
(
char
*
)
0
)
{
printk
(
"%s: structure/compiler botch:
\"
%s
\"\n
"
,
dev
->
name
,
wavelan_struct_check
());
if
(
wavelan_debug
>
0
)
printk
(
"%s: <-wavelan_probe(): ENODEV
\n
"
,
dev
->
name
);
return
ENODEV
;
}
#endif
/* STRUCT_CHECK == 1 */
...
...
@@ -732,16 +769,25 @@ wavelan_probe(device *dev)
base_addr
=
dev
->
base_addr
;
if
(
base_addr
<
0
)
{
/*
* Don't probe at all.
*/
if
(
wavelan_debug
>
0
)
printk
(
"%s: <-wavelan_probe(): ENXIO
\n
"
,
dev
->
name
);
return
ENXIO
;
}
if
(
base_addr
>
0x100
)
{
/*
* Check a single specified location.
*/
return
wavelan_probe1
(
dev
,
base_addr
);
r
=
wavelan_probe1
(
dev
,
base_addr
);
if
(
wavelan_debug
>
0
)
printk
(
"%s: <-wavelan_probe(): %d
\n
"
,
dev
->
name
,
r
);
return
r
;
}
for
(
i
=
0
;
i
<
nels
(
iobase
);
i
++
)
{
...
...
@@ -749,9 +795,16 @@ wavelan_probe(device *dev)
continue
;
if
(
wavelan_probe1
(
dev
,
iobase
[
i
])
==
0
)
{
if
(
wavelan_debug
>
0
)
printk
(
"%s: <-wavelan_probe(): 0
\n
"
,
dev
->
name
);
return
0
;
}
}
if
(
wavelan_debug
>
0
)
printk
(
"%s: <-wavelan_probe(): ENODEV
\n
"
,
dev
->
name
);
return
ENODEV
;
}
...
...
@@ -764,6 +817,9 @@ wavelan_probe1(device *dev, unsigned short ioaddr)
int
i
;
net_local
*
lp
;
if
(
wavelan_debug
>
0
)
printk
(
"%s: ->wavelan_probe1(dev=0x%x, ioaddr=0x%x)
\n
"
,
dev
->
name
,
(
unsigned
int
)
dev
,
ioaddr
);
wavelan_reset
(
ioaddr
);
psa_read
(
ioaddr
,
HACR_DEFAULT
,
0
,
(
unsigned
char
*
)
&
psa
,
sizeof
(
psa
));
...
...
@@ -780,13 +836,19 @@ wavelan_probe1(device *dev, unsigned short ioaddr)
||
psa
.
psa_univ_mac_addr
[
2
]
!=
SA_ADDR2
)
{
if
(
wavelan_debug
>
0
)
printk
(
"%s: <-wavelan_probe1(): ENODEV
\n
"
,
dev
->
name
);
return
ENODEV
;
}
printk
(
"%s: WaveLAN at %#x,"
,
dev
->
name
,
ioaddr
);
if
((
irq
=
wavelan_map_irq
(
ioaddr
,
psa
.
psa_int_req_no
))
==
-
1
)
{
printk
(
" could not wavelan_map_irq(0x%x, %d).
\n
"
,
ioaddr
,
psa
.
psa_int_req_no
);
if
(
wavelan_debug
>
0
)
printk
(
"%s: <-wavelan_probe1(): EAGAIN
\n
"
,
dev
->
name
);
return
EAGAIN
;
}
...
...
@@ -871,7 +933,7 @@ wavelan_probe1(device *dev, unsigned short ioaddr)
printk
(
"
\n
"
);
if
(
wavelan_debug
)
if
(
wavelan_debug
>
0
)
printk
(
version
);
dev
->
priv
=
kmalloc
(
sizeof
(
net_local
),
GFP_KERNEL
);
...
...
@@ -915,6 +977,9 @@ wavelan_probe1(device *dev, unsigned short ioaddr)
dev
->
mtu
=
WAVELAN_MTU
;
if
(
wavelan_debug
>
0
)
printk
(
"%s: <-wavelan_probe1(): 0
\n
"
,
dev
->
name
);
return
0
;
}
...
...
@@ -1074,12 +1139,21 @@ wavelan_open(device *dev)
{
unsigned
short
ioaddr
;
net_local
*
lp
;
unsigned
long
x
;
int
r
;
if
(
wavelan_debug
>
0
)
printk
(
"%s: ->wavelan_open(dev=0x%x)
\n
"
,
dev
->
name
,
(
unsigned
int
)
dev
);
ioaddr
=
dev
->
base_addr
;
lp
=
(
net_local
*
)
dev
->
priv
;
if
(
dev
->
irq
==
0
)
{
if
(
wavelan_debug
>
0
)
printk
(
"%s: <-wavelan_open(): -ENXIO
\n
"
,
dev
->
name
);
return
-
ENXIO
;
}
if
(
...
...
@@ -1092,23 +1166,35 @@ wavelan_open(device *dev)
)
{
irq2dev_map
[
dev
->
irq
]
=
(
device
*
)
0
;
if
(
wavelan_debug
>
0
)
printk
(
"%s: <-wavelan_open(): -EAGAIN
\n
"
,
dev
->
name
);
return
-
EAGAIN
;
}
if
(
wavelan_hardware_reset
(
dev
)
==
-
1
)
x
=
wavelan_splhi
();
if
((
r
=
wavelan_hardware_reset
(
dev
))
!=
-
1
)
{
dev
->
interrupt
=
0
;
dev
->
start
=
1
;
}
wavelan_splx
(
x
);
if
(
r
==
-
1
)
{
free_irq
(
dev
->
irq
);
irq2dev_map
[
dev
->
irq
]
=
(
device
*
)
0
;
if
(
wavelan_debug
>
0
)
printk
(
"%s: <-wavelan_open(): -EAGAIN(2)
\n
"
,
dev
->
name
);
return
-
EAGAIN
;
}
dev
->
interrupt
=
0
;
dev
->
start
=
1
;
#if defined(MODULE)
MOD_INC_USE_COUNT
;
#endif
/* defined(MODULE) */
if
(
wavelan_debug
>
0
)
printk
(
"%s: <-wavelan_open(): 0
\n
"
,
dev
->
name
);
return
0
;
}
...
...
@@ -1438,7 +1524,7 @@ wavelan_receive(device *dev)
}
#endif /* 0 */
if
(
wavelan_debug
>
0
)
if
(
wavelan_debug
>
5
)
{
unsigned
char
addr
[
WAVELAN_ADDR_SIZE
];
unsigned
short
ltype
;
...
...
@@ -1723,14 +1809,14 @@ wavelan_interrupt(int irq, struct pt_regs *regs)
* This will clear it -- ignored for now.
*/
mmc_read
(
ioaddr
,
mmroff
(
0
,
mmr_dce_status
),
&
dce_status
,
sizeof
(
dce_status
));
if
(
wavelan_debug
>
4
)
if
(
wavelan_debug
>
0
)
printk
(
"%s: warning: wavelan_interrupt(): unexpected mmc interrupt: status 0x%04x.
\n
"
,
dev
->
name
,
dce_status
);
}
if
((
hasr
&
HASR_82586_INTR
)
==
0
)
{
dev
->
interrupt
=
0
;
if
(
wavelan_debug
>
4
)
if
(
wavelan_debug
>
0
)
printk
(
"%s: warning: wavelan_interrupt() but (hasr & HASR_82586_INTR) == 0.
\n
"
,
dev
->
name
);
return
;
}
...
...
@@ -1746,7 +1832,7 @@ wavelan_interrupt(int irq, struct pt_regs *regs)
set_chan_attn
(
ioaddr
,
lp
->
hacr
);
if
(
wavelan_debug
>
4
)
if
(
wavelan_debug
>
5
)
printk
(
"%s: interrupt, status 0x%04x.
\n
"
,
dev
->
name
,
status
);
if
((
status
&
SCB_ST_CX
)
==
SCB_ST_CX
)
...
...
@@ -1804,6 +1890,9 @@ wavelan_close(device *dev)
net_local
*
lp
;
unsigned
short
scb_cmd
;
if
(
wavelan_debug
>
0
)
printk
(
"%s: ->wavelan_close(dev=0x%x)
\n
"
,
dev
->
name
,
(
unsigned
int
)
dev
);
ioaddr
=
dev
->
base_addr
;
lp
=
(
net_local
*
)
dev
->
priv
;
...
...
@@ -1831,6 +1920,9 @@ wavelan_close(device *dev)
MOD_DEC_USE_COUNT
;
#endif
/* defined(MODULE) */
if
(
wavelan_debug
>
0
)
printk
(
"%s: <-wavelan_close(): 0
\n
"
,
dev
->
name
);
return
0
;
}
...
...
@@ -1856,6 +1948,9 @@ wavelan_set_multicast_list(device *dev, int num_addrs, void *addrs)
net_local
*
lp
;
unsigned
long
x
;
if
(
wavelan_debug
>
0
)
printk
(
"%s: ->wavelan_set_multicast_list(dev=0x%x, num_addrs=%d, addrs=0x%x)
\n
"
,
dev
->
name
,
(
unsigned
int
)
dev
,
num_addrs
,
(
unsigned
int
)
addrs
);
lp
=
(
net_local
*
)
dev
->
priv
;
switch
(
num_addrs
)
...
...
@@ -1888,6 +1983,9 @@ wavelan_set_multicast_list(device *dev, int num_addrs, void *addrs)
*/
break
;
}
if
(
wavelan_debug
>
0
)
printk
(
"%s: <-wavelan_set_multicast_list()
\n
"
,
dev
->
name
);
}
/*
...
...
@@ -2330,6 +2428,7 @@ wavelan_local_show(device *dev)
* Matthew Geier (matthew@cs.usyd.edu.au),
* Remo di Giovanni (remo@cs.usyd.edu.au),
* Eckhard Grah (grah@wrcs1.urz.uni-wuppertal.de),
* Vipul Gupta (vgupta@cs.binghamton.edu),
* Mark Hagan (mhagan@wtcpost.daytonoh.NCR.COM),
* Tim Nicholson (tim@cs.usyd.edu.au),
* Ian Parkin (ian@cs.usyd.edu.au),
...
...
drivers/scsi/Makefile
View file @
3793c9b9
...
...
@@ -86,9 +86,11 @@ SCSI_OBJS := $(SCSI_OBJS) buslogic.o
SCSI_SRCS
:=
$(SCSI_SRCS)
buslogic.c
endif
SCSI_SRCS
:=
$(SCSI_SRCS)
eata_dma.c
ifdef
CONFIG_SCSI_EATA_DMA
SCSI_OBJS
:=
$(SCSI_OBJS)
eata_dma.o
SCSI_SRCS
:=
$(SCSI_SRCS)
eata_dma.c
else
SCSI_MODULE_OBJS
:=
$(SCSI_MODULE_OBJS)
eata_dma.o
endif
ifdef
CONFIG_SCSI_U14_34F
...
...
drivers/scsi/buslogic.c
View file @
3793c9b9
...
...
@@ -56,16 +56,18 @@
* BT-747D - 747S + differential termination.
* BT-757S - 747S + WIDE SCSI.
* BT-757D - 747D + WIDE SCSI.
* BT-445S - VESA bus-master FAST SCSI with active termination
and floppy
* support.
* BT-445S - VESA bus-master FAST SCSI with active termination
*
and floppy
support.
* BT-445C - 445S + enhanced BIOS & firmware options.
* BT-946C - PCI bus-master FAST SCSI. (??? Nothing else known.)
* BT-946C - PCI bus-master FAST SCSI.
* BT-956C - PCI bus-master FAST/WIDE SCSI.
*
* ??? I believe other boards besides the 445 now have a "C" model, but I
* have no facts on them.
*
* This driver SHOULD support all of these boards. It has only been tested
* with a 747S and 445S.
* with a 747S, 445S, 946C, and 956C; there is no PCI-specific support as
* yet.
*
* Should you require further information on any of these boards, BusLogic
* can be reached at (408)492-9090. Their BBS # is (408)492-1984 (maybe BBS
...
...
@@ -118,7 +120,7 @@
The test is believed to fail on at least some AMI BusLogic clones. */
/* #define BIOS_TRANSLATION_OVERRIDE BIOS_TRANSLATION_BIG */
#define BUSLOGIC_VERSION "1.1
4
"
#define BUSLOGIC_VERSION "1.1
5
"
/* Not a random value - if this is too large, the system hangs for a long time
waiting for something to happen if a board is not installed. */
...
...
@@ -137,11 +139,13 @@
/* Since the SG list is malloced, we have to limit the length. */
#define BUSLOGIC_MAX_SG (BUSLOGIC_SG_MALLOC / sizeof (struct chain))
/* ??? Arbitrary. If we can dynamically allocate the mailbox arrays, I may
bump up this number. */
#define BUSLOGIC_MAILBOXES 16
/* Since the host adapters have room to buffer 32 commands internally, there
is some virtue in setting BUSLOGIC_MAILBOXES to 32. The maximum value
appears to be 255, since the Count parameter to the Initialize Extended
Mailbox command is limited to one byte. */
#define BUSLOGIC_MAILBOXES 32
#define BUSLOGIC_CMDLUN 4
/* ??? Arbitrary
*/
#define BUSLOGIC_CMDLUN 4
/* Arbitrary, but seems to work well.
*/
/* BusLogic boards can be configured for quite a number of port addresses (six
to be exact), but I generally do not want the driver poking around at
...
...
@@ -165,8 +169,8 @@ static unsigned short bases[7] = {
struct
hostdata
{
unsigned
int
bus_type
;
unsigned
int
bios_translation
:
1
;
/* BIOS mapping (for compatibility) */
size_
t
last_mbi_used
;
size_
t
last_mbo_used
;
in
t
last_mbi_used
;
in
t
last_mbo_used
;
char
model
[
7
];
char
firmware_rev
[
6
];
Scsi_Cmnd
*
sc
[
BUSLOGIC_MAILBOXES
];
...
...
@@ -425,174 +429,131 @@ const char *buslogic_info(struct Scsi_Host *shpnt)
return
"BusLogic SCSI driver "
BUSLOGIC_VERSION
;
}
/* A "high" level interrupt handler. */
/*
This is a major rewrite of the interrupt handler to support the newer
and faster PCI cards. While the previous interrupt handler was supposed
to handle multiple incoming becoming available mailboxes during the same
interrupt, my testing showed that in practice only a single mailbox was
ever made available. With the 946C and 956C, multiple incoming mailboxes
being ready for processing during a single interrupt occurs much more
frequently, and so care must be taken to avoid race conditions managing
the Host Adapter Interrupt Register, which can lead to lost interrupts.
Leonard N. Zubkoff, 23-Mar-95
*/
static
void
buslogic_interrupt
(
int
irq
,
struct
pt_regs
*
regs
)
{
void
(
*
my_done
)(
Scsi_Cmnd
*
)
=
NULL
;
int
errstatus
,
mbistatus
=
MBX_NOT_IN_USE
,
number_serviced
,
found
;
size_t
mbi
,
mbo
=
0
;
int
mbi
,
saved_mbo
[
BUSLOGIC_MAILBOXES
];
int
base
,
interrupt_flags
,
found
,
i
;
struct
Scsi_Host
*
shpnt
;
Scsi_Cmnd
*
sctmp
;
unsigned
long
flags
;
int
base
,
flag
;
int
needs_restart
;
struct
mailbox
*
mb
;
struct
ccb
*
ccb
;
shpnt
=
host
[
irq
-
9
];
if
(
!
shpnt
)
panic
(
"buslogic_interrupt: NULL SCSI host entry"
);
if
(
shpnt
==
NULL
)
panic
(
"buslogic_interrupt: NULL SCSI host entry"
);
mb
=
HOSTDATA
(
shpnt
)
->
mb
;
ccb
=
HOSTDATA
(
shpnt
)
->
ccbs
;
base
=
shpnt
->
io_port
;
#if (BUSLOGIC_DEBUG & BD_INTERRUPT)
flag
=
inb
(
INTERRUPT
(
base
));
buslogic_printk
(
""
);
if
(
!
(
flag
&
INTV
))
printk
(
"no interrupt? "
);
if
(
flag
&
IMBL
)
printk
(
"IMBL "
);
if
(
flag
&
MBOR
)
printk
(
"MBOR "
);
if
(
flag
&
CMDC
)
printk
(
"CMDC "
);
if
(
flag
&
RSTS
)
printk
(
"RSTS "
);
printk
(
"status %02X
\n
"
,
inb
(
STATUS
(
base
)));
#endif
/*
This interrupt handler is now specified to use the SA_INTERRUPT
protocol, so interrupts are inhibited on entry until explicitly
allowed again. Read the Host Adapter Interrupt Register, and
complain if there is no pending interrupt being signaled.
*/
number_serviced
=
0
;
needs_restart
=
0
;
interrupt_flags
=
inb
(
INTERRUPT
(
base
));
for
(;;)
{
flag
=
inb
(
INTERRUPT
(
base
));
/* Check for unusual interrupts. If any of these happen, we should
probably do something special, but for now just printing a message
is sufficient. A SCSI reset detected is something that we really
need to deal with in some way. */
if
(
flag
&
(
MBOR
|
CMDC
|
RSTS
))
{
buslogic_printk
(
"unusual flag:"
);
if
(
flag
&
MBOR
)
printk
(
" MBOR"
);
if
(
flag
&
CMDC
)
printk
(
" CMDC"
);
if
(
flag
&
RSTS
)
{
needs_restart
=
1
;
printk
(
" RSTS"
);
}
printk
(
"
\n
"
);
}
if
(
!
(
interrupt_flags
&
INTV
))
{
buslogic_printk
(
"interrupt received, but INTV not set
\n
"
);
return
;
}
INTR_RESET
(
base
);
/*
Reset the Host Adapter Interrupt Register. It appears to be
important that this is only done once per interrupt to avoid
losing interrupts under heavy loads.
*/
save_flags
(
flags
);
cli
();
INTR_RESET
(
base
);
mbi
=
HOSTDATA
(
shpnt
)
->
last_mbi_used
+
1
;
if
(
mbi
>=
2
*
BUSLOGIC_MAILBOXES
)
mbi
=
BUSLOGIC_MAILBOXES
;
if
(
interrupt_flags
&
RSTS
)
{
restart
(
shpnt
);
return
;
}
/* I use the "found" variable as I like to keep cli/sti pairs at the
same block level. Debugging dropped sti's is no fun... */
/*
With interrupts still inhibited, scan through the incoming mailboxes
in strict round robin fashion saving the status information and
then freeing the mailbox. A second pass over the completed commands
will be made separately to complete their processing.
*/
found
=
FALSE
;
do
{
if
(
mb
[
mbi
].
status
!=
MBX_NOT_IN_USE
)
{
found
=
TRUE
;
break
;
}
mbi
++
;
if
(
mbi
>=
2
*
BUSLOGIC_MAILBOXES
)
mbi
=
BUSLOGIC_MAILBOXES
;
}
while
(
mbi
!=
HOSTDATA
(
shpnt
)
->
last_mbi_used
);
if
(
found
)
{
mbo
=
(
struct
ccb
*
)
mb
[
mbi
].
ccbptr
-
ccb
;
mbistatus
=
mb
[
mbi
].
status
;
mb
[
mbi
].
status
=
MBX_NOT_IN_USE
;
HOSTDATA
(
shpnt
)
->
last_mbi_used
=
mbi
;
}
mbi
=
HOSTDATA
(
shpnt
)
->
last_mbi_used
+
1
;
if
(
mbi
>=
2
*
BUSLOGIC_MAILBOXES
)
mbi
=
BUSLOGIC_MAILBOXES
;
restore_flags
(
flags
)
;
found
=
0
;
if
(
!
found
)
{
/* Hmm, no mail. Must have read it the last time around. */
if
(
!
number_serviced
&&
!
needs_restart
)
buslogic_printk
(
"interrupt received, but no mail.
\n
"
);
/* We detected a reset. Restart all pending commands for devices
that use the hard reset option. */
if
(
needs_restart
)
restart
(
shpnt
);
return
;
}
while
(
mb
[
mbi
].
status
!=
MBX_NOT_IN_USE
&&
found
<
BUSLOGIC_MAILBOXES
)
{
int
mbo
=
(
struct
ccb
*
)
mb
[
mbi
].
ccbptr
-
ccb
;
int
result
=
0
;
#if (BUSLOGIC_DEBUG & BD_INTERRUPT)
if
(
ccb
[
mbo
].
tarstat
||
ccb
[
mbo
].
hastat
)
buslogic_printk
(
"returning %08X (status %d).
\n
"
,
((
int
)
ccb
[
mbo
].
hastat
<<
16
)
|
ccb
[
mbo
].
tarstat
,
mb
[
mbi
].
status
);
#endif
saved_mbo
[
found
++
]
=
mbo
;
if
(
mb
istatus
==
MBX_COMPLETION_NOT_FOUND
)
continue
;
if
(
mb
[
mbi
].
status
!=
MBX_COMPLETION_OK
)
result
=
makecode
(
ccb
[
mbo
].
hastat
,
ccb
[
mbo
].
tarstat
)
;
#if (BUSLOGIC_DEBUG & BD_INTERRUPT)
buslogic_printk
(
"...done %u %u
\n
"
,
mbo
,
mbi
);
#endif
HOSTDATA
(
shpnt
)
->
sc
[
mbo
]
->
result
=
result
;
sctmp
=
HOSTDATA
(
shpnt
)
->
sc
[
mbo
]
;
mb
[
mbi
].
status
=
MBX_NOT_IN_USE
;
if
(
!
sctmp
||
!
sctmp
->
scsi_done
)
{
buslogic_printk
(
"unexpected interrupt.
\n
"
);
buslogic_printk
(
"tarstat=%02X, hastat=%02X id=%d lun=%d ccb#=%u
\n
"
,
ccb
[
mbo
].
tarstat
,
ccb
[
mbo
].
hastat
,
ccb
[
mbo
].
id
,
ccb
[
mbo
].
lun
,
mbo
);
return
;
}
HOSTDATA
(
shpnt
)
->
last_mbi_used
=
mbi
;
my_done
=
sctmp
->
scsi_done
;
if
(
sctmp
->
host_scribble
)
scsi_free
(
sctmp
->
host_scribble
,
BUSLOGIC_SG_MALLOC
);
/* ??? more error checking left out here */
if
(
mbistatus
!=
MBX_COMPLETION_OK
)
{
/* ??? This is surely wrong, but I don't know what's right. */
errstatus
=
makecode
(
ccb
[
mbo
].
hastat
,
ccb
[
mbo
].
tarstat
);
}
else
errstatus
=
0
;
#if (BUSLOGIC_DEBUG & BD_INTERRUPT)
if
(
errstatus
)
buslogic_printk
(
"error: %04X %04X
\n
"
,
ccb
[
mbo
].
hastat
,
ccb
[
mbo
].
tarstat
);
if
(
status_byte
(
ccb
[
mbo
].
tarstat
)
==
CHECK_CONDITION
)
{
size_t
i
;
buslogic_printk
(
"sense:"
);
for
(
i
=
0
;
i
<
sizeof
sctmp
->
sense_buffer
;
i
++
)
printk
(
" %02X"
,
sctmp
->
sense_buffer
[
i
]);
printk
(
"
\n
"
);
}
if
(
++
mbi
>=
2
*
BUSLOGIC_MAILBOXES
)
mbi
=
BUSLOGIC_MAILBOXES
;
}
if
(
errstatus
)
buslogic_printk
(
"returning %08X.
\n
"
,
errstatus
);
#endif
/*
With interrupts no longer inhibited, iterate over the completed
commands freeing resources and calling the completion routines.
Since we exit upon completion of this loop, there is no need to
inhibit interrupts before exit, as this will be handled by the
fast interrupt assembly code we return to.
*/
sctmp
->
result
=
errstatus
;
HOSTDATA
(
shpnt
)
->
sc
[
mbo
]
=
NULL
;
/* This effectively frees up
the mailbox slot, as far as
queuecommand is
concerned. */
my_done
(
sctmp
);
number_serviced
++
;
}
sti
();
for
(
i
=
0
;
i
<
found
;
i
++
)
{
int
mbo
=
saved_mbo
[
i
];
sctmp
=
HOSTDATA
(
shpnt
)
->
sc
[
mbo
];
/*
First, free any storage allocated for a scatter/gather
data segment list.
*/
if
(
sctmp
->
host_scribble
)
scsi_free
(
sctmp
->
host_scribble
,
BUSLOGIC_SG_MALLOC
);
/*
Next, call the SCSI command completion handler.
*/
sctmp
->
scsi_done
(
sctmp
);
/*
Finally, mark the SCSI Command as completed so it may be reused
for another command by buslogic_queuecommand.
*/
HOSTDATA
(
shpnt
)
->
sc
[
mbo
]
=
NULL
;
}
}
/* ??? Why does queuecommand return a value? scsi.c never looks at it... */
int
buslogic_queuecommand
(
Scsi_Cmnd
*
scpnt
,
void
(
*
done
)(
Scsi_Cmnd
*
))
{
...
...
@@ -605,9 +566,10 @@ int buslogic_queuecommand(Scsi_Cmnd *scpnt, void (*done)(Scsi_Cmnd *))
int
bufflen
=
scpnt
->
request_bufflen
;
int
mbo
;
unsigned
long
flags
;
struct
mailbox
*
mb
;
struct
ccb
*
ccb
;
struct
Scsi_Host
*
shpnt
=
scpnt
->
host
;
struct
mailbox
*
mb
=
HOSTDATA
(
shpnt
)
->
mb
;
struct
ccb
*
ccb
;
#if (BUSLOGIC_DEBUG & BD_COMMAND)
if
(
target
>
1
)
{
...
...
@@ -651,9 +613,6 @@ int buslogic_queuecommand(Scsi_Cmnd *scpnt, void (*done)(Scsi_Cmnd *))
}
#endif
mb
=
HOSTDATA
(
shpnt
)
->
mb
;
ccb
=
HOSTDATA
(
shpnt
)
->
ccbs
;
/* Use the outgoing mailboxes in a round-robin fashion, because this
is how the host adapter will scan for them. */
...
...
@@ -693,12 +652,14 @@ int buslogic_queuecommand(Scsi_Cmnd *scpnt, void (*done)(Scsi_Cmnd *))
buslogic_printk
(
"sending command (%d %08X)..."
,
mbo
,
done
);
#endif
ccb
=
&
HOSTDATA
(
shpnt
)
->
ccbs
[
mbo
];
/* This gets trashed for some reason */
mb
[
mbo
].
ccbptr
=
&
ccb
[
mbo
]
;
mb
[
mbo
].
ccbptr
=
ccb
;
memset
(
&
ccb
[
mbo
]
,
0
,
sizeof
(
struct
ccb
));
memset
(
ccb
,
0
,
sizeof
(
struct
ccb
));
ccb
[
mbo
].
cdblen
=
scpnt
->
cmd_len
;
/* SCSI Command Descriptor
ccb
->
cdblen
=
scpnt
->
cmd_len
;
/* SCSI Command Descriptor
Block Length */
direction
=
0
;
...
...
@@ -707,14 +668,14 @@ int buslogic_queuecommand(Scsi_Cmnd *scpnt, void (*done)(Scsi_Cmnd *))
else
if
(
*
cmd
==
WRITE_10
||
*
cmd
==
WRITE_6
)
direction
=
16
;
memcpy
(
ccb
[
mbo
].
cdb
,
cmd
,
ccb
[
mbo
].
cdblen
);
memcpy
(
ccb
->
cdb
,
cmd
,
ccb
->
cdblen
);
if
(
scpnt
->
use_sg
)
{
struct
scatterlist
*
sgpnt
;
struct
chain
*
cptr
;
size_t
i
;
ccb
[
mbo
].
op
=
CCB_OP_INIT_SG
;
/* SCSI Initiator Command
ccb
->
op
=
CCB_OP_INIT_SG
;
/* SCSI Initiator Command
w/scatter-gather */
scpnt
->
host_scribble
=
(
unsigned
char
*
)
scsi_malloc
(
BUSLOGIC_SG_MALLOC
);
...
...
@@ -735,8 +696,8 @@ int buslogic_queuecommand(Scsi_Cmnd *scpnt, void (*done)(Scsi_Cmnd *))
cptr
[
i
].
dataptr
=
sgpnt
[
i
].
address
;
cptr
[
i
].
datalen
=
sgpnt
[
i
].
length
;
}
ccb
[
mbo
].
datalen
=
scpnt
->
use_sg
*
sizeof
(
struct
chain
);
ccb
[
mbo
].
dataptr
=
cptr
;
ccb
->
datalen
=
scpnt
->
use_sg
*
sizeof
(
struct
chain
);
ccb
->
dataptr
=
cptr
;
#if (BUSLOGIC_DEBUG & BD_COMMAND)
{
unsigned
char
*
ptr
;
...
...
@@ -749,27 +710,26 @@ int buslogic_queuecommand(Scsi_Cmnd *scpnt, void (*done)(Scsi_Cmnd *))
}
#endif
}
else
{
ccb
[
mbo
].
op
=
CCB_OP_INIT
;
/* SCSI Initiator Command */
ccb
->
op
=
CCB_OP_INIT
;
/* SCSI Initiator Command */
scpnt
->
host_scribble
=
NULL
;
CHECK_DMA_ADDR
(
shpnt
->
unchecked_isa_dma
,
buff
,
goto
baddma
);
ccb
[
mbo
].
datalen
=
bufflen
;
ccb
[
mbo
].
dataptr
=
buff
;
ccb
->
datalen
=
bufflen
;
ccb
->
dataptr
=
buff
;
}
ccb
[
mbo
].
id
=
target
;
ccb
[
mbo
].
lun
=
lun
;
ccb
[
mbo
].
dir
=
direction
;
ccb
[
mbo
].
rsalen
=
sizeof
scpnt
->
sense_buffer
;
ccb
[
mbo
].
senseptr
=
scpnt
->
sense_buffer
;
ccb
[
mbo
].
linkptr
=
NULL
;
ccb
[
mbo
].
commlinkid
=
0
;
ccb
->
id
=
target
;
ccb
->
lun
=
lun
;
ccb
->
dir
=
direction
;
ccb
->
rsalen
=
sizeof
scpnt
->
sense_buffer
;
ccb
->
senseptr
=
scpnt
->
sense_buffer
;
/* ccbcontrol, commlinkid, and linkptr are 0 due to above memset. */
#if (BUSLOGIC_DEBUG & BD_COMMAND)
{
size_t
i
;
buslogic_printk
(
"sending..."
);
for
(
i
=
0
;
i
<
sizeof
ccb
[
mbo
]
-
10
;
i
++
)
printk
(
" %02X"
,
((
unsigned
char
*
)
&
ccb
[
mbo
]
)[
i
]);
for
(
i
=
0
;
i
<
sizeof
(
struct
ccb
)
-
10
;
i
++
)
printk
(
" %02X"
,
((
unsigned
char
*
)
ccb
)[
i
]);
printk
(
"
\n
"
);
}
#endif
...
...
@@ -1255,7 +1215,8 @@ int buslogic_detect(Scsi_Host_Template *tpnt)
save_flags
(
flags
);
cli
();
if
(
request_irq
(
irq
,
buslogic_interrupt
,
0
,
"buslogic"
))
{
if
(
request_irq
(
irq
,
buslogic_interrupt
,
SA_INTERRUPT
,
"buslogic"
))
{
buslogic_printk
(
"unable to allocate IRQ for "
"BusLogic controller.
\n
"
);
restore_flags
(
flags
);
...
...
drivers/scsi/eata_dma.c
View file @
3793c9b9
...
...
@@ -44,13 +44,14 @@
* Thanks also to Greg Hosler who did a lot of testing and *
* found quite a number of bugs during the development. *
************************************************************
* last change: 95/0
2/13 OS: Linux 1.1.91
or higher *
* last change: 95/0
4/10 OS: Linux 1.2.00
or higher *
************************************************************/
/* Look in eata_dma.h for configuration and revision information */
#ifdef MODULE
#include <linux/module.h>
#include <linux/version.h>
#endif
#include <linux/kernel.h>
...
...
@@ -61,6 +62,7 @@
#include <linux/in.h>
#include <linux/bios32.h>
#include <linux/pci.h>
#include <asm/types.h>
#include <asm/io.h>
#include <asm/dma.h>
#include "../block/blk.h"
...
...
@@ -87,10 +89,13 @@ static unchar reg_IRQ[] =
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
};
static
unchar
reg_IRQL
[]
=
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
};
static
struct
eata_sp
status
[
MAXIRQ
];
/* Statuspacket array */
static
struct
eata_sp
*
status
=
0
;
/* Statuspacket array */
static
void
*
dma_scratch
=
0
;
static
uint
internal_command_finished
=
TRUE
;
static
unchar
HBA_interpret
=
FALSE
;
static
u32
fake_int_base
;
static
u32
fake_int_result
;
static
struct
geom_emul
geometry
;
/* Drive 1 & 2 geometry */
static
ulong
int_counter
=
0
;
...
...
@@ -101,6 +106,14 @@ void eata_scsi_done (Scsi_Cmnd * SCpnt)
return
;
}
void
eata_fake_int_handler
(
s32
irq
,
struct
pt_regs
*
regs
)
{
fake_int_result
=
inb
(
fake_int_base
+
HA_RSTATUS
);
DBG
(
DBG_INTR3
,
printk
(
"eata_fake_int_handler called irq%ld base %#lx res %#lx
\n
"
,
irq
,
fake_int_base
,
fake_int_result
));
return
;
}
#if EATA_DMA_PROC
#include "eata_dma_proc.c"
#endif
...
...
@@ -109,6 +122,9 @@ int eata_release(struct Scsi_Host *sh)
{
if
(
sh
->
irq
&&
reg_IRQ
[
sh
->
irq
]
==
1
)
free_irq
(
sh
->
irq
);
else
reg_IRQ
[
sh
->
irq
]
--
;
scsi_init_free
((
void
*
)
status
,
512
);
if
(
SD
(
sh
)
->
channel
==
0
)
{
if
(
sh
->
dma_channel
!=
0xff
)
free_dma
(
sh
->
dma_channel
);
if
(
sh
->
io_port
&&
sh
->
n_io_port
)
...
...
@@ -125,7 +141,7 @@ const char *eata_info(struct Scsi_Host *host)
void
eata_int_handler
(
int
irq
,
struct
pt_regs
*
regs
)
{
uint
i
,
result
;
uint
i
,
result
=
0
;
uint
hba_stat
,
scsi_stat
,
eata_stat
;
Scsi_Cmnd
*
cmd
;
struct
eata_ccb
*
cp
;
...
...
@@ -183,21 +199,25 @@ void eata_int_handler(int irq, struct pt_regs * regs)
eata_stat
,
hba_stat
));
switch
(
hba_stat
)
{
case
0x00
:
/* NO Error */
case
HA_NO_ERROR
:
/* NO Error */
if
(
scsi_stat
==
CONDITION_GOOD
&&
cmd
->
device
->
type
==
TYPE_DISK
&&
(
HD
(
cmd
)
->
t_state
[
cmd
->
target
]
==
RESET
))
result
=
DID_BUS_BUSY
<<
16
;
else
if
(
scsi_stat
==
GOOD
)
HD
(
cmd
)
->
t_state
[
cmd
->
target
]
=
FALSE
;
else
if
(
scsi_stat
==
CHECK_CONDITION
&&
cmd
->
device
->
type
==
TYPE_DISK
&&
(
cmd
->
sense_buffer
[
2
]
&
0xf
)
==
RECOVERED_ERROR
)
result
=
DID_BUS_BUSY
<<
16
;
else
result
=
DID_OK
<<
16
;
if
(
scsi_stat
==
GOOD
)
HD
(
cmd
)
->
t_state
[
cmd
->
target
]
=
FALSE
;
HD
(
cmd
)
->
t_timeout
[
cmd
->
target
]
=
0
;
HD
(
cmd
)
->
t_timeout
[
cmd
->
target
]
=
FALSE
;
break
;
case
0x01
:
/* Selection Timeout */
case
HA_ERR_SEL_TO
:
/* Selection Timeout */
result
=
DID_BAD_TARGET
<<
16
;
break
;
case
0x02
:
/* Command Timeout */
case
HA_ERR_CMD_TO
:
/* Command Timeout */
if
(
HD
(
cmd
)
->
t_timeout
[
cmd
->
target
]
>
1
)
result
=
DID_ERROR
<<
16
;
else
{
...
...
@@ -205,7 +225,8 @@ void eata_int_handler(int irq, struct pt_regs * regs)
HD
(
cmd
)
->
t_timeout
[
cmd
->
target
]
++
;
}
break
;
case
0x03
:
/* SCSI Bus Reset Received */
case
HA_ERR_RESET
:
/* SCSI Bus Reset Received */
case
HA_INIT_POWERUP
:
/* Initial Controller Power-up */
if
(
cmd
->
device
->
type
!=
TYPE_TAPE
)
result
=
DID_BUS_BUSY
<<
16
;
else
...
...
@@ -214,23 +235,19 @@ void eata_int_handler(int irq, struct pt_regs * regs)
for
(
i
=
0
;
i
<
MAXTARGET
;
i
++
)
HD
(
cmd
)
->
t_state
[
i
]
=
RESET
;
break
;
case
0x07
:
/* Bus Parity Error */
case
0x0c
:
/* Controller Ram Parity */
case
0x04
:
/* Initial Controller Power-up */
case
0x05
:
/* Unexpected Bus Phase */
case
0x06
:
/* Unexpected Bus Free */
case
0x08
:
/* SCSI Hung */
case
0x09
:
/* Unexpected Message Reject */
case
0x0a
:
/* SCSI Bus Reset Stuck */
case
0x0b
:
/* Auto Request-Sense Failed */
case
HA_UNX_BUSPHASE
:
/* Unexpected Bus Phase */
case
HA_UNX_BUS_FREE
:
/* Unexpected Bus Free */
case
HA_BUS_PARITY
:
/* Bus Parity Error */
case
HA_SCSI_HUNG
:
/* SCSI Hung */
case
HA_UNX_MSGRJCT
:
/* Unexpected Message Reject */
case
HA_RESET_STUCK
:
/* SCSI Bus Reset Stuck */
case
HA_RSENSE_FAIL
:
/* Auto Request-Sense Failed */
case
HA_PARITY_ERR
:
/* Controller Ram Parity */
default:
result
=
DID_ERROR
<<
16
;
break
;
}
cmd
->
result
=
result
|
scsi_stat
;
if
(
in_scan_scsis
&&
scsi_stat
==
CHECK_CONDITION
&&
(
cmd
->
sense_buffer
[
2
]
&
0xf
)
==
UNIT_ATTENTION
)
cmd
->
result
|=
(
DRIVER_SENSE
<<
24
);
cmd
->
result
=
result
|
(
scsi_stat
<<
1
);
#if DBG_INTR2
if
(
scsi_stat
||
result
||
hba_stat
||
eata_stat
!=
0x50
)
...
...
@@ -262,14 +279,14 @@ inline uint eata_send_command(ulong addr, uint base, unchar command)
while
(
inb
(
base
+
HA_RAUXSTAT
)
&
HA_ABUSY
)
if
(
--
loop
==
0
)
return
(
TRU
E
);
return
(
FALS
E
);
outb
(
addr
&
0x000000ff
,
base
+
HA_WDMAADDR
);
outb
((
addr
&
0x0000ff00
)
>>
8
,
base
+
HA_WDMAADDR
+
1
);
outb
((
addr
&
0x00ff0000
)
>>
16
,
base
+
HA_WDMAADDR
+
2
);
outb
((
addr
&
0xff000000
)
>>
24
,
base
+
HA_WDMAADDR
+
3
);
outb
(
command
,
base
+
HA_WCOMMAND
);
return
(
FALS
E
);
return
(
TRU
E
);
}
int
eata_queue
(
Scsi_Cmnd
*
cmd
,
void
*
(
done
)
(
Scsi_Cmnd
*
))
...
...
@@ -337,10 +354,10 @@ int eata_queue(Scsi_Cmnd * cmd, void *(done) (Scsi_Cmnd *))
case
FORMAT_UNIT
:
case
REASSIGN_BLOCKS
:
case
RESERVE
:
case
SEARCH_EQUAL
:
case
SEARCH_HIGH
:
case
SEARCH_LOW
:
case
WRITE_6
:
case
WRITE_10
:
case
WRITE_VERIFY
:
case
0x3f
:
case
0x41
:
case
0xb1
:
case
0xb0
:
case
0xb2
:
case
0xaa
:
case
0xae
:
case
0x24
:
case
0x38
:
case
0x3d
:
case
0xb6
:
case
UPDATE_BLOCK
:
case
WRITE_LONG
:
case
WRITE_SAME
:
case
SEARCH_HIGH_12
:
case
SEARCH_EQUAL_12
:
case
SEARCH_LOW_12
:
case
WRITE_12
:
case
WRITE_VERIFY_12
:
case
SET_WINDOW
:
case
MEDIUM_SCAN
:
case
SEND_VOLUME_TAG
:
case
0xea
:
/* alternate number for WRITE LONG */
cp
->
DataOut
=
TRUE
;
/* Output mode */
break
;
...
...
@@ -376,7 +393,7 @@ int eata_queue(Scsi_Cmnd * cmd, void *(done) (Scsi_Cmnd *))
cp
->
cp_lun
=
cmd
->
lun
;
cp
->
cp_dispri
=
TRUE
;
cp
->
cp_identify
=
TRUE
;
memcpy
(
cp
->
cp_cdb
,
cmd
->
cmnd
,
COMMAND_SIZE
(
*
cmd
->
cmnd
)
);
memcpy
(
cp
->
cp_cdb
,
cmd
->
cmnd
,
cmd
->
cmd_len
);
cp
->
cp_statDMA
=
htonl
((
ulong
)
&
(
hd
->
sp
));
...
...
@@ -384,7 +401,7 @@ int eata_queue(Scsi_Cmnd * cmd, void *(done) (Scsi_Cmnd *))
cp
->
cmd
=
cmd
;
cmd
->
host_scribble
=
(
char
*
)
&
hd
->
ccb
[
y
];
if
(
eata_send_command
((
ulong
)
cp
,
(
uint
)
sh
->
base
,
EATA_CMD_DMA_SEND_CP
))
{
if
(
eata_send_command
((
ulong
)
cp
,
(
uint
)
sh
->
base
,
EATA_CMD_DMA_SEND_CP
)
==
FALSE
)
{
cmd
->
result
=
DID_ERROR
<<
16
;
printk
(
"eata_queue target %d, pid %ld, HBA busy, returning DID_ERROR, done.
\n
"
,
cmd
->
target
,
cmd
->
pid
);
...
...
@@ -494,8 +511,10 @@ int eata_reset(Scsi_Cmnd * cmd)
DBG
(
DBG_ABNORM
&&
DBG_DELAY
,
DEL2
(
500
));
return
(
SCSI_RESET_ERROR
);
}
for
(
z
=
0
;
z
<
MAXTARGET
;
z
++
)
for
(
z
=
0
;
z
<
MAXTARGET
;
z
++
)
{
HD
(
cmd
)
->
t_state
[
z
]
=
RESET
;
HD
(
cmd
)
->
t_timeout
[
z
]
=
FALSE
;
}
for
(
x
=
0
;
x
<
cmd
->
host
->
can_queue
;
x
++
)
{
...
...
@@ -577,16 +596,21 @@ char * get_board_data(ulong base, uint irq, uint id)
{
struct
eata_ccb
cp
;
struct
eata_sp
sp
;
static
char
buff
[
256
];
static
char
*
buff
;
u32
i
;
buff
=
dma_scratch
;
memset
(
&
cp
,
0
,
sizeof
(
struct
eata_ccb
));
memset
(
buff
,
0
,
sizeof
(
buff
));
memset
(
&
sp
,
0
,
sizeof
(
struct
eata_sp
));
memset
(
buff
,
0
,
256
);
cp
.
DataIn
=
TRUE
;
cp
.
Interpret
=
TRUE
;
/* Interpret command */
cp
.
cp_datalen
=
htonl
(
255
);
cp
.
cp_dataDMA
=
htonl
((
long
)
buff
);
cp
.
cp_dataDMA
=
htonl
((
s32
)
buff
);
cp
.
cp_viraddr
=
&
cp
;
cp
.
cp_id
=
id
;
cp
.
cp_lun
=
0
;
...
...
@@ -600,9 +624,21 @@ char * get_board_data(ulong base, uint irq, uint id)
cp
.
cp_statDMA
=
htonl
((
ulong
)
&
sp
);
eata_send_command
((
ulong
)
&
cp
,
(
uint
)
base
,
EATA_CMD_DMA_SEND_CP
);
while
(
!
(
inb
(
base
+
HA_RAUXSTAT
)
&
HA_AIRQ
));
if
(
inb
((
uint
)
base
+
HA_RSTATUS
)
&
1
)
fake_int_base
=
base
;
fake_int_result
=
0
;
eata_send_command
((
u32
)
&
cp
,
(
u32
)
base
,
EATA_CMD_DMA_SEND_CP
);
i
=
jiffies
+
300
;
while
(
!
fake_int_result
&&
jiffies
<=
i
)
/* nothing */
;
DBG
(
DBG_INTR3
,
printk
(
"fake_int_result: %#lx hbastat %#lx scsistat %#lx,"
" buff %p sp %p
\n
"
,
fake_int_result
,
(
u32
)
(
sp
.
hba_stat
&
0x7f
),
(
u32
)
sp
.
scsi_stat
,
buff
,
&
sp
));
if
(
jiffies
>
i
||
(
fake_int_result
&
1
))
return
(
NULL
);
else
return
(
buff
);
...
...
@@ -610,7 +646,6 @@ char * get_board_data(ulong base, uint irq, uint id)
int
check_blink_state
(
long
base
)
{
uint
ret
=
0
;
uint
loops
=
10
;
ulong
blinkindicator
=
0x42445054
;
ulong
state
=
0x12345678
;
...
...
@@ -621,10 +656,13 @@ int check_blink_state(long base)
state
=
inl
((
uint
)
base
+
1
);
}
DBG
(
DBG_BLINK
,
printk
(
"Did Blink check. Status: %d
\n
"
,
(
state
==
oldstate
)
&&
(
state
==
blinkindicator
)));
if
((
state
==
oldstate
)
&&
(
state
==
blinkindicator
))
ret
=
1
;
DBG
(
DBG_BLINK
,
printk
(
"Did Blink check. Status: %d
\n
"
,
ret
));
return
(
ret
);
return
(
TRUE
)
;
else
return
(
FALSE
);
}
int
get_conf_PIO
(
struct
eata_register
*
base
,
struct
get_conf
*
buf
)
...
...
@@ -632,8 +670,14 @@ int get_conf_PIO(struct eata_register *base, struct get_conf *buf)
ulong
loop
=
R_LIMIT
;
ushort
*
p
;
if
(
check_region
((
uint
)
base
,
9
))
u8
warning
=
FALSE
;
if
(
check_region
((
int
)
base
,
9
))
{
if
((
int
)
base
==
0x1f0
||
(
int
)
base
==
0x170
)
{
warning
=
1
;
}
else
return
(
FALSE
);
}
memset
(
buf
,
0
,
sizeof
(
struct
get_conf
));
...
...
@@ -665,11 +709,15 @@ int get_conf_PIO(struct eata_register *base, struct get_conf *buf)
while
(
inb
((
uint
)
base
+
HA_RSTATUS
)
&
HA_SDRQ
)
inw
((
uint
)
base
+
HA_RDATA
);
if
(
warning
==
TRUE
)
printk
(
"Warning: HBA with IO on 0x%p dectected,
\n
"
" this IO space is already allocated, probably by the IDE driver.
\n
"
" This might lead to problems."
,
base
);
return
(
TRUE
);
}
}
else
{
printk
(
"eata_dma: get_conf_PIO, error during transfer for HBA at %lx"
,
(
long
)
base
);
DBG
(
DBG_PROBE
,
printk
(
"eata_dma: get_conf_PIO, error during transfer "
"for HBA at %lx
\n
"
,
(
long
)
base
)
);
}
return
(
FALSE
);
}
...
...
@@ -701,42 +749,14 @@ int register_HBA(long base, struct get_conf *gc, Scsi_Host_Template * tpnt)
DBG
(
DBG_REGISTER
,
print_config
(
gc
));
if
(
!
gc
->
DMA_support
)
{
printk
(
"HBA at %#.8lx doesn't support DMA. Sorry
\n
"
,
base
);
return
(
FALSE
);
}
if
((
buff
=
get_board_data
((
uint
)
base
,
gc
->
IRQ
,
gc
->
scsi_id
[
3
]))
==
NULL
){
printk
(
"HBA at %#lx didn't react on INQUIRY. Sorry.
\n
"
,
(
ulong
)
base
);
return
(
FALSE
);
}
if
(
gc
->
HAA_valid
==
FALSE
||
ntohl
(
gc
->
len
)
<=
0x1e
)
gc
->
MAX_CHAN
=
0
;
if
(
strncmp
(
"PM2322"
,
&
buff
[
16
],
6
)
&&
strncmp
(
"PM3021"
,
&
buff
[
16
],
6
)
&&
strncmp
(
"PM3222"
,
&
buff
[
16
],
6
)
&&
strncmp
(
"PM3224"
,
&
buff
[
16
],
6
))
if
(
gc
->
HAA_valid
==
FALSE
||
ntohl
(
gc
->
len
)
<
0x22
)
gc
->
MAX_CHAN
=
0
;
/* if gc->DMA_valid it must be a PM2011 and we have to register it */
dma_channel
=
0xff
;
if
(
gc
->
DMA_valid
)
{
if
(
request_dma
(
dma_channel
=
(
8
-
gc
->
DMA_channel
)
&
7
,
"DPT_PM2011"
))
{
printk
(
"Unable to allocate DMA channel %d for HBA PM2011.
\n
"
,
dma_channel
);
return
(
FALSE
);
}
}
if
(
!
reg_IRQ
[
gc
->
IRQ
])
{
/* Interrupt already registered ? */
if
(
!
request_irq
(
gc
->
IRQ
,
eata_int_handler
,
SA_INTERRUPT
,
"EATA-DMA
"
)){
if
(
!
request_irq
(
gc
->
IRQ
,
(
void
*
)
eata_fake_int_handler
,
SA_INTERRUPT
,
"eata_dma
"
)){
reg_IRQ
[
gc
->
IRQ
]
+=
(
gc
->
MAX_CHAN
+
1
);
if
(
!
gc
->
IRQ_TR
)
reg_IRQL
[
gc
->
IRQ
]
=
TRUE
;
/* IRQ is edge triggered */
/* We free it again so we can do a get_conf_dma and
* allocate the interrupt again later */
free_irq
(
gc
->
IRQ
);
}
else
{
printk
(
"Couldn't allocate IRQ %d, Sorry."
,
gc
->
IRQ
);
return
(
FALSE
);
...
...
@@ -750,7 +770,47 @@ int register_HBA(long base, struct get_conf *gc, Scsi_Host_Template * tpnt)
reg_IRQ
[
gc
->
IRQ
]
+=
(
gc
->
MAX_CHAN
+
1
);
}
request_region
(
base
,
9
,
"eata_dma"
);
/* if gc->DMA_valid it must be an ISA HBA and we have to register it */
dma_channel
=
0xff
;
if
(
gc
->
DMA_valid
)
{
if
(
request_dma
(
dma_channel
=
(
8
-
gc
->
DMA_channel
)
&
7
,
"eata_dma"
))
{
printk
(
"Unable to allocate DMA channel %d for ISA HBA at %#.4lx.
\n
"
,
dma_channel
,
base
);
reg_IRQ
[
gc
->
IRQ
]
-=
(
gc
->
MAX_CHAN
+
1
);
if
(
reg_IRQ
[
gc
->
IRQ
]
==
0
)
free_irq
(
gc
->
IRQ
);
if
(
!
gc
->
IRQ_TR
)
reg_IRQL
[
gc
->
IRQ
]
=
FALSE
;
return
(
FALSE
);
}
}
buff
=
get_board_data
(
base
,
gc
->
IRQ
,
gc
->
scsi_id
[
3
]);
if
(
buff
==
NULL
)
{
if
(
gc
->
DMA_support
==
FALSE
)
printk
(
"HBA at %#.4lx doesn't support DMA. Sorry
\n
"
,
base
);
else
printk
(
"HBA at %#.4lx didn't react on INQUIRY. Sorry.
\n
"
,
base
);
if
(
gc
->
DMA_valid
)
free_dma
(
dma_channel
);
reg_IRQ
[
gc
->
IRQ
]
-=
(
gc
->
MAX_CHAN
+
1
);
if
(
reg_IRQ
[
gc
->
IRQ
]
==
0
)
free_irq
(
gc
->
IRQ
);
if
(
!
gc
->
IRQ_TR
)
reg_IRQL
[
gc
->
IRQ
]
=
FALSE
;
return
(
FALSE
);
}
if
(
gc
->
DMA_support
==
FALSE
&&
buff
!=
NULL
)
printk
(
"HBA %.12sat %#.4lx doesn't set the DMA_support flag correctly.
\n
"
,
&
buff
[
16
],
base
);
request_region
(
base
,
9
,
"eata_dma"
);
/* We already checked the
* availability, so this could
* only fail if we're on
* 0x1f0 or 0x170.
*/
if
(
ntohs
(
gc
->
queuesiz
)
==
0
)
{
gc
->
queuesiz
=
ntohs
(
64
);
...
...
@@ -769,6 +829,18 @@ int register_HBA(long base, struct get_conf *gc, Scsi_Host_Template * tpnt)
for
(
i
=
0
;
i
<=
gc
->
MAX_CHAN
;
i
++
)
{
sh
=
scsi_register
(
tpnt
,
size
);
if
(
sh
==
NULL
)
{
if
(
gc
->
DMA_valid
)
free_dma
(
dma_channel
);
reg_IRQ
[
gc
->
IRQ
]
-=
1
;
if
(
reg_IRQ
[
gc
->
IRQ
]
==
0
)
free_irq
(
gc
->
IRQ
);
if
(
!
gc
->
IRQ_TR
)
reg_IRQL
[
gc
->
IRQ
]
=
FALSE
;
return
(
FALSE
);
}
hd
=
SD
(
sh
);
memset
(
hd
->
ccb
,
0
,
(
sizeof
(
struct
eata_ccb
)
*
ntohs
(
gc
->
queuesiz
))
/
...
...
@@ -808,8 +880,10 @@ int register_HBA(long base, struct get_conf *gc, Scsi_Host_Template * tpnt)
if
(
gc
->
OCS_enabled
==
TRUE
)
{
sh
->
cmd_per_lun
=
sh
->
can_queue
/
C_P_L_DIV
;
#if 0 /* The memory management seems to be more stable now */
if (sh->cmd_per_lun > C_P_L_CURRENT_MAX)
sh->cmd_per_lun = C_P_L_CURRENT_MAX;
#endif
}
else
{
sh
->
cmd_per_lun
=
1
;
}
...
...
@@ -940,7 +1014,7 @@ void find_PCI(struct get_conf *buf, Scsi_Host_Template * tpnt)
{
#ifndef CONFIG_PCI
printk
(
"Kernel PCI support not enabled. Skipping.
\n
"
);
printk
(
"Kernel PCI support not enabled. Skipping
scan for PCI HBAs
.
\n
"
);
#else
unchar
pci_bus
,
pci_device_fn
;
...
...
@@ -1041,14 +1115,12 @@ int eata_detect(Scsi_Host_Template * tpnt)
geometry
.
drv
[
0
].
trans
=
geometry
.
drv
[
1
].
trans
=
0
;
printk
(
"EATA (Extended Attachment) driver version: %d.%d%s
\n
"
"developed in co-operation with DPT
\n
"
"(c) 1993-95 Michael Neuffer neuffer@goofy.zdv.uni-mainz.de
\n
"
,
VER_MAJOR
,
VER_MINOR
,
VER_SUB
);
DBG
((
DBG_PROBE
&&
DBG_DELAY
)
||
DPT_DEBUG
,
printk
(
"Using lots of delays to let you read the debugging output
\n
"
));
status
=
scsi_init_malloc
(
512
,
GFP_ATOMIC
|
GFP_DMA
);
dma_scratch
=
scsi_init_malloc
(
512
,
GFP_ATOMIC
|
GFP_DMA
);
find_PCI
(
&
gc
,
tpnt
);
for
(
i
=
0
;
i
<
MAXEISA
;
i
++
)
{
...
...
@@ -1064,23 +1136,40 @@ int eata_detect(Scsi_Host_Template * tpnt)
}
for
(
i
=
0
;
i
<=
MAXIRQ
;
i
++
)
if
(
reg_IRQ
[
i
])
if
(
reg_IRQ
[
i
]){
free_irq
(
i
);
request_irq
(
i
,
eata_int_handler
,
SA_INTERRUPT
,
"EATA-DMA"
);
}
HBA_ptr
=
first_HBA
;
if
(
registered_HBAs
!=
0
)
{
printk
(
"EATA (Extended Attachment) driver version: %d.%d%s
\n
"
"developed in co-operation with DPT
\n
"
"(c) 1993-95 Michael Neuffer neuffer@goofy.zdv.uni-mainz.de
\n
"
,
VER_MAJOR
,
VER_MINOR
,
VER_SUB
);
printk
(
"Registered HBAs:
\n
"
);
printk
(
"HBA no. Boardtype: Revis: EATA: Bus: BaseIO: IRQ: DMA: Ch: ID: Pr: QS: SG: CPL:
\n
"
);
for
(
i
=
1
;
i
<=
registered_HBAs
;
i
++
)
{
printk
(
"scsi%-2d: %.10s v%s 2.0%c %s %#.4x %2d %2x %d %d %d %2d %2d %2d
\n
"
,
printk
(
"scsi%-2d: %.10s v%s 2.0%c %s %#.4lx %2d"
,
HBA_ptr
->
host_no
,
SD
(
HBA_ptr
)
->
name
,
SD
(
HBA_ptr
)
->
revision
,
SD
(
HBA_ptr
)
->
EATA_revision
,
(
SD
(
HBA_ptr
)
->
bustype
==
'P'
)
?
"PCI "
:
(
SD
(
HBA_ptr
)
->
bustype
==
'E'
)
?
"EISA"
:
"ISA "
,
(
uint
)
HBA_ptr
->
base
,
HBA_ptr
->
irq
,
HBA_ptr
->
dma_channel
,
SD
(
HBA_ptr
)
->
channel
,
HBA_ptr
->
this_id
,
SD
(
HBA_ptr
)
->
primary
,
(
u32
)
HBA_ptr
->
base
,
HBA_ptr
->
irq
);
if
(
HBA_ptr
->
dma_channel
!=
0xff
)
printk
(
" %2x "
,
HBA_ptr
->
dma_channel
);
else
printk
(
" %s"
,
"BMST"
);
printk
(
" %d %d %c %2d %2d %2d
\n
"
,
SD
(
HBA_ptr
)
->
channel
,
HBA_ptr
->
this_id
,
(
SD
(
HBA_ptr
)
->
primary
==
TRUE
)
?
'Y'
:
'N'
,
HBA_ptr
->
can_queue
,
HBA_ptr
->
sg_tablesize
,
HBA_ptr
->
cmd_per_lun
);
HBA_ptr
=
SD
(
HBA_ptr
)
->
next
;
}
}
else
scsi_init_free
((
void
*
)
status
,
512
);
scsi_init_free
((
void
*
)
dma_scratch
,
512
);
DBG
(
DPT_DEBUG
,
DELAY
(
1200
));
return
(
registered_HBAs
);
...
...
drivers/scsi/eata_dma.h
View file @
3793c9b9
...
...
@@ -2,7 +2,7 @@
* Header file for eata_dma.c Linux EATA-DMA SCSI driver *
* (c) 1993,94,95 Michael Neuffer *
*********************************************************
* last change: 95/0
2/13
*
* last change: 95/0
4/10
*
********************************************************/
...
...
@@ -11,7 +11,7 @@
#define VER_MAJOR 2
#define VER_MINOR 3
#define VER_SUB "
1a
"
#define VER_SUB "
5r
"
/************************************************************************
* Here you can configure your drives that are using a non-standard *
...
...
@@ -61,6 +61,7 @@
#define DBG_QUEUE 0
/* Trace command queueing. */
#define DBG_INTR 0
/* Trace interrupt service routine. */
#define DBG_INTR2 0
/* Trace interrupt service routine. */
#define DBG_INTR3 0
/* Trace interrupt service routine. */
#define DBG_PROC 0
/* Debug proc-fs related statistics */
#define DBG_REGISTER 0
/* */
#define DBG_ABNORM 1
/* Debug abnormal actions (reset, abort)*/
...
...
@@ -125,13 +126,15 @@ int eata_release(struct Scsi_Host *);
#define SG_SIZE 64
#define C_P_L_CURRENT_MAX 1
0
/* Until this limit in the mm is removed
#define C_P_L_CURRENT_MAX 1
6
/* Until this limit in the mm is removed
* Kernels < 1.1.86 died horrible deaths
* if you used values >2. The memory management
* since pl1.1.86 seems to cope with up to 10
* queued commands per device.
* Since 1.2.0 the memory management seems to
* have no more problems......
*/
#define C_P_L_DIV
4
/* 1 <= C_P_L_DIV <= 8
#define C_P_L_DIV
3
/* 1 <= C_P_L_DIV <= 8
* You can use this parameter to fine-tune
* the driver. Depending on the number of
* devices and their speed and ability to queue
...
...
@@ -201,6 +204,24 @@ int eata_release(struct Scsi_Host *);
#define HA_SBUSY 0x80
/* drive busy */
#define HA_SDRDY HA_SSC+HA_SREADY+HA_SDRQ
#define HA_NO_ERROR 0x00
#define HA_ERR_SEL_TO 0x01
#define HA_ERR_CMD_TO 0x02
#define HA_ERR_RESET 0x03
#define HA_INIT_POWERUP 0x04
#define HA_UNX_BUSPHASE 0x05
#define HA_UNX_BUS_FREE 0x06
#define HA_BUS_PARITY 0x07
#define HA_SCSI_HUNG 0x08
#define HA_UNX_MSGRJCT 0x09
#define HA_RESET_STUCK 0x0a
#define HA_RSENSE_FAIL 0x0b
#define HA_PARITY_ERR 0x0c
#define HA_CP_ABORT_NA 0x0d
#define HA_CP_ABORTED 0x0e
#define HA_CP_RESET_NA 0x0f
#define HA_CP_RESET 0x10
/**********************************************
* Message definitions *
**********************************************/
...
...
drivers/scsi/scsi.c
View file @
3793c9b9
...
...
@@ -387,7 +387,8 @@ void scan_scsis (struct Scsi_Host * shpnt)
if
(
SCpnt
->
result
)
{
if
((
driver_byte
(
SCpnt
->
result
)
&
DRIVER_SENSE
)
&&
if
(((
driver_byte
(
SCpnt
->
result
)
&
DRIVER_SENSE
)
||
(
status_byte
(
SCpnt
->
result
)
&
CHECK_CONDITION
))
&&
((
SCpnt
->
sense_buffer
[
0
]
&
0x70
)
>>
4
)
==
7
)
{
if
(
SCpnt
->
sense_buffer
[
2
]
&
0xe0
)
continue
;
/* No devices here... */
...
...
drivers/scsi/scsi.h
View file @
3793c9b9
...
...
@@ -50,6 +50,7 @@
#define SEND_DIAGNOSTIC 0x1d
#define ALLOW_MEDIUM_REMOVAL 0x1e
#define SET_WINDOW 0x24
#define READ_CAPACITY 0x25
#define READ_10 0x28
#define WRITE_10 0x2a
...
...
@@ -65,16 +66,26 @@
#define SYNCHRONIZE_CACHE 0x35
#define LOCK_UNLOCK_CACHE 0x36
#define READ_DEFECT_DATA 0x37
#define MEDIUM_SCAN 0x38
#define COMPARE 0x39
#define COPY_VERIFY 0x3a
#define WRITE_BUFFER 0x3b
#define READ_BUFFER 0x3c
#define UPDATE_BLOCK 0x3d
#define READ_LONG 0x3e
#define WRITE_LONG 0x3f
#define CHANGE_DEFINITION 0x40
#define WRITE_SAME 0x41
#define LOG_SELECT 0x4c
#define LOG_SENSE 0x4d
#define MODE_SELECT_10 0x55
#define MODE_SENSE_10 0x5a
#define WRITE_12 0xaa
#define WRITE_VERIFY_12 0xae
#define SEARCH_HIGH_12 0xb0
#define SEARCH_EQUAL_12 0xb1
#define SEARCH_LOW_12 0xb2
#define SEND_VOLUME_TAG 0xb6
extern
void
scsi_make_blocked_list
(
void
);
extern
volatile
int
in_scan_scsis
;
...
...
drivers/scsi/sd.c
View file @
3793c9b9
...
...
@@ -358,8 +358,8 @@ static void do_sd_request (void)
unsigned
long
flags
;
int
flag
=
0
;
save_flags
(
flags
);
while
(
1
==
1
){
save_flags
(
flags
);
cli
();
if
(
CURRENT
!=
NULL
&&
CURRENT
->
dev
==
-
1
)
{
restore_flags
(
flags
);
...
...
@@ -387,12 +387,10 @@ static void do_sd_request (void)
/*
* The following restore_flags leads to latency problems. FIXME.
* Using a "sti()" gets rid of the latency problems but causes
* race conditions and crashes.
*/
#if 0
restore_flags
(
flags
);
#else
sti
();
#endif
/* This is a performance enhancement. We dig down into the request list and
try and find a queueable request (i.e. device not busy, and host able to
...
...
@@ -404,7 +402,6 @@ static void do_sd_request (void)
if
(
!
SCpnt
&&
sd_template
.
nr_dev
>
1
){
struct
request
*
req1
;
req1
=
NULL
;
save_flags
(
flags
);
cli
();
req
=
CURRENT
;
while
(
req
){
...
...
drivers/scsi/st.c
View file @
3793c9b9
...
...
@@ -1063,8 +1063,7 @@ st_read(struct inode * inode, struct file * filp, char * buf, int count)
SCpnt
->
request
.
dev
=
dev
;
scsi_do_cmd
(
SCpnt
,
(
void
*
)
cmd
,
(
STp
->
buffer
)
->
b_data
,
(
STp
->
buffer
)
->
buffer_size
,
st_sleep_done
,
ST_TIMEOUT
,
MAX_RETRIES
);
bytes
,
st_sleep_done
,
ST_TIMEOUT
,
MAX_RETRIES
);
/* this must be done with interrupts off */
...
...
fs/isofs/inode.c
View file @
3793c9b9
...
...
@@ -79,7 +79,7 @@ static int parse_options(char *options, struct iso9660_options * popt)
popt
->
rock
=
'y'
;
popt
->
cruft
=
'n'
;
popt
->
unhide
=
'n'
;
popt
->
conversion
=
'
a'
;
popt
->
conversion
=
'
b'
;
/* default: no conversion */
popt
->
blocksize
=
1024
;
popt
->
mode
=
S_IRUGO
;
popt
->
gid
=
0
;
...
...
include/linux/major.h
View file @
3793c9b9
...
...
@@ -7,8 +7,8 @@
/* limits */
#define MAX_CHRDEV
32
#define MAX_BLKDEV
32
#define MAX_CHRDEV
64
#define MAX_BLKDEV
64
/*
* assignments
...
...
include/linux/serial.h
View file @
3793c9b9
...
...
@@ -140,6 +140,7 @@ struct async_struct {
int
xmit_tail
;
int
xmit_cnt
;
struct
tq_struct
tqueue
;
struct
tq_struct
tqueue_hangup
;
struct
termios
normal_termios
;
struct
termios
callout_termios
;
struct
wait_queue
*
open_wait
;
...
...
@@ -160,7 +161,6 @@ struct async_struct {
* time, instead of at rs interrupt time.
*/
#define RS_EVENT_WRITE_WAKEUP 0
#define RS_EVENT_HANGUP 1
/*
* Multiport serial configuration structure --- internal structure
...
...
include/linux/tqueue.h
View file @
3793c9b9
...
...
@@ -57,7 +57,7 @@ typedef struct tq_struct * task_queue;
#define DECLARE_TASK_QUEUE(q) task_queue q = &tq_last
extern
struct
tq_struct
tq_last
;
extern
task_queue
tq_timer
,
tq_immediate
;
extern
task_queue
tq_timer
,
tq_immediate
,
tq_scheduler
;
#ifdef INCLUDE_INLINE_FUNCS
struct
tq_struct
tq_last
=
{
...
...
kernel/ksyms.c
View file @
3793c9b9
...
...
@@ -41,8 +41,10 @@
#include <linux/tcp.h>
#include "../net/inet/protocol.h"
#include "../net/inet/arp.h"
#if defined(CONFIG_PPP) || defined(CONFIG_SLIP)
#include "../drivers/net/slhc.h"
#endif
#endif
#ifdef CONFIG_PCI
#include <linux/pci.h>
#endif
...
...
@@ -209,6 +211,7 @@ struct symbol_table symbol_table = {
X
(
del_timer
),
X
(
tq_timer
),
X
(
tq_immediate
),
X
(
tq_scheduler
),
X
(
tq_last
),
X
(
timer_active
),
X
(
timer_table
),
...
...
@@ -273,11 +276,13 @@ struct symbol_table symbol_table = {
#ifdef CONFIG_INET
X
(
inet_add_protocol
),
X
(
inet_del_protocol
),
#if defined(CONFIG_PPP) || defined(CONFIG_SLIP)
X
(
slhc_init
),
X
(
slhc_free
),
X
(
slhc_remember
),
X
(
slhc_compress
),
X
(
slhc_uncompress
),
#endif
#endif
/* Device callback registration */
X
(
register_netdevice_notifier
),
...
...
@@ -323,6 +328,8 @@ struct symbol_table symbol_table = {
X
(
scsi_register
),
X
(
scsi_unregister
),
X
(
scsicam_bios_param
),
X
(
scsi_init_malloc
),
X
(
scsi_init_free
),
X
(
print_command
),
#endif
/* Added to make file system as module */
...
...
kernel/sched.c
View file @
3793c9b9
...
...
@@ -45,6 +45,7 @@ int tickadj = 500/HZ; /* microsecs */
DECLARE_TASK_QUEUE
(
tq_timer
);
DECLARE_TASK_QUEUE
(
tq_immediate
);
DECLARE_TASK_QUEUE
(
tq_scheduler
);
/*
* phase-lock loop variables
...
...
@@ -119,6 +120,7 @@ asmlinkage void schedule(void)
printk
(
"Aiee: scheduling in interrupt
\n
"
);
intr_count
=
0
;
}
run_task_queue
(
&
tq_scheduler
);
cli
();
ticks
=
itimer_ticks
;
itimer_ticks
=
0
;
...
...
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