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
cd509844
Commit
cd509844
authored
Oct 08, 2002
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wd7000 indent pass, no code changes
indent -kr -i8 -bri0 -l255 wd7000.{c,h}
parent
6f720ad0
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
919 additions
and
968 deletions
+919
-968
drivers/scsi/wd7000.c
drivers/scsi/wd7000.c
+909
-958
drivers/scsi/wd7000.h
drivers/scsi/wd7000.h
+10
-10
No files found.
drivers/scsi/wd7000.c
View file @
cd509844
...
...
@@ -244,15 +244,13 @@ typedef struct adapter {
/*
* (linear) base address for ROM BIOS
*/
static
const
long
wd7000_biosaddr
[]
=
{
static
const
long
wd7000_biosaddr
[]
=
{
0xc0000
,
0xc2000
,
0xc4000
,
0xc6000
,
0xc8000
,
0xca000
,
0xcc000
,
0xce000
,
0xd0000
,
0xd2000
,
0xd4000
,
0xd6000
,
0xd8000
,
0xda000
,
0xdc000
,
0xde000
};
#define NUM_ADDRS (sizeof(wd7000_biosaddr)/sizeof(long))
static
const
unsigned
short
wd7000_iobase
[]
=
{
static
const
unsigned
short
wd7000_iobase
[]
=
{
0x0300
,
0x0308
,
0x0310
,
0x0318
,
0x0320
,
0x0328
,
0x0330
,
0x0338
,
0x0340
,
0x0348
,
0x0350
,
0x0358
,
0x0360
,
0x0368
,
0x0370
,
0x0378
,
0x0380
,
0x0388
,
0x0390
,
0x0398
,
0x03a0
,
0x03a8
,
0x03b0
,
0x03b8
,
...
...
@@ -294,12 +292,11 @@ typedef struct {
/*
* Add here your configuration...
*/
static
Config
configs
[]
=
{
{
15
,
6
,
0x350
,
BUS_ON
,
BUS_OFF
},
/* defaults for single adapter */
{
11
,
5
,
0x320
,
BUS_ON
,
BUS_OFF
},
/* defaults for second adapter */
{
7
,
6
,
0x350
,
BUS_ON
,
BUS_OFF
},
/* My configuration (Zaga) */
{
-
1
,
-
1
,
0x0
,
BUS_ON
,
BUS_OFF
}
/* Empty slot */
static
Config
configs
[]
=
{
{
15
,
6
,
0x350
,
BUS_ON
,
BUS_OFF
},
/* defaults for single adapter */
{
11
,
5
,
0x320
,
BUS_ON
,
BUS_OFF
},
/* defaults for second adapter */
{
7
,
6
,
0x350
,
BUS_ON
,
BUS_OFF
},
/* My configuration (Zaga) */
{
-
1
,
-
1
,
0x0
,
BUS_ON
,
BUS_OFF
}
/* Empty slot */
};
#define NUM_CONFIGS (sizeof(configs)/sizeof(Config))
...
...
@@ -314,8 +311,7 @@ typedef struct signature {
unsigned
len
;
/* length of string */
}
Signature
;
static
const
Signature
signatures
[]
=
{
static
const
Signature
signatures
[]
=
{
{
"SSTBIOS"
,
0x0000d
,
7
}
/* "SSTBIOS" @ offset 0x0000d */
};
#define NUM_SIGNATURES (sizeof(signatures)/sizeof(Signature))
...
...
@@ -594,14 +590,11 @@ static spinlock_t scbpool_lock; /* guards the scb free list and count */
static
void
__init
setup_error
(
char
*
mesg
,
int
*
ints
)
{
if
(
ints
[
0
]
==
3
)
printk
(
KERN_ERR
"wd7000_setup:
\"
wd7000=%d,%d,0x%x
\"
-> %s
\n
"
,
ints
[
1
],
ints
[
2
],
ints
[
3
],
mesg
);
printk
(
KERN_ERR
"wd7000_setup:
\"
wd7000=%d,%d,0x%x
\"
-> %s
\n
"
,
ints
[
1
],
ints
[
2
],
ints
[
3
],
mesg
);
else
if
(
ints
[
0
]
==
4
)
printk
(
KERN_ERR
"wd7000_setup:
\"
wd7000=%d,%d,0x%x,%d
\"
-> %s
\n
"
,
ints
[
1
],
ints
[
2
],
ints
[
3
],
ints
[
4
],
mesg
);
printk
(
KERN_ERR
"wd7000_setup:
\"
wd7000=%d,%d,0x%x,%d
\"
-> %s
\n
"
,
ints
[
1
],
ints
[
2
],
ints
[
3
],
ints
[
4
],
mesg
);
else
printk
(
KERN_ERR
"wd7000_setup:
\"
wd7000=%d,%d,0x%x,%d,%d
\"
-> %s
\n
"
,
ints
[
1
],
ints
[
2
],
ints
[
3
],
ints
[
4
],
ints
[
5
],
mesg
);
printk
(
KERN_ERR
"wd7000_setup:
\"
wd7000=%d,%d,0x%x,%d,%d
\"
-> %s
\n
"
,
ints
[
1
],
ints
[
2
],
ints
[
3
],
ints
[
4
],
ints
[
5
],
mesg
);
}
...
...
@@ -625,19 +618,15 @@ static int __init wd7000_setup(char *str)
short
i
;
int
ints
[
6
];
(
void
)
get_options
(
str
,
ARRAY_SIZE
(
ints
),
ints
);
(
void
)
get_options
(
str
,
ARRAY_SIZE
(
ints
),
ints
);
if
(
wd7000_card_num
>=
NUM_CONFIGS
)
{
printk
(
KERN_ERR
"%s: Too many
\"
wd7000=
\"
configurations in "
"command line!
\n
"
,
__FUNCTION__
);
printk
(
KERN_ERR
"%s: Too many
\"
wd7000=
\"
configurations in "
"command line!
\n
"
,
__FUNCTION__
);
return
0
;
}
if
((
ints
[
0
]
<
3
)
||
(
ints
[
0
]
>
5
))
{
printk
(
KERN_ERR
"%s: Error in command line! "
"Usage: wd7000=<IRQ>,<DMA>,IO>[,<BUS_ON>"
"[,<BUS_OFF>]]
\n
"
,
__FUNCTION__
);
printk
(
KERN_ERR
"%s: Error in command line! "
"Usage: wd7000=<IRQ>,<DMA>,IO>[,<BUS_ON>"
"[,<BUS_OFF>]]
\n
"
,
__FUNCTION__
);
}
else
{
for
(
i
=
0
;
i
<
NUM_IRQS
;
i
++
)
if
(
ints
[
1
]
==
wd7000_irq
[
i
])
...
...
@@ -671,8 +660,7 @@ static int __init wd7000_setup(char *str)
if
(
ints
[
0
]
>
3
)
{
if
((
ints
[
4
]
<
500
)
||
(
ints
[
4
]
>
31875
))
{
setup_error
(
"BUS_ON value is out of range (500"
" to 31875 nanoseconds)!"
,
ints
);
setup_error
(
"BUS_ON value is out of range (500"
" to 31875 nanoseconds)!"
,
ints
);
configs
[
wd7000_card_num
].
bus_on
=
BUS_ON
;
}
else
configs
[
wd7000_card_num
].
bus_on
=
ints
[
4
]
/
125
;
...
...
@@ -681,12 +669,10 @@ static int __init wd7000_setup(char *str)
if
(
ints
[
0
]
>
4
)
{
if
((
ints
[
5
]
<
500
)
||
(
ints
[
5
]
>
31875
))
{
setup_error
(
"BUS_OFF value is out of range (500"
" to 31875 nanoseconds)!"
,
ints
);
setup_error
(
"BUS_OFF value is out of range (500"
" to 31875 nanoseconds)!"
,
ints
);
configs
[
wd7000_card_num
].
bus_off
=
BUS_OFF
;
}
else
configs
[
wd7000_card_num
].
bus_off
=
ints
[
5
]
/
125
;
configs
[
wd7000_card_num
].
bus_off
=
ints
[
5
]
/
125
;
}
else
configs
[
wd7000_card_num
].
bus_off
=
BUS_OFF
;
...
...
@@ -696,32 +682,22 @@ static int __init wd7000_setup(char *str)
for
(;
j
<
wd7000_card_num
;
j
++
)
if
(
configs
[
i
].
irq
==
configs
[
j
].
irq
)
{
setup_error
(
"duplicated IRQ!"
,
ints
);
setup_error
(
"duplicated IRQ!"
,
ints
);
return
0
;
}
if
(
configs
[
i
].
dma
==
configs
[
j
].
dma
)
{
setup_error
(
"duplicated DMA "
"channel!"
,
ints
);
setup_error
(
"duplicated DMA "
"channel!"
,
ints
);
return
0
;
}
if
(
configs
[
i
].
iobase
==
configs
[
j
].
iobase
)
{
setup_error
(
"duplicated I/O "
"base address!"
,
ints
);
if
(
configs
[
i
].
iobase
==
configs
[
j
].
iobase
)
{
setup_error
(
"duplicated I/O "
"base address!"
,
ints
);
return
0
;
}
}
}
dprintk
(
KERN_DEBUG
"wd7000_setup: IRQ=%d, DMA=%d, I/O=0x%x, "
"BUS_ON=%dns, BUS_OFF=%dns
\n
"
,
configs
[
wd7000_card_num
].
irq
,
configs
[
wd7000_card_num
].
dma
,
configs
[
wd7000_card_num
].
iobase
,
configs
[
wd7000_card_num
].
bus_on
*
125
,
configs
[
wd7000_card_num
].
bus_off
*
125
);
"BUS_ON=%dns, BUS_OFF=%dns
\n
"
,
configs
[
wd7000_card_num
].
irq
,
configs
[
wd7000_card_num
].
dma
,
configs
[
wd7000_card_num
].
iobase
,
configs
[
wd7000_card_num
].
bus_on
*
125
,
configs
[
wd7000_card_num
].
bus_off
*
125
);
wd7000_card_num
++
;
}
...
...
@@ -741,11 +717,11 @@ __setup("wd7000=", wd7000_setup);
*/
typedef
union
{
/* let's cheat... */
int
i
;
unchar
u
[
sizeof
(
int
)];
/* the sizeof(int) makes it more portable */
unchar
u
[
sizeof
(
int
)];
/* the sizeof(int) makes it more portable */
}
i_u
;
static
inline
void
any2scsi
(
unchar
*
scsi
,
int
any
)
static
inline
void
any2scsi
(
unchar
*
scsi
,
int
any
)
{
*
scsi
++
=
((
i_u
)
any
).
u
[
2
];
*
scsi
++
=
((
i_u
)
any
).
u
[
1
];
...
...
@@ -753,7 +729,7 @@ static inline void any2scsi (unchar * scsi, int any)
}
static
inline
int
scsi2int
(
unchar
*
scsi
)
static
inline
int
scsi2int
(
unchar
*
scsi
)
{
i_u
result
;
...
...
@@ -780,22 +756,22 @@ static inline int scsi2int (unchar * scsi)
#endif
static
inline
void
wd7000_enable_intr
(
Adapter
*
host
)
static
inline
void
wd7000_enable_intr
(
Adapter
*
host
)
{
host
->
control
|=
INT_EN
;
outb
(
host
->
control
,
host
->
iobase
+
ASC_CONTROL
);
outb
(
host
->
control
,
host
->
iobase
+
ASC_CONTROL
);
}
static
inline
void
wd7000_enable_dma
(
Adapter
*
host
)
static
inline
void
wd7000_enable_dma
(
Adapter
*
host
)
{
unsigned
long
flags
;
host
->
control
|=
DMA_EN
;
outb
(
host
->
control
,
host
->
iobase
+
ASC_CONTROL
);
outb
(
host
->
control
,
host
->
iobase
+
ASC_CONTROL
);
flags
=
claim_dma_lock
();
set_dma_mode
(
host
->
dma
,
DMA_MODE_CASCADE
);
enable_dma
(
host
->
dma
);
set_dma_mode
(
host
->
dma
,
DMA_MODE_CASCADE
);
enable_dma
(
host
->
dma
);
release_dma_lock
(
flags
);
}
...
...
@@ -803,13 +779,13 @@ static inline void wd7000_enable_dma (Adapter *host)
#define WAITnexttimeout 200
/* 2 seconds */
static
inline
short
WAIT
(
unsigned
port
,
unsigned
mask
,
unsigned
allof
,
unsigned
noneof
)
static
inline
short
WAIT
(
unsigned
port
,
unsigned
mask
,
unsigned
allof
,
unsigned
noneof
)
{
register
unsigned
WAITbits
;
register
unsigned
long
WAITtimeout
=
jiffies
+
WAITnexttimeout
;
while
(
time_before_eq
(
jiffies
,
WAITtimeout
))
{
WAITbits
=
inb
(
port
)
&
mask
;
WAITbits
=
inb
(
port
)
&
mask
;
if
(((
WAITbits
&
allof
)
==
allof
)
&&
((
WAITbits
&
noneof
)
==
0
))
return
(
0
);
...
...
@@ -819,14 +795,14 @@ static inline short WAIT (unsigned port, unsigned mask, unsigned allof, unsigned
}
static
inline
int
command_out
(
Adapter
*
host
,
unchar
*
cmd
,
int
len
)
static
inline
int
command_out
(
Adapter
*
host
,
unchar
*
cmd
,
int
len
)
{
if
(
!
WAIT
(
host
->
iobase
+
ASC_STAT
,
ASC_STATMASK
,
CMD_RDY
,
0
))
{
if
(
!
WAIT
(
host
->
iobase
+
ASC_STAT
,
ASC_STATMASK
,
CMD_RDY
,
0
))
{
while
(
len
--
)
{
do
{
outb
(
*
cmd
,
host
->
iobase
+
ASC_COMMAND
);
WAIT
(
host
->
iobase
+
ASC_STAT
,
ASC_STATMASK
,
CMD_RDY
,
0
);
}
while
(
inb
(
host
->
iobase
+
ASC_STAT
)
&
CMD_REJ
);
outb
(
*
cmd
,
host
->
iobase
+
ASC_COMMAND
);
WAIT
(
host
->
iobase
+
ASC_STAT
,
ASC_STATMASK
,
CMD_RDY
,
0
);
}
while
(
inb
(
host
->
iobase
+
ASC_STAT
)
&
CMD_REJ
);
cmd
++
;
}
...
...
@@ -863,12 +839,12 @@ static inline Scb *alloc_scbs(struct Scsi_Host *host, int needed)
spin_unlock_irq
(
host
->
host_lock
);
retry:
retry:
while
(
freescbs
<
needed
)
{
timeout
=
jiffies
+
WAITnexttimeout
;
do
{
/* FIXME: can we actually just yield here ?? */
for
(
now
=
jiffies
;
now
==
jiffies
;
)
for
(
now
=
jiffies
;
now
==
jiffies
;
)
cpu_relax
();
/* wait a jiffy */
}
while
(
freescbs
<
needed
&&
time_before_eq
(
jiffies
,
timeout
));
/*
...
...
@@ -876,15 +852,14 @@ static inline Scb *alloc_scbs(struct Scsi_Host *host, int needed)
* Otherwise, we timed out and didn't get enough.
*/
if
(
freescbs
<
needed
)
{
printk
(
KERN_ERR
"wd7000: can't get enough free SCBs.
\n
"
);
printk
(
KERN_ERR
"wd7000: can't get enough free SCBs.
\n
"
);
return
(
NULL
);
}
}
/* Take the lock, then check we didnt get beaten, if so try again */
spin_lock_irqsave
(
&
scbpool_lock
,
flags
);
if
(
freescbs
<
needed
)
{
if
(
freescbs
<
needed
)
{
spin_unlock_irqrestore
(
&
scbpool_lock
,
flags
);
goto
retry
;
}
...
...
@@ -904,13 +879,13 @@ static inline Scb *alloc_scbs(struct Scsi_Host *host, int needed)
}
static
inline
void
free_scb
(
Scb
*
scb
)
static
inline
void
free_scb
(
Scb
*
scb
)
{
register
unsigned
long
flags
;
spin_lock_irqsave
(
&
scbpool_lock
,
flags
);
memset
(
scb
,
0
,
sizeof
(
Scb
));
memset
(
scb
,
0
,
sizeof
(
Scb
));
scb
->
next
=
scbfree
;
scbfree
=
scb
;
freescbs
++
;
...
...
@@ -919,7 +894,7 @@ static inline void free_scb (Scb *scb)
}
static
inline
void
init_scbs
(
void
)
static
inline
void
init_scbs
(
void
)
{
int
i
;
...
...
@@ -928,7 +903,7 @@ static inline void init_scbs (void)
/* This is only ever called before the SCB pool is active */
scbfree
=
&
(
scbs
[
0
]);
memset
(
scbs
,
0
,
sizeof
(
scbs
));
memset
(
scbs
,
0
,
sizeof
(
scbs
));
for
(
i
=
0
;
i
<
MAX_SCBS
-
1
;
i
++
)
{
scbs
[
i
].
next
=
&
(
scbs
[
i
+
1
]);
scbs
[
i
].
SCpnt
=
NULL
;
...
...
@@ -938,7 +913,7 @@ static inline void init_scbs (void)
}
static
int
mail_out
(
Adapter
*
host
,
Scb
*
scbptr
)
static
int
mail_out
(
Adapter
*
host
,
Scb
*
scbptr
)
/*
* Note: this can also be used for ICBs; just cast to the parm type.
*/
...
...
@@ -958,12 +933,11 @@ static int mail_out (Adapter *host, Scb *scbptr)
if
(
ogmbs
[
ogmb
].
status
==
0
)
{
dprintk
(
" using OGMB 0x%x"
,
ogmb
);
ogmbs
[
ogmb
].
status
=
1
;
any2scsi
((
unchar
*
)
ogmbs
[
ogmb
].
scbptr
,
(
int
)
scbptr
);
any2scsi
((
unchar
*
)
ogmbs
[
ogmb
].
scbptr
,
(
int
)
scbptr
);
*
next_ogmb
=
(
ogmb
+
1
)
%
OGMB_CNT
;
break
;
}
else
}
else
ogmb
=
(
ogmb
+
1
)
%
OGMB_CNT
;
}
spin_unlock_irqrestore
(
host
->
sh
->
host_lock
,
flags
);
...
...
@@ -983,10 +957,10 @@ static int mail_out (Adapter *host, Scb *scbptr)
return
(
0
);
}
wd7000_enable_intr
(
host
);
wd7000_enable_intr
(
host
);
start_ogmb
=
START_OGMB
|
ogmb
;
command_out
(
host
,
&
start_ogmb
,
1
);
command_out
(
host
,
&
start_ogmb
,
1
);
dprintk
(
", awaiting interrupt.
\n
"
);
...
...
@@ -994,7 +968,7 @@ static int mail_out (Adapter *host, Scb *scbptr)
}
static
int
make_code
(
unsigned
hosterr
,
unsigned
scsierr
)
static
int
make_code
(
unsigned
hosterr
,
unsigned
scsierr
)
{
#ifdef WD7000_DEBUG
int
in_error
=
hosterr
;
...
...
@@ -1035,41 +1009,40 @@ static int make_code (unsigned hosterr, unsigned scsierr)
}
#ifdef WD7000_DEBUG
if
(
scsierr
||
hosterr
)
dprintk
(
"
\n
SCSI command error: SCSI 0x%02x host 0x%04x return %d
\n
"
,
scsierr
,
in_error
,
hosterr
);
dprintk
(
"
\n
SCSI command error: SCSI 0x%02x host 0x%04x return %d
\n
"
,
scsierr
,
in_error
,
hosterr
);
#endif
return
(
scsierr
|
(
hosterr
<<
16
));
}
static
void
wd7000_scsi_done
(
Scsi_Cmnd
*
SCpnt
)
static
void
wd7000_scsi_done
(
Scsi_Cmnd
*
SCpnt
)
{
dprintk
(
"wd7000_scsi_done: 0x%06lx
\n
"
,
(
long
)
SCpnt
);
dprintk
(
"wd7000_scsi_done: 0x%06lx
\n
"
,
(
long
)
SCpnt
);
SCpnt
->
SCp
.
phase
=
0
;
}
#define wd7000_intr_ack(host) outb (0, host->iobase + ASC_INTR_ACK)
static
void
wd7000_intr_handle
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
static
void
wd7000_intr_handle
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
register
int
flag
,
icmb
,
errstatus
,
icmb_status
;
register
int
host_error
,
scsi_error
;
register
Scb
*
scb
;
/* for SCSI commands */
register
IcbAny
*
icb
;
/* for host commands */
register
Scsi_Cmnd
*
SCpnt
;
Adapter
*
host
=
(
Adapter
*
)
dev_id
;
Adapter
*
host
=
(
Adapter
*
)
dev_id
;
Mailbox
*
icmbs
=
host
->
mb
.
icmb
;
host
->
int_counter
++
;
dprintk
(
"wd7000_intr_handle: irq = %d, host = 0x%06lx
\n
"
,
irq
,
(
long
)
host
);
flag
=
inb
(
host
->
iobase
+
ASC_INTR_STAT
);
flag
=
inb
(
host
->
iobase
+
ASC_INTR_STAT
);
dprintk
(
"wd7000_intr_handle: intr stat = 0x%02x
\n
"
,
flag
);
if
(
!
(
inb
(
host
->
iobase
+
ASC_STAT
)
&
INT_IM
))
{
if
(
!
(
inb
(
host
->
iobase
+
ASC_STAT
)
&
INT_IM
))
{
/* NB: these are _very_ possible if IRQ 15 is being used, since
* it's the "garbage collector" on the 2nd 8259 PIC. Specifically,
* any interrupt signal into the 8259 which can't be identified
...
...
@@ -1079,7 +1052,7 @@ static void wd7000_intr_handle (int irq, void *dev_id, struct pt_regs *regs)
* problems would be indistinguishable from valid interrupts...
*/
dprintk
(
"wd7000_intr_handle: phantom interrupt...
\n
"
);
wd7000_intr_ack
(
host
);
wd7000_intr_ack
(
host
);
return
;
}
...
...
@@ -1092,36 +1065,33 @@ static void wd7000_intr_handle (int irq, void *dev_id, struct pt_regs *regs)
* used in mail_out(), wake_up() should correspondingly be called
* here. For now, we don't need to do anything special.
*/
wd7000_intr_ack
(
host
);
wd7000_intr_ack
(
host
);
return
;
}
else
{
}
else
{
/* The interrupt is for an incoming mailbox */
icmb
=
flag
&
MB_MASK
;
icmb_status
=
icmbs
[
icmb
].
status
;
if
(
icmb_status
&
0x80
)
{
/* unsolicited - result in ICMB */
dprintk
(
"wd7000_intr_handle: unsolicited interrupt 0x%02x
\n
"
,
icmb_status
);
wd7000_intr_ack
(
host
);
dprintk
(
"wd7000_intr_handle: unsolicited interrupt 0x%02x
\n
"
,
icmb_status
);
wd7000_intr_ack
(
host
);
return
;
}
/* Aaaargh! (Zaga) */
scb
=
isa_bus_to_virt
(
scsi2int
((
unchar
*
)
icmbs
[
icmb
].
scbptr
));
scb
=
isa_bus_to_virt
(
scsi2int
((
unchar
*
)
icmbs
[
icmb
].
scbptr
));
icmbs
[
icmb
].
status
=
0
;
if
(
!
(
scb
->
op
&
ICB_OP_MASK
))
{
/* an SCB is done */
SCpnt
=
scb
->
SCpnt
;
if
(
--
(
SCpnt
->
SCp
.
phase
)
<=
0
)
{
/* all scbs are done */
host_error
=
scb
->
vue
|
(
icmb_status
<<
8
);
scsi_error
=
scb
->
status
;
errstatus
=
make_code
(
host_error
,
scsi_error
);
errstatus
=
make_code
(
host_error
,
scsi_error
);
SCpnt
->
result
=
errstatus
;
free_scb
(
scb
);
free_scb
(
scb
);
SCpnt
->
scsi_done
(
SCpnt
);
SCpnt
->
scsi_done
(
SCpnt
);
}
}
else
{
/* an ICB is done */
}
else
{
/* an ICB is done */
icb
=
(
IcbAny
*
)
scb
;
icb
->
status
=
icmb_status
;
icb
->
phase
=
0
;
...
...
@@ -1129,12 +1099,12 @@ static void wd7000_intr_handle (int irq, void *dev_id, struct pt_regs *regs)
}
/* incoming mailbox */
}
wd7000_intr_ack
(
host
);
wd7000_intr_ack
(
host
);
dprintk
(
"wd7000_intr_handle: return from interrupt handler
\n
"
);
}
static
void
do_wd7000_intr_handle
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
static
void
do_wd7000_intr_handle
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
unsigned
long
flags
;
struct
Scsi_Host
*
host
=
dev_id
;
...
...
@@ -1145,7 +1115,7 @@ static void do_wd7000_intr_handle (int irq, void *dev_id, struct pt_regs *regs)
}
static
int
wd7000_queuecommand
(
Scsi_Cmnd
*
SCpnt
,
void
(
*
done
)
(
Scsi_Cmnd
*
))
static
int
wd7000_queuecommand
(
Scsi_Cmnd
*
SCpnt
,
void
(
*
done
)
(
Scsi_Cmnd
*
))
{
register
Scb
*
scb
;
register
Sgb
*
sgb
;
...
...
@@ -1160,7 +1130,7 @@ static int wd7000_queuecommand (Scsi_Cmnd *SCpnt, void (*done) (Scsi_Cmnd *))
SCpnt
->
SCp
.
phase
=
1
;
scb
=
alloc_scbs
(
SCpnt
->
host
,
1
);
scb
->
idlun
=
idlun
;
memcpy
(
scb
->
cdb
,
cdb
,
cdblen
);
memcpy
(
scb
->
cdb
,
cdb
,
cdblen
);
scb
->
direc
=
0x40
;
/* Disable direction check */
scb
->
SCpnt
=
SCpnt
;
/* so we can find stuff later */
...
...
@@ -1172,42 +1142,39 @@ static int wd7000_queuecommand (Scsi_Cmnd *SCpnt, void (*done) (Scsi_Cmnd *))
unsigned
i
;
if
(
SCpnt
->
host
->
sg_tablesize
==
SG_NONE
)
{
panic
(
"wd7000_queuecommand: scatter/gather not supported.
\n
"
);
panic
(
"wd7000_queuecommand: scatter/gather not supported.
\n
"
);
}
dprintk
(
"Using scatter/gather with %d elements.
\n
"
,
SCpnt
->
use_sg
);
dprintk
(
"Using scatter/gather with %d elements.
\n
"
,
SCpnt
->
use_sg
);
sgb
=
scb
->
sgb
;
scb
->
op
=
1
;
any2scsi
(
scb
->
dataptr
,
(
int
)
sgb
);
any2scsi
(
scb
->
maxlen
,
SCpnt
->
use_sg
*
sizeof
(
Sgb
));
any2scsi
(
scb
->
dataptr
,
(
int
)
sgb
);
any2scsi
(
scb
->
maxlen
,
SCpnt
->
use_sg
*
sizeof
(
Sgb
));
for
(
i
=
0
;
i
<
SCpnt
->
use_sg
;
i
++
)
{
any2scsi
(
sgb
[
i
].
ptr
,
isa_page_to_bus
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
);
any2scsi
(
sgb
[
i
].
len
,
sg
[
i
].
length
);
}
any2scsi
(
sgb
[
i
].
ptr
,
isa_page_to_bus
(
sg
[
i
].
page
)
+
sg
[
i
].
offset
);
any2scsi
(
sgb
[
i
].
len
,
sg
[
i
].
length
);
}
else
{
}
else
{
scb
->
op
=
0
;
any2scsi
(
scb
->
dataptr
,
isa_virt_to_bus
(
SCpnt
->
request_buffer
));
any2scsi
(
scb
->
maxlen
,
SCpnt
->
request_bufflen
);
any2scsi
(
scb
->
dataptr
,
isa_virt_to_bus
(
SCpnt
->
request_buffer
));
any2scsi
(
scb
->
maxlen
,
SCpnt
->
request_bufflen
);
}
/* FIXME: drop lock and yield here ? */
while
(
!
mail_out
(
host
,
scb
))
while
(
!
mail_out
(
host
,
scb
))
cpu_relax
();
/* keep trying */
return
0
;
}
static
int
wd7000_command
(
Scsi_Cmnd
*
SCpnt
)
static
int
wd7000_command
(
Scsi_Cmnd
*
SCpnt
)
{
wd7000_queuecommand
(
SCpnt
,
wd7000_scsi_done
);
wd7000_queuecommand
(
SCpnt
,
wd7000_scsi_done
);
while
(
SCpnt
->
SCp
.
phase
>
0
)
{
while
(
SCpnt
->
SCp
.
phase
>
0
)
{
cpu_relax
();
barrier
();
/* phase counts scbs down to 0 */
}
...
...
@@ -1216,36 +1183,34 @@ static int wd7000_command (Scsi_Cmnd *SCpnt)
}
static
int
wd7000_diagnostics
(
Adapter
*
host
,
int
code
)
static
int
wd7000_diagnostics
(
Adapter
*
host
,
int
code
)
{
static
IcbDiag
icb
=
{
ICB_OP_DIAGNOSTICS
};
static
IcbDiag
icb
=
{
ICB_OP_DIAGNOSTICS
};
static
unchar
buf
[
256
];
unsigned
long
timeout
;
icb
.
type
=
code
;
any2scsi
(
icb
.
len
,
sizeof
(
buf
));
any2scsi
(
icb
.
ptr
,
(
int
)
&
buf
);
any2scsi
(
icb
.
len
,
sizeof
(
buf
));
any2scsi
(
icb
.
ptr
,
(
int
)
&
buf
);
icb
.
phase
=
1
;
/*
* This routine is only called at init, so there should be OGMBs
* available. I'm assuming so here. If this is going to
* fail, I can just let the timeout catch the failure.
*/
mail_out
(
host
,
(
struct
scb
*
)
&
icb
);
mail_out
(
host
,
(
struct
scb
*
)
&
icb
);
timeout
=
jiffies
+
WAITnexttimeout
;
/* wait up to 2 seconds */
while
(
icb
.
phase
&&
time_before
(
jiffies
,
timeout
))
{
while
(
icb
.
phase
&&
time_before
(
jiffies
,
timeout
))
{
cpu_relax
();
/* wait for completion */
barrier
();
}
if
(
icb
.
phase
)
{
printk
(
"wd7000_diagnostics: timed out.
\n
"
);
printk
(
"wd7000_diagnostics: timed out.
\n
"
);
return
(
0
);
}
if
(
make_code
(
icb
.
vue
|
(
icb
.
status
<<
8
),
0
))
{
printk
(
"wd7000_diagnostics: failed (0x%02x,0x%02x)
\n
"
,
icb
.
vue
,
icb
.
status
);
if
(
make_code
(
icb
.
vue
|
(
icb
.
status
<<
8
),
0
))
{
printk
(
"wd7000_diagnostics: failed (0x%02x,0x%02x)
\n
"
,
icb
.
vue
,
icb
.
status
);
return
(
0
);
}
...
...
@@ -1253,16 +1218,15 @@ static int wd7000_diagnostics (Adapter *host, int code)
}
static
int
wd7000_adapter_reset
(
Adapter
*
host
)
static
int
wd7000_adapter_reset
(
Adapter
*
host
)
{
InitCmd
init_cmd
=
{
InitCmd
init_cmd
=
{
INITIALIZATION
,
7
,
host
->
bus_on
,
host
->
bus_off
,
0
,
{
0
,
0
,
0
},
{
0
,
0
,
0
},
OGMB_CNT
,
ICMB_CNT
};
...
...
@@ -1271,74 +1235,81 @@ static int wd7000_adapter_reset(Adapter *host)
* Reset the adapter - only. The SCSI bus was initialized at power-up,
* and we need to do this just so we control the mailboxes, etc.
*/
outb
(
ASC_RES
,
host
->
iobase
+
ASC_CONTROL
);
outb
(
ASC_RES
,
host
->
iobase
+
ASC_CONTROL
);
udelay
(
40
);
/* reset pulse: this is 40us, only need 25us */
outb
(
0
,
host
->
iobase
+
ASC_CONTROL
);
outb
(
0
,
host
->
iobase
+
ASC_CONTROL
);
host
->
control
=
0
;
/* this must always shadow ASC_CONTROL */
if
(
WAIT
(
host
->
iobase
+
ASC_STAT
,
ASC_STATMASK
,
CMD_RDY
,
0
))
{
printk
(
"wd7000_init: WAIT timed out.
\n
"
);
if
(
WAIT
(
host
->
iobase
+
ASC_STAT
,
ASC_STATMASK
,
CMD_RDY
,
0
))
{
printk
(
"wd7000_init: WAIT timed out.
\n
"
);
return
-
1
;
/* -1 = not ok */
}
if
((
diag
=
inb
(
host
->
iobase
+
ASC_INTR_STAT
))
!=
1
)
{
printk
(
"wd7000_init: "
);
if
((
diag
=
inb
(
host
->
iobase
+
ASC_INTR_STAT
))
!=
1
)
{
printk
(
"wd7000_init: "
);
switch
(
diag
)
{
case
2
:
printk
(
"RAM failure.
\n
"
);
case
2
:
printk
(
"RAM failure.
\n
"
);
break
;
case
3
:
printk
(
"FIFO R/W failed
\n
"
);
case
3
:
printk
(
"FIFO R/W failed
\n
"
);
break
;
case
4
:
printk
(
"SBIC register R/W failed
\n
"
);
case
4
:
printk
(
"SBIC register R/W failed
\n
"
);
break
;
case
5
:
printk
(
"Initialization D-FF failed.
\n
"
);
case
5
:
printk
(
"Initialization D-FF failed.
\n
"
);
break
;
case
6
:
printk
(
"Host IRQ D-FF failed.
\n
"
);
case
6
:
printk
(
"Host IRQ D-FF failed.
\n
"
);
break
;
case
7
:
printk
(
"ROM checksum error.
\n
"
);
case
7
:
printk
(
"ROM checksum error.
\n
"
);
break
;
default:
printk
(
"diagnostic code 0x%02Xh received.
\n
"
,
diag
);
default:
printk
(
"diagnostic code 0x%02Xh received.
\n
"
,
diag
);
}
return
-
1
;
}
/* Clear mailboxes */
memset
(
&
(
host
->
mb
),
0
,
sizeof
(
host
->
mb
));
memset
(
&
(
host
->
mb
),
0
,
sizeof
(
host
->
mb
));
/* Execute init command */
any2scsi
((
unchar
*
)
&
(
init_cmd
.
mailboxes
),
(
int
)
&
(
host
->
mb
));
if
(
!
command_out
(
host
,
(
unchar
*
)
&
init_cmd
,
sizeof
(
init_cmd
)))
{
printk
(
KERN_ERR
"wd7000_adapter_reset: adapter initialization failed.
\n
"
);
any2scsi
((
unchar
*
)
&
(
init_cmd
.
mailboxes
),
(
int
)
&
(
host
->
mb
));
if
(
!
command_out
(
host
,
(
unchar
*
)
&
init_cmd
,
sizeof
(
init_cmd
)))
{
printk
(
KERN_ERR
"wd7000_adapter_reset: adapter initialization failed.
\n
"
);
return
-
1
;
}
if
(
WAIT
(
host
->
iobase
+
ASC_STAT
,
ASC_STATMASK
,
ASC_INIT
,
0
))
{
printk
(
"wd7000_adapter_reset: WAIT timed out.
\n
"
);
if
(
WAIT
(
host
->
iobase
+
ASC_STAT
,
ASC_STATMASK
,
ASC_INIT
,
0
))
{
printk
(
"wd7000_adapter_reset: WAIT timed out.
\n
"
);
return
-
1
;
}
return
0
;
}
static
int
wd7000_init
(
Adapter
*
host
)
static
int
wd7000_init
(
Adapter
*
host
)
{
if
(
wd7000_adapter_reset
(
host
)
==
-
1
)
if
(
wd7000_adapter_reset
(
host
)
==
-
1
)
return
0
;
if
(
request_irq
(
host
->
irq
,
do_wd7000_intr_handle
,
SA_INTERRUPT
,
"wd7000"
,
host
))
{
printk
(
"wd7000_init: can't get IRQ %d.
\n
"
,
host
->
irq
);
if
(
request_irq
(
host
->
irq
,
do_wd7000_intr_handle
,
SA_INTERRUPT
,
"wd7000"
,
host
))
{
printk
(
"wd7000_init: can't get IRQ %d.
\n
"
,
host
->
irq
);
return
(
0
);
}
if
(
request_dma
(
host
->
dma
,
"wd7000"
))
{
printk
(
"wd7000_init: can't get DMA channel %d.
\n
"
,
host
->
dma
);
free_irq
(
host
->
irq
,
host
);
if
(
request_dma
(
host
->
dma
,
"wd7000"
))
{
printk
(
"wd7000_init: can't get DMA channel %d.
\n
"
,
host
->
dma
);
free_irq
(
host
->
irq
,
host
);
return
(
0
);
}
wd7000_enable_dma
(
host
);
wd7000_enable_intr
(
host
);
wd7000_enable_dma
(
host
);
wd7000_enable_intr
(
host
);
if
(
!
wd7000_diagnostics
(
host
,
ICB_DIAG_FULL
))
{
free_dma
(
host
->
dma
);
free_irq
(
host
->
irq
,
NULL
);
if
(
!
wd7000_diagnostics
(
host
,
ICB_DIAG_FULL
))
{
free_dma
(
host
->
dma
);
free_irq
(
host
->
irq
,
NULL
);
return
(
0
);
}
...
...
@@ -1346,10 +1317,9 @@ static int wd7000_init (Adapter *host)
}
static
void
wd7000_revision
(
Adapter
*
host
)
static
void
wd7000_revision
(
Adapter
*
host
)
{
static
IcbRevLvl
icb
=
{
ICB_OP_GET_REVISION
};
static
IcbRevLvl
icb
=
{
ICB_OP_GET_REVISION
};
icb
.
phase
=
1
;
/*
...
...
@@ -1358,9 +1328,8 @@ static void wd7000_revision (Adapter *host)
* the only damage will be that the revision will show up as 0.0,
* which in turn means that scatter/gather will be disabled.
*/
mail_out
(
host
,
(
struct
scb
*
)
&
icb
);
while
(
icb
.
phase
)
{
mail_out
(
host
,
(
struct
scb
*
)
&
icb
);
while
(
icb
.
phase
)
{
cpu_relax
();
/* wait for completion */
barrier
();
}
...
...
@@ -1372,7 +1341,7 @@ static void wd7000_revision (Adapter *host)
#undef SPRINTF
#define SPRINTF(args...) { if (pos < (buffer + length)) pos += sprintf (pos, ## args); }
static
int
wd7000_set_info
(
char
*
buffer
,
int
length
,
struct
Scsi_Host
*
host
)
static
int
wd7000_set_info
(
char
*
buffer
,
int
length
,
struct
Scsi_Host
*
host
)
{
dprintk
(
"Buffer = <%.*s>, length = %d
\n
"
,
length
,
buffer
,
length
);
...
...
@@ -1384,7 +1353,7 @@ 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_proc_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
,
int
hostno
,
int
inout
)
{
struct
Scsi_Host
*
host
=
NULL
;
Scsi_Device
*
scd
;
...
...
@@ -1411,55 +1380,55 @@ static int wd7000_proc_info (char *buffer, char **start, off_t offset, int lengt
/*
* Host not found!
*/
if
(
!
host
)
if
(
!
host
)
return
(
-
ESRCH
);
/*
* Has data been written to the file ?
*/
if
(
inout
)
return
(
wd7000_set_info
(
buffer
,
length
,
host
));
return
(
wd7000_set_info
(
buffer
,
length
,
host
));
adapter
=
(
Adapter
*
)
host
->
hostdata
;
spin_lock_irqsave
(
host
->
host_lock
,
flags
);
SPRINTF
(
"Host scsi%d: Western Digital WD-7000 (rev %d.%d)
\n
"
,
hostno
,
adapter
->
rev1
,
adapter
->
rev2
);
SPRINTF
(
" IO base: 0x%x
\n
"
,
adapter
->
iobase
);
SPRINTF
(
" IRQ: %d
\n
"
,
adapter
->
irq
);
SPRINTF
(
" DMA channel: %d
\n
"
,
adapter
->
dma
);
SPRINTF
(
" Interrupts: %d
\n
"
,
adapter
->
int_counter
);
SPRINTF
(
" BUS_ON time: %d nanoseconds
\n
"
,
adapter
->
bus_on
*
125
);
SPRINTF
(
" BUS_OFF time: %d nanoseconds
\n
"
,
adapter
->
bus_off
*
125
);
SPRINTF
(
"Host scsi%d: Western Digital WD-7000 (rev %d.%d)
\n
"
,
hostno
,
adapter
->
rev1
,
adapter
->
rev2
);
SPRINTF
(
" IO base: 0x%x
\n
"
,
adapter
->
iobase
);
SPRINTF
(
" IRQ: %d
\n
"
,
adapter
->
irq
);
SPRINTF
(
" DMA channel: %d
\n
"
,
adapter
->
dma
);
SPRINTF
(
" Interrupts: %d
\n
"
,
adapter
->
int_counter
);
SPRINTF
(
" BUS_ON time: %d nanoseconds
\n
"
,
adapter
->
bus_on
*
125
);
SPRINTF
(
" BUS_OFF time: %d nanoseconds
\n
"
,
adapter
->
bus_off
*
125
);
#ifdef WD7000_DEBUG
ogmbs
=
adapter
->
mb
.
ogmb
;
icmbs
=
adapter
->
mb
.
icmb
;
SPRINTF
(
"
\n
Control port value: 0x%x
\n
"
,
adapter
->
control
);
SPRINTF
(
"Incoming mailbox:
\n
"
);
SPRINTF
(
" size: %d
\n
"
,
ICMB_CNT
);
SPRINTF
(
" queued messages: "
);
SPRINTF
(
"
\n
Control port value: 0x%x
\n
"
,
adapter
->
control
);
SPRINTF
(
"Incoming mailbox:
\n
"
);
SPRINTF
(
" size: %d
\n
"
,
ICMB_CNT
);
SPRINTF
(
" queued messages: "
);
for
(
i
=
count
=
0
;
i
<
ICMB_CNT
;
i
++
)
if
(
icmbs
[
i
].
status
)
{
count
++
;
SPRINTF
(
"0x%x "
,
i
);
SPRINTF
(
"0x%x "
,
i
);
}
SPRINTF
(
count
?
"
\n
"
:
"none
\n
"
);
SPRINTF
(
count
?
"
\n
"
:
"none
\n
"
);
SPRINTF
(
"Outgoing mailbox:
\n
"
);
SPRINTF
(
" size: %d
\n
"
,
OGMB_CNT
);
SPRINTF
(
" next message: 0x%x
\n
"
,
adapter
->
next_ogmb
);
SPRINTF
(
" queued messages: "
);
SPRINTF
(
"Outgoing mailbox:
\n
"
);
SPRINTF
(
" size: %d
\n
"
,
OGMB_CNT
);
SPRINTF
(
" next message: 0x%x
\n
"
,
adapter
->
next_ogmb
);
SPRINTF
(
" queued messages: "
);
for
(
i
=
count
=
0
;
i
<
OGMB_CNT
;
i
++
)
if
(
ogmbs
[
i
].
status
)
{
count
++
;
SPRINTF
(
"0x%x "
,
i
);
SPRINTF
(
"0x%x "
,
i
);
}
SPRINTF
(
count
?
"
\n
"
:
"none
\n
"
);
SPRINTF
(
count
?
"
\n
"
:
"none
\n
"
);
#endif
/*
...
...
@@ -1467,25 +1436,23 @@ static int wd7000_proc_info (char *buffer, char **start, off_t offset, int lengt
*/
scd
=
host
->
host_queue
;
SPRINTF
(
"
\n
Attached devices: %s
\n
"
,
scd
?
""
:
"none"
);
SPRINTF
(
"
\n
Attached devices: %s
\n
"
,
scd
?
""
:
"none"
);
for
(
;
scd
;
scd
=
scd
->
next
)
for
(
;
scd
;
scd
=
scd
->
next
)
if
(
scd
->
host
->
host_no
==
hostno
)
{
SPRINTF
(
" [Channel: %02d, Id: %02d, Lun: %02d] "
,
scd
->
channel
,
scd
->
id
,
scd
->
lun
);
SPRINTF
(
"%s "
,
(
scd
->
type
<
MAX_SCSI_DEVICE_CODE
)
?
scsi_device_types
[(
short
)
scd
->
type
]
:
"Unknown device"
);
SPRINTF
(
" [Channel: %02d, Id: %02d, Lun: %02d] "
,
scd
->
channel
,
scd
->
id
,
scd
->
lun
);
SPRINTF
(
"%s "
,
(
scd
->
type
<
MAX_SCSI_DEVICE_CODE
)
?
scsi_device_types
[(
short
)
scd
->
type
]
:
"Unknown device"
);
for
(
i
=
0
;
(
i
<
8
)
&&
(
scd
->
vendor
[
i
]
>=
0x20
);
i
++
)
SPRINTF
(
"%c"
,
scd
->
vendor
[
i
]);
SPRINTF
(
" "
);
SPRINTF
(
"%c"
,
scd
->
vendor
[
i
]);
SPRINTF
(
" "
);
for
(
i
=
0
;
(
i
<
16
)
&&
(
scd
->
model
[
i
]
>=
0x20
);
i
++
)
SPRINTF
(
"%c"
,
scd
->
model
[
i
]);
SPRINTF
(
"
\n
"
);
SPRINTF
(
"%c"
,
scd
->
model
[
i
]);
SPRINTF
(
"
\n
"
);
}
SPRINTF
(
"
\n
"
);
SPRINTF
(
"
\n
"
);
spin_unlock_irqrestore
(
host
->
host_lock
,
flags
);
...
...
@@ -1514,7 +1481,7 @@ static int wd7000_proc_info (char *buffer, char **start, off_t offset, int lengt
*
*/
static
int
wd7000_detect
(
Scsi_Host_Template
*
tpnt
)
static
int
wd7000_detect
(
Scsi_Host_Template
*
tpnt
)
{
short
present
=
0
,
biosaddr_ptr
,
sig_ptr
,
i
,
pass
;
short
biosptr
[
NUM_CONFIGS
];
...
...
@@ -1530,8 +1497,8 @@ static int wd7000_detect (Scsi_Host_Template *tpnt)
wd7000_setup
(
wd7000
);
#endif
for
(
i
=
0
;
i
<
UNITS
;
wd7000_host
[
i
++
]
=
NULL
)
;
for
(
i
=
0
;
i
<
NUM_CONFIGS
;
biosptr
[
i
++
]
=
-
1
)
;
for
(
i
=
0
;
i
<
UNITS
;
wd7000_host
[
i
++
]
=
NULL
)
;
for
(
i
=
0
;
i
<
NUM_CONFIGS
;
biosptr
[
i
++
]
=
-
1
)
;
tpnt
->
proc_name
=
"wd7000"
;
tpnt
->
proc_info
=
&
wd7000_proc_info
;
...
...
@@ -1539,7 +1506,7 @@ static int wd7000_detect (Scsi_Host_Template *tpnt)
/*
* Set up SCB free list, which is shared by all adapters
*/
init_scbs
();
init_scbs
();
for
(
pass
=
0
;
pass
<
NUM_CONFIGS
;
pass
++
)
{
/*
...
...
@@ -1552,18 +1519,16 @@ static int wd7000_detect (Scsi_Host_Template *tpnt)
break
;
if
(
i
==
pass
)
{
void
*
biosaddr
=
ioremap
(
wd7000_biosaddr
[
biosaddr_ptr
]
+
signatures
[
sig_ptr
].
ofs
,
void
*
biosaddr
=
ioremap
(
wd7000_biosaddr
[
biosaddr_ptr
]
+
signatures
[
sig_ptr
].
ofs
,
signatures
[
sig_ptr
].
len
);
short
bios_match
=
0
;
short
bios_match
=
0
;
if
(
biosaddr
)
bios_match
=
memcmp
((
char
*
)
biosaddr
,
signatures
[
sig_ptr
].
sig
,
signatures
[
sig_ptr
].
len
);
if
(
biosaddr
)
bios_match
=
memcmp
((
char
*
)
biosaddr
,
signatures
[
sig_ptr
].
sig
,
signatures
[
sig_ptr
].
len
);
iounmap
(
biosaddr
);
iounmap
(
biosaddr
);
if
(
!
bios_match
)
if
(
!
bios_match
)
goto
bios_matched
;
}
}
...
...
@@ -1578,8 +1543,7 @@ static int wd7000_detect (Scsi_Host_Template *tpnt)
if
(
biosaddr_ptr
==
NUM_ADDRS
)
dprintk
(
"WD-7000 SST BIOS not detected...
\n
"
);
else
dprintk
(
"WD-7000 SST BIOS detected at 0x%lx: checking...
\n
"
,
wd7000_biosaddr
[
biosaddr_ptr
]);
dprintk
(
"WD-7000 SST BIOS detected at 0x%lx: checking...
\n
"
,
wd7000_biosaddr
[
biosaddr_ptr
]);
#endif
if
(
configs
[
pass
].
irq
<
0
)
...
...
@@ -1592,24 +1556,24 @@ static int wd7000_detect (Scsi_Host_Template *tpnt)
dprintk
(
"wd7000_detect: check IO 0x%x region...
\n
"
,
iobase
);
if
(
request_region
(
iobase
,
4
,
"wd7000"
))
{
if
(
request_region
(
iobase
,
4
,
"wd7000"
))
{
dprintk
(
"wd7000_detect: ASC reset (IO 0x%x) ..."
,
iobase
);
/*
* ASC reset...
*/
outb
(
ASC_RES
,
iobase
+
ASC_CONTROL
);
outb
(
ASC_RES
,
iobase
+
ASC_CONTROL
);
set_current_state
(
TASK_UNINTERRUPTIBLE
);
schedule_timeout
(
HZ
/
100
);
outb
(
0
,
iobase
+
ASC_CONTROL
);
schedule_timeout
(
HZ
/
100
);
outb
(
0
,
iobase
+
ASC_CONTROL
);
if
(
WAIT
(
iobase
+
ASC_STAT
,
ASC_STATMASK
,
CMD_RDY
,
0
))
{
if
(
WAIT
(
iobase
+
ASC_STAT
,
ASC_STATMASK
,
CMD_RDY
,
0
))
{
dprintk
(
"failed!
\n
"
);
goto
err_release
;
}
else
dprintk
(
"ok!
\n
"
);
if
(
inb
(
iobase
+
ASC_INTR_STAT
)
==
1
)
{
if
(
inb
(
iobase
+
ASC_INTR_STAT
)
==
1
)
{
/*
* We register here, to get a pointer to the extra space,
* which we'll use as the Adapter structure (host) for
...
...
@@ -1617,15 +1581,14 @@ static int wd7000_detect (Scsi_Host_Template *tpnt)
* Scsi_Host structure (sh), and is located by the empty
* array hostdata.
*/
sh
=
scsi_register
(
tpnt
,
sizeof
(
Adapter
));
if
(
sh
==
NULL
)
sh
=
scsi_register
(
tpnt
,
sizeof
(
Adapter
));
if
(
sh
==
NULL
)
goto
err_release
;
host
=
(
Adapter
*
)
sh
->
hostdata
;
dprintk
(
"wd7000_detect: adapter allocated at 0x%x
\n
"
,
(
int
)
host
);
memset
(
host
,
0
,
sizeof
(
Adapter
));
dprintk
(
"wd7000_detect: adapter allocated at 0x%x
\n
"
,
(
int
)
host
);
memset
(
host
,
0
,
sizeof
(
Adapter
));
host
->
irq
=
configs
[
pass
].
irq
;
host
->
dma
=
configs
[
pass
].
dma
;
...
...
@@ -1636,17 +1599,15 @@ static int wd7000_detect (Scsi_Host_Template *tpnt)
host
->
sh
=
wd7000_host
[
unit
]
=
sh
;
unit
++
;
dprintk
(
"wd7000_detect: Trying init WD-7000 card at IO "
"0x%x, IRQ %d, DMA %d...
\n
"
,
host
->
iobase
,
host
->
irq
,
host
->
dma
);
dprintk
(
"wd7000_detect: Trying init WD-7000 card at IO "
"0x%x, IRQ %d, DMA %d...
\n
"
,
host
->
iobase
,
host
->
irq
,
host
->
dma
);
if
(
!
wd7000_init
(
host
))
/* Initialization failed */
if
(
!
wd7000_init
(
host
))
/* Initialization failed */
goto
err_unregister
;
/*
* OK from here - we'll use this adapter/configuration.
*/
wd7000_revision
(
host
);
/* important for scatter/gather */
wd7000_revision
(
host
);
/* important for scatter/gather */
/*
* For boards before rev 6.0, scatter/gather isn't supported.
...
...
@@ -1659,28 +1620,24 @@ static int wd7000_detect (Scsi_Host_Template *tpnt)
if
(
biosaddr_ptr
!=
NUM_ADDRS
)
biosptr
[
pass
]
=
biosaddr_ptr
;
printk
(
KERN_INFO
"Western Digital WD-7000 (rev %d.%d) "
,
host
->
rev1
,
host
->
rev2
);
printk
(
"using IO 0x%x, IRQ %d, DMA %d.
\n
"
,
host
->
iobase
,
host
->
irq
,
host
->
dma
);
printk
(
" BUS_ON time: %dns, BUS_OFF time: %dns
\n
"
,
host
->
bus_on
*
125
,
host
->
bus_off
*
125
);
printk
(
KERN_INFO
"Western Digital WD-7000 (rev %d.%d) "
,
host
->
rev1
,
host
->
rev2
);
printk
(
"using IO 0x%x, IRQ %d, DMA %d.
\n
"
,
host
->
iobase
,
host
->
irq
,
host
->
dma
);
printk
(
" BUS_ON time: %dns, BUS_OFF time: %dns
\n
"
,
host
->
bus_on
*
125
,
host
->
bus_off
*
125
);
}
}
else
dprintk
(
"wd7000_detect: IO 0x%x region already allocated!
\n
"
,
iobase
);
dprintk
(
"wd7000_detect: IO 0x%x region already allocated!
\n
"
,
iobase
);
continue
;
err_unregister:
scsi_unregister
(
sh
);
scsi_unregister
(
sh
);
err_release:
release_region
(
iobase
,
4
);
}
if
(
!
present
)
printk
(
"Failed initialization of WD-7000 SCSI card!
\n
"
);
printk
(
"Failed initialization of WD-7000 SCSI card!
\n
"
);
return
(
present
);
}
...
...
@@ -1689,13 +1646,13 @@ static int wd7000_detect (Scsi_Host_Template *tpnt)
/*
* I have absolutely NO idea how to do an abort with the WD7000...
*/
static
int
wd7000_abort
(
Scsi_Cmnd
*
SCpnt
)
static
int
wd7000_abort
(
Scsi_Cmnd
*
SCpnt
)
{
Adapter
*
host
=
(
Adapter
*
)
SCpnt
->
host
->
hostdata
;
if
(
inb
(
host
->
iobase
+
ASC_STAT
)
&
INT_IM
)
{
printk
(
"wd7000_abort: lost interrupt
\n
"
);
wd7000_intr_handle
(
host
->
irq
,
NULL
,
NULL
);
if
(
inb
(
host
->
iobase
+
ASC_STAT
)
&
INT_IM
)
{
printk
(
"wd7000_abort: lost interrupt
\n
"
);
wd7000_intr_handle
(
host
->
irq
,
NULL
,
NULL
);
return
FAILED
;
}
return
FAILED
;
...
...
@@ -1706,12 +1663,12 @@ static int wd7000_abort (Scsi_Cmnd *SCpnt)
* I also have no idea how to do a reset...
*/
static
int
wd7000_bus_reset
(
Scsi_Cmnd
*
SCpnt
)
static
int
wd7000_bus_reset
(
Scsi_Cmnd
*
SCpnt
)
{
return
FAILED
;
}
static
int
wd7000_device_reset
(
Scsi_Cmnd
*
SCpnt
)
static
int
wd7000_device_reset
(
Scsi_Cmnd
*
SCpnt
)
{
return
FAILED
;
}
...
...
@@ -1720,13 +1677,13 @@ static int wd7000_device_reset (Scsi_Cmnd *SCpnt)
* Last resort. Reinitialize the board.
*/
static
int
wd7000_host_reset
(
Scsi_Cmnd
*
SCpnt
)
static
int
wd7000_host_reset
(
Scsi_Cmnd
*
SCpnt
)
{
Adapter
*
host
=
(
Adapter
*
)
SCpnt
->
host
->
hostdata
;
if
(
wd7000_adapter_reset
(
host
)
<
0
)
if
(
wd7000_adapter_reset
(
host
)
<
0
)
return
FAILED
;
wd7000_enable_intr
(
host
);
wd7000_enable_intr
(
host
);
return
SUCCESS
;
}
...
...
@@ -1735,10 +1692,9 @@ static int wd7000_host_reset (Scsi_Cmnd *SCpnt)
* This was borrowed directly from aha1542.c. (Zaga)
*/
static
int
wd7000_biosparam
(
Disk
*
disk
,
struct
block_device
*
bdev
,
int
*
ip
)
static
int
wd7000_biosparam
(
Disk
*
disk
,
struct
block_device
*
bdev
,
int
*
ip
)
{
dprintk
(
"wd7000_biosparam: dev=%s, size=%d, "
,
bdevname
(
bdev
),
disk
->
capacity
);
dprintk
(
"wd7000_biosparam: dev=%s, size=%d, "
,
bdevname
(
bdev
),
disk
->
capacity
);
/*
* try default translation
...
...
@@ -1756,24 +1712,19 @@ static int wd7000_biosparam (Disk *disk, struct block_device *bdev, int *ip)
/*
* try to figure out the geometry from the partition table
*/
if
((
scsicam_bios_param
(
disk
,
bdev
,
info
)
<
0
)
||
!
(((
info
[
0
]
==
64
)
&&
(
info
[
1
]
==
32
))
||
((
info
[
0
]
==
255
)
&&
(
info
[
1
]
==
63
))))
{
printk
(
"wd7000_biosparam: unable to verify geometry for disk with >1GB.
\n
"
" using extended translation.
\n
"
);
if
((
scsicam_bios_param
(
disk
,
bdev
,
info
)
<
0
)
||
!
(((
info
[
0
]
==
64
)
&&
(
info
[
1
]
==
32
))
||
((
info
[
0
]
==
255
)
&&
(
info
[
1
]
==
63
))))
{
printk
(
"wd7000_biosparam: unable to verify geometry for disk with >1GB.
\n
"
" using extended translation.
\n
"
);
ip
[
0
]
=
255
;
ip
[
1
]
=
63
;
ip
[
2
]
=
(
unsigned
long
)
disk
->
capacity
/
(
255
*
63
);
}
else
{
ip
[
2
]
=
(
unsigned
long
)
disk
->
capacity
/
(
255
*
63
);
}
else
{
ip
[
0
]
=
info
[
0
];
ip
[
1
]
=
info
[
1
];
ip
[
2
]
=
info
[
2
];
if
(
info
[
0
]
==
255
)
printk
(
KERN_INFO
"%s: current partition table is "
"using extended translation.
\n
"
,
__FUNCTION__
);
printk
(
KERN_INFO
"%s: current partition table is "
"using extended translation.
\n
"
,
__FUNCTION__
);
}
}
...
...
drivers/scsi/wd7000.h
View file @
cd509844
...
...
@@ -13,16 +13,16 @@
#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
(
Disk
*
,
struct
block_device
*
,
int
*
);
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
(
Disk
*
,
struct
block_device
*
,
int
*
);
#ifndef NULL
#define NULL 0L
...
...
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