Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
e34b1b85
Commit
e34b1b85
authored
Feb 26, 2003
by
Dave Jones
Committed by
James Bottomley
Feb 26, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] Put sgiwd93.c back in sync with 2.4
parent
c2351f2a
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
32 additions
and
112 deletions
+32
-112
drivers/scsi/sgiwd93.c
drivers/scsi/sgiwd93.c
+32
-112
No files found.
drivers/scsi/sgiwd93.c
View file @
e34b1b85
...
...
@@ -4,10 +4,13 @@
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
* 1999 Andrew R. Baker (andrewb@uab.edu)
* - Support for 2nd SCSI controller on Indigo2
* 2001 Florian Lohoff (flo@rfc822.org)
* - Delete HPC scatter gather (Read corruption on
* multiple disks)
* - Cleanup wback cache handling
*
* (In all truth, Jed Schimmel wrote all this code.)
*
* $Id: sgiwd93.c,v 1.19 2000/02/04 07:40:47 ralf Exp $
*/
#include <linux/init.h>
#include <linux/types.h>
...
...
@@ -36,32 +39,13 @@
struct
hpc_chunk
{
struct
hpc_dma_desc
desc
;
u
nsigned
long
padding
;
u
32
_padding
;
/* align to quadword boundary */
};
struct
Scsi_Host
*
sgiwd93_host
=
NULL
;
struct
Scsi_Host
*
sgiwd93_host1
=
NULL
;
/* Wuff wuff, wuff, wd33c93.c, wuff wuff, object oriented, bow wow. */
static
inline
void
write_wd33c93_count
(
const
wd33c93_regs
regs
,
unsigned
long
value
)
{
*
regs
.
SASR
=
WD_TRANSFER_COUNT_MSB
;
*
regs
.
SCMD
=
((
value
>>
16
)
&
0xff
);
*
regs
.
SCMD
=
((
value
>>
8
)
&
0xff
);
*
regs
.
SCMD
=
((
value
>>
0
)
&
0xff
);
}
static
inline
unsigned
long
read_wd33c93_count
(
const
wd33c93_regs
regs
)
{
unsigned
long
value
;
*
regs
.
SASR
=
WD_TRANSFER_COUNT_MSB
;
value
=
(
*
regs
.
SCMD
<<
16
);
value
|=
(
*
regs
.
SCMD
<<
8
);
value
|=
(
*
regs
.
SCMD
<<
0
);
return
value
;
}
/* XXX woof! */
static
void
sgiwd93_intr
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
...
...
@@ -82,7 +66,6 @@ void fill_hpc_entries (struct hpc_chunk **hcp, char *addr, unsigned long len)
unsigned
long
physaddr
;
unsigned
long
count
;
dma_cache_wback_inv
((
unsigned
long
)
addr
,
len
);
physaddr
=
PHYSADDR
(
addr
);
while
(
len
)
{
/*
...
...
@@ -101,7 +84,6 @@ void fill_hpc_entries (struct hpc_chunk **hcp, char *addr, unsigned long len)
static
int
dma_setup
(
Scsi_Cmnd
*
cmd
,
int
datainp
)
{
struct
WD33C93_hostdata
*
hdata
=
(
struct
WD33C93_hostdata
*
)
cmd
->
host
->
hostdata
;
const
wd33c93_regs
regs
=
hdata
->
regs
;
struct
hpc3_scsiregs
*
hregs
=
(
struct
hpc3_scsiregs
*
)
cmd
->
host
->
base
;
struct
hpc_chunk
*
hcp
=
(
struct
hpc_chunk
*
)
hdata
->
dma_bounce_buffer
;
...
...
@@ -112,46 +94,17 @@ static int dma_setup(Scsi_Cmnd *cmd, int datainp)
hdata
->
dma_dir
=
datainp
;
if
(
cmd
->
SCp
.
buffers_residual
)
{
struct
scatterlist
*
slp
=
cmd
->
SCp
.
buffer
;
int
i
,
totlen
=
0
;
/*
* wd33c93 shouldn't pass us bogus dma_setups, but
* it does:-( The other wd33c93 drivers deal with
* it the same way (which isn't that obvious).
* IMHO a better fix would be, not to do these
* dma setups in the first place
*/
if
(
cmd
->
SCp
.
ptr
==
NULL
)
return
1
;
#ifdef DEBUG_DMA
printk
(
"SCLIST<"
);
#endif
for
(
i
=
0
;
i
<=
cmd
->
SCp
.
buffers_residual
;
i
++
)
{
#ifdef DEBUG_DMA
printk
(
"[%p,%d]"
,
page_address
(
slp
[
i
].
page
)
+
slp
[
i
].
offset
,
slp
[
i
].
length
);
#endif
fill_hpc_entries
(
&
hcp
,
page_address
(
slp
[
i
].
page
)
+
slp
[
i
].
offset
,
slp
[
i
].
length
);
totlen
+=
slp
[
i
].
length
;
}
#ifdef DEBUG_DMA
printk
(
">tlen<%d>"
,
totlen
);
#endif
hdata
->
dma_bounce_len
=
totlen
;
/* a trick... */
write_wd33c93_count
(
regs
,
totlen
);
}
else
{
/* Non-scattered dma. */
#ifdef DEBUG_DMA
printk
(
"ONEBUF<%p,%d>"
,
cmd
->
SCp
.
ptr
,
cmd
->
SCp
.
this_residual
);
#endif
/*
* wd33c93 shouldn't pass us bogus dma_setups, but
* it does:-( The other wd33c93 drivers deal with
* it the same way (which isn't that obvious).
* IMHO a better fix would be, not to do these
* dma setups in the first place
*/
if
(
cmd
->
SCp
.
ptr
==
NULL
)
return
1
;
fill_hpc_entries
(
&
hcp
,
cmd
->
SCp
.
ptr
,
cmd
->
SCp
.
this_residual
);
write_wd33c93_count
(
regs
,
cmd
->
SCp
.
this_residual
);
}
fill_hpc_entries
(
&
hcp
,
cmd
->
SCp
.
ptr
,
cmd
->
SCp
.
this_residual
);
/* To make sure, if we trip an HPC bug, that we transfer
* every single byte, we tag on an extra zero length dma
...
...
@@ -166,10 +119,14 @@ static int dma_setup(Scsi_Cmnd *cmd, int datainp)
/* Start up the HPC. */
hregs
->
ndptr
=
PHYSADDR
(
hdata
->
dma_bounce_buffer
);
if
(
datainp
)
if
(
datainp
)
{
dma_cache_inv
((
unsigned
long
)
cmd
->
SCp
.
ptr
,
cmd
->
SCp
.
this_residual
);
hregs
->
ctrl
=
(
HPC3_SCTRL_ACTIVE
);
else
}
else
{
dma_cache_wback_inv
((
unsigned
long
)
cmd
->
SCp
.
ptr
,
cmd
->
SCp
.
this_residual
);
hregs
->
ctrl
=
(
HPC3_SCTRL_ACTIVE
|
HPC3_SCTRL_DIR
);
}
return
0
;
}
...
...
@@ -177,7 +134,6 @@ static void dma_stop(struct Scsi_Host *instance, Scsi_Cmnd *SCpnt,
int
status
)
{
struct
WD33C93_hostdata
*
hdata
=
(
struct
WD33C93_hostdata
*
)
instance
->
hostdata
;
const
wd33c93_regs
regs
=
hdata
->
regs
;
struct
hpc3_scsiregs
*
hregs
;
if
(
!
SCpnt
)
...
...
@@ -197,44 +153,6 @@ static void dma_stop(struct Scsi_Host *instance, Scsi_Cmnd *SCpnt,
}
hregs
->
ctrl
=
0
;
/* See how far we got and update scatterlist state if necessary. */
if
(
SCpnt
->
SCp
.
buffers_residual
)
{
struct
scatterlist
*
slp
=
SCpnt
->
SCp
.
buffer
;
int
totlen
,
wd93_residual
,
transferred
,
i
;
/* Yep, we were doing the scatterlist thang. */
totlen
=
hdata
->
dma_bounce_len
;
wd93_residual
=
read_wd33c93_count
(
regs
);
transferred
=
totlen
-
wd93_residual
;
#ifdef DEBUG_DMA
printk
(
"tlen<%d>resid<%d>transf<%d> "
,
totlen
,
wd93_residual
,
transferred
);
#endif
/* Avoid long winded partial-transfer search for common case. */
if
(
transferred
!=
totlen
)
{
/* This is the nut case. */
#ifdef DEBUG_DMA
printk
(
"Jed was here..."
);
#endif
for
(
i
=
0
;
i
<=
SCpnt
->
SCp
.
buffers_residual
;
i
++
)
{
if
(
slp
[
i
].
length
>=
transferred
)
break
;
transferred
-=
slp
[
i
].
length
;
}
}
else
{
/* This is the common case. */
#ifdef DEBUG_DMA
printk
(
"did it all..."
);
#endif
i
=
SCpnt
->
SCp
.
buffers_residual
;
}
SCpnt
->
SCp
.
buffer
=
&
slp
[
i
];
SCpnt
->
SCp
.
buffers_residual
=
SCpnt
->
SCp
.
buffers_residual
-
i
;
SCpnt
->
SCp
.
ptr
=
(
char
*
)
page_address
(
slp
[
i
].
page
)
+
slp
[
i
].
offset
;
SCpnt
->
SCp
.
this_residual
=
slp
[
i
].
length
;
}
#ifdef DEBUG_DMA
printk
(
"
\n
"
);
#endif
...
...
@@ -264,6 +182,9 @@ static inline void init_hpc_chain(uchar *buf)
};
hcp
--
;
hcp
->
desc
.
pnext
=
PHYSADDR
(
buf
);
/* Force flush to memory */
dma_cache_wback_inv
((
unsigned
long
)
buf
,
PAGE_SIZE
);
}
int
__init
sgiwd93_detect
(
Scsi_Host_Template
*
SGIblows
)
...
...
@@ -273,8 +194,8 @@ int __init sgiwd93_detect(Scsi_Host_Template *SGIblows)
struct
hpc3_scsiregs
*
hregs1
=
&
hpc3c0
->
scsi_chan1
;
struct
WD33C93_hostdata
*
hdata
;
struct
WD33C93_hostdata
*
hdata1
;
uchar
*
buf
;
wd33c93_regs
regs
;
uchar
*
buf
;
if
(
called
)
return
0
;
/* Should bitch on the console about this... */
...
...
@@ -294,10 +215,10 @@ int __init sgiwd93_detect(Scsi_Host_Template *SGIblows)
return
0
;
}
init_hpc_chain
(
buf
);
dma_cache_wback_inv
((
unsigned
long
)
buf
,
PAGE_SIZE
);
/* HPC_SCSI_REG0 | 0x03 | KSEG1 */
regs
.
SASR
=
(
volatile
unsigned
char
*
)
KSEG1ADDR
(
0x1fbc0003
);
regs
.
SCMD
=
(
volatile
unsigned
char
*
)
KSEG1ADDR
(
0x1fbc0007
);
regs
.
SASR
=
(
unsigned
char
*
)
KSEG1ADDR
(
0x1fbc0003
);
regs
.
SCMD
=
(
unsigned
char
*
)
KSEG1ADDR
(
0x1fbc0007
);
wd33c93_init
(
sgiwd93_host
,
regs
,
dma_setup
,
dma_stop
,
WD33C93_FS_16_20
);
hdata
=
(
struct
WD33C93_hostdata
*
)
sgiwd93_host
->
hostdata
;
...
...
@@ -329,17 +250,16 @@ int __init sgiwd93_detect(Scsi_Host_Template *SGIblows)
return
1
;
/* We registered host0 so return success*/
}
init_hpc_chain
(
buf
);
dma_cache_wback_inv
((
unsigned
long
)
buf
,
PAGE_SIZE
);
/* HPC_SCSI_REG1 | 0x03 | KSEG1 */
regs
.
SASR
=
(
volatile
unsigned
char
*
)
KSEG1ADDR
(
0x1fbc8003
);
regs
.
SCMD
=
(
volatile
unsigned
char
*
)
KSEG1ADDR
(
0x1fbc8007
);
regs
.
SASR
=
(
unsigned
char
*
)
KSEG1ADDR
(
0x1fbc8003
);
regs
.
SCMD
=
(
unsigned
char
*
)
KSEG1ADDR
(
0x1fbc8007
);
wd33c93_init
(
sgiwd93_host1
,
regs
,
dma_setup
,
dma_stop
,
WD33C93_FS_16_20
);
WD33C93_FS_16_20
);
hdata1
=
(
struct
WD33C93_hostdata
*
)
sgiwd93_host1
->
hostdata
;
hdata1
->
no_sync
=
0
;
hdata1
->
dma_bounce_buffer
=
(
uchar
*
)
(
KSEG1ADDR
(
buf
));
dma_cache_wback_inv
((
unsigned
long
)
buf
,
PAGE_SIZE
);
if
(
request_irq
(
SGI_WD93_1_IRQ
,
sgiwd93_intr
,
0
,
"SGI WD93"
,
(
void
*
)
sgiwd93_host1
))
{
printk
(
KERN_WARNING
"sgiwd93: Could not allocate irq %d (for host1).
\n
"
,
SGI_WD93_1_IRQ
);
...
...
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