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
8e9c238c
Commit
8e9c238c
authored
Jan 09, 2006
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge master.kernel.org:/home/rmk/linux-2.6-mmc
parents
f17578de
7225b3fd
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
282 additions
and
266 deletions
+282
-266
drivers/mmc/mmc.c
drivers/mmc/mmc.c
+1
-0
drivers/mmc/mmc_block.c
drivers/mmc/mmc_block.c
+7
-1
drivers/mmc/wbsd.c
drivers/mmc/wbsd.c
+270
-263
include/linux/mmc/mmc.h
include/linux/mmc/mmc.h
+4
-2
No files found.
drivers/mmc/mmc.c
View file @
8e9c238c
...
@@ -495,6 +495,7 @@ static void mmc_decode_cid(struct mmc_card *card)
...
@@ -495,6 +495,7 @@ static void mmc_decode_cid(struct mmc_card *card)
case
2
:
/* MMC v2.0 - v2.2 */
case
2
:
/* MMC v2.0 - v2.2 */
case
3
:
/* MMC v3.1 - v3.3 */
case
3
:
/* MMC v3.1 - v3.3 */
case
4
:
/* MMC v4 */
card
->
cid
.
manfid
=
UNSTUFF_BITS
(
resp
,
120
,
8
);
card
->
cid
.
manfid
=
UNSTUFF_BITS
(
resp
,
120
,
8
);
card
->
cid
.
oemid
=
UNSTUFF_BITS
(
resp
,
104
,
16
);
card
->
cid
.
oemid
=
UNSTUFF_BITS
(
resp
,
104
,
16
);
card
->
cid
.
prod_name
[
0
]
=
UNSTUFF_BITS
(
resp
,
96
,
8
);
card
->
cid
.
prod_name
[
0
]
=
UNSTUFF_BITS
(
resp
,
96
,
8
);
...
...
drivers/mmc/mmc_block.c
View file @
8e9c238c
...
@@ -187,7 +187,13 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
...
@@ -187,7 +187,13 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
brq
.
data
.
flags
|=
MMC_DATA_WRITE
;
brq
.
data
.
flags
|=
MMC_DATA_WRITE
;
brq
.
data
.
blocks
=
1
;
brq
.
data
.
blocks
=
1
;
}
}
brq
.
mrq
.
stop
=
brq
.
data
.
blocks
>
1
?
&
brq
.
stop
:
NULL
;
if
(
brq
.
data
.
blocks
>
1
)
{
brq
.
data
.
flags
|=
MMC_DATA_MULTI
;
brq
.
mrq
.
stop
=
&
brq
.
stop
;
}
else
{
brq
.
mrq
.
stop
=
NULL
;
}
brq
.
data
.
sg
=
mq
->
sg
;
brq
.
data
.
sg
=
mq
->
sg
;
brq
.
data
.
sg_len
=
blk_rq_map_sg
(
req
->
q
,
req
,
brq
.
data
.
sg
);
brq
.
data
.
sg_len
=
blk_rq_map_sg
(
req
->
q
,
req
,
brq
.
data
.
sg
);
...
...
drivers/mmc/wbsd.c
View file @
8e9c238c
...
@@ -90,7 +90,7 @@ static int dma = 2;
...
@@ -90,7 +90,7 @@ static int dma = 2;
* Basic functions
* Basic functions
*/
*/
static
inline
void
wbsd_unlock_config
(
struct
wbsd_host
*
host
)
static
inline
void
wbsd_unlock_config
(
struct
wbsd_host
*
host
)
{
{
BUG_ON
(
host
->
config
==
0
);
BUG_ON
(
host
->
config
==
0
);
...
@@ -98,14 +98,14 @@ static inline void wbsd_unlock_config(struct wbsd_host* host)
...
@@ -98,14 +98,14 @@ static inline void wbsd_unlock_config(struct wbsd_host* host)
outb
(
host
->
unlock_code
,
host
->
config
);
outb
(
host
->
unlock_code
,
host
->
config
);
}
}
static
inline
void
wbsd_lock_config
(
struct
wbsd_host
*
host
)
static
inline
void
wbsd_lock_config
(
struct
wbsd_host
*
host
)
{
{
BUG_ON
(
host
->
config
==
0
);
BUG_ON
(
host
->
config
==
0
);
outb
(
LOCK_CODE
,
host
->
config
);
outb
(
LOCK_CODE
,
host
->
config
);
}
}
static
inline
void
wbsd_write_config
(
struct
wbsd_host
*
host
,
u8
reg
,
u8
value
)
static
inline
void
wbsd_write_config
(
struct
wbsd_host
*
host
,
u8
reg
,
u8
value
)
{
{
BUG_ON
(
host
->
config
==
0
);
BUG_ON
(
host
->
config
==
0
);
...
@@ -113,7 +113,7 @@ static inline void wbsd_write_config(struct wbsd_host* host, u8 reg, u8 value)
...
@@ -113,7 +113,7 @@ static inline void wbsd_write_config(struct wbsd_host* host, u8 reg, u8 value)
outb
(
value
,
host
->
config
+
1
);
outb
(
value
,
host
->
config
+
1
);
}
}
static
inline
u8
wbsd_read_config
(
struct
wbsd_host
*
host
,
u8
reg
)
static
inline
u8
wbsd_read_config
(
struct
wbsd_host
*
host
,
u8
reg
)
{
{
BUG_ON
(
host
->
config
==
0
);
BUG_ON
(
host
->
config
==
0
);
...
@@ -121,13 +121,13 @@ static inline u8 wbsd_read_config(struct wbsd_host* host, u8 reg)
...
@@ -121,13 +121,13 @@ static inline u8 wbsd_read_config(struct wbsd_host* host, u8 reg)
return
inb
(
host
->
config
+
1
);
return
inb
(
host
->
config
+
1
);
}
}
static
inline
void
wbsd_write_index
(
struct
wbsd_host
*
host
,
u8
index
,
u8
value
)
static
inline
void
wbsd_write_index
(
struct
wbsd_host
*
host
,
u8
index
,
u8
value
)
{
{
outb
(
index
,
host
->
base
+
WBSD_IDXR
);
outb
(
index
,
host
->
base
+
WBSD_IDXR
);
outb
(
value
,
host
->
base
+
WBSD_DATAR
);
outb
(
value
,
host
->
base
+
WBSD_DATAR
);
}
}
static
inline
u8
wbsd_read_index
(
struct
wbsd_host
*
host
,
u8
index
)
static
inline
u8
wbsd_read_index
(
struct
wbsd_host
*
host
,
u8
index
)
{
{
outb
(
index
,
host
->
base
+
WBSD_IDXR
);
outb
(
index
,
host
->
base
+
WBSD_IDXR
);
return
inb
(
host
->
base
+
WBSD_DATAR
);
return
inb
(
host
->
base
+
WBSD_DATAR
);
...
@@ -137,7 +137,7 @@ static inline u8 wbsd_read_index(struct wbsd_host* host, u8 index)
...
@@ -137,7 +137,7 @@ static inline u8 wbsd_read_index(struct wbsd_host* host, u8 index)
* Common routines
* Common routines
*/
*/
static
void
wbsd_init_device
(
struct
wbsd_host
*
host
)
static
void
wbsd_init_device
(
struct
wbsd_host
*
host
)
{
{
u8
setup
,
ier
;
u8
setup
,
ier
;
...
@@ -197,7 +197,7 @@ static void wbsd_init_device(struct wbsd_host* host)
...
@@ -197,7 +197,7 @@ static void wbsd_init_device(struct wbsd_host* host)
inb
(
host
->
base
+
WBSD_ISR
);
inb
(
host
->
base
+
WBSD_ISR
);
}
}
static
void
wbsd_reset
(
struct
wbsd_host
*
host
)
static
void
wbsd_reset
(
struct
wbsd_host
*
host
)
{
{
u8
setup
;
u8
setup
;
...
@@ -211,14 +211,13 @@ static void wbsd_reset(struct wbsd_host* host)
...
@@ -211,14 +211,13 @@ static void wbsd_reset(struct wbsd_host* host)
wbsd_write_index
(
host
,
WBSD_IDX_SETUP
,
setup
);
wbsd_write_index
(
host
,
WBSD_IDX_SETUP
,
setup
);
}
}
static
void
wbsd_request_end
(
struct
wbsd_host
*
host
,
struct
mmc_request
*
mrq
)
static
void
wbsd_request_end
(
struct
wbsd_host
*
host
,
struct
mmc_request
*
mrq
)
{
{
unsigned
long
dmaflags
;
unsigned
long
dmaflags
;
DBGF
(
"Ending request, cmd (%x)
\n
"
,
mrq
->
cmd
->
opcode
);
DBGF
(
"Ending request, cmd (%x)
\n
"
,
mrq
->
cmd
->
opcode
);
if
(
host
->
dma
>=
0
)
if
(
host
->
dma
>=
0
)
{
{
/*
/*
* Release ISA DMA controller.
* Release ISA DMA controller.
*/
*/
...
@@ -247,7 +246,7 @@ static void wbsd_request_end(struct wbsd_host* host, struct mmc_request* mrq)
...
@@ -247,7 +246,7 @@ static void wbsd_request_end(struct wbsd_host* host, struct mmc_request* mrq)
* Scatter/gather functions
* Scatter/gather functions
*/
*/
static
inline
void
wbsd_init_sg
(
struct
wbsd_host
*
host
,
struct
mmc_data
*
data
)
static
inline
void
wbsd_init_sg
(
struct
wbsd_host
*
host
,
struct
mmc_data
*
data
)
{
{
/*
/*
* Get info. about SG list from data structure.
* Get info. about SG list from data structure.
...
@@ -259,7 +258,7 @@ static inline void wbsd_init_sg(struct wbsd_host* host, struct mmc_data* data)
...
@@ -259,7 +258,7 @@ static inline void wbsd_init_sg(struct wbsd_host* host, struct mmc_data* data)
host
->
remain
=
host
->
cur_sg
->
length
;
host
->
remain
=
host
->
cur_sg
->
length
;
}
}
static
inline
int
wbsd_next_sg
(
struct
wbsd_host
*
host
)
static
inline
int
wbsd_next_sg
(
struct
wbsd_host
*
host
)
{
{
/*
/*
* Skip to next SG entry.
* Skip to next SG entry.
...
@@ -270,33 +269,32 @@ static inline int wbsd_next_sg(struct wbsd_host* host)
...
@@ -270,33 +269,32 @@ static inline int wbsd_next_sg(struct wbsd_host* host)
/*
/*
* Any entries left?
* Any entries left?
*/
*/
if
(
host
->
num_sg
>
0
)
if
(
host
->
num_sg
>
0
)
{
{
host
->
offset
=
0
;
host
->
offset
=
0
;
host
->
remain
=
host
->
cur_sg
->
length
;
host
->
remain
=
host
->
cur_sg
->
length
;
}
}
return
host
->
num_sg
;
return
host
->
num_sg
;
}
}
static
inline
char
*
wbsd_kmap_sg
(
struct
wbsd_host
*
host
)
static
inline
char
*
wbsd_kmap_sg
(
struct
wbsd_host
*
host
)
{
{
host
->
mapped_sg
=
kmap_atomic
(
host
->
cur_sg
->
page
,
KM_BIO_SRC_IRQ
)
+
host
->
mapped_sg
=
kmap_atomic
(
host
->
cur_sg
->
page
,
KM_BIO_SRC_IRQ
)
+
host
->
cur_sg
->
offset
;
host
->
cur_sg
->
offset
;
return
host
->
mapped_sg
;
return
host
->
mapped_sg
;
}
}
static
inline
void
wbsd_kunmap_sg
(
struct
wbsd_host
*
host
)
static
inline
void
wbsd_kunmap_sg
(
struct
wbsd_host
*
host
)
{
{
kunmap_atomic
(
host
->
mapped_sg
,
KM_BIO_SRC_IRQ
);
kunmap_atomic
(
host
->
mapped_sg
,
KM_BIO_SRC_IRQ
);
}
}
static
inline
void
wbsd_sg_to_dma
(
struct
wbsd_host
*
host
,
struct
mmc_data
*
data
)
static
inline
void
wbsd_sg_to_dma
(
struct
wbsd_host
*
host
,
struct
mmc_data
*
data
)
{
{
unsigned
int
len
,
i
,
size
;
unsigned
int
len
,
i
,
size
;
struct
scatterlist
*
sg
;
struct
scatterlist
*
sg
;
char
*
dmabuf
=
host
->
dma_buffer
;
char
*
dmabuf
=
host
->
dma_buffer
;
char
*
sgbuf
;
char
*
sgbuf
;
size
=
host
->
size
;
size
=
host
->
size
;
...
@@ -308,8 +306,7 @@ static inline void wbsd_sg_to_dma(struct wbsd_host* host, struct mmc_data* data)
...
@@ -308,8 +306,7 @@ static inline void wbsd_sg_to_dma(struct wbsd_host* host, struct mmc_data* data)
* be the entire list though so make sure that
* be the entire list though so make sure that
* we do not transfer too much.
* we do not transfer too much.
*/
*/
for
(
i
=
0
;
i
<
len
;
i
++
)
for
(
i
=
0
;
i
<
len
;
i
++
)
{
{
sgbuf
=
kmap_atomic
(
sg
[
i
].
page
,
KM_BIO_SRC_IRQ
)
+
sg
[
i
].
offset
;
sgbuf
=
kmap_atomic
(
sg
[
i
].
page
,
KM_BIO_SRC_IRQ
)
+
sg
[
i
].
offset
;
if
(
size
<
sg
[
i
].
length
)
if
(
size
<
sg
[
i
].
length
)
memcpy
(
dmabuf
,
sgbuf
,
size
);
memcpy
(
dmabuf
,
sgbuf
,
size
);
...
@@ -337,12 +334,12 @@ static inline void wbsd_sg_to_dma(struct wbsd_host* host, struct mmc_data* data)
...
@@ -337,12 +334,12 @@ static inline void wbsd_sg_to_dma(struct wbsd_host* host, struct mmc_data* data)
host
->
size
-=
size
;
host
->
size
-=
size
;
}
}
static
inline
void
wbsd_dma_to_sg
(
struct
wbsd_host
*
host
,
struct
mmc_data
*
data
)
static
inline
void
wbsd_dma_to_sg
(
struct
wbsd_host
*
host
,
struct
mmc_data
*
data
)
{
{
unsigned
int
len
,
i
,
size
;
unsigned
int
len
,
i
,
size
;
struct
scatterlist
*
sg
;
struct
scatterlist
*
sg
;
char
*
dmabuf
=
host
->
dma_buffer
;
char
*
dmabuf
=
host
->
dma_buffer
;
char
*
sgbuf
;
char
*
sgbuf
;
size
=
host
->
size
;
size
=
host
->
size
;
...
@@ -354,8 +351,7 @@ static inline void wbsd_dma_to_sg(struct wbsd_host* host, struct mmc_data* data)
...
@@ -354,8 +351,7 @@ static inline void wbsd_dma_to_sg(struct wbsd_host* host, struct mmc_data* data)
* be the entire list though so make sure that
* be the entire list though so make sure that
* we do not transfer too much.
* we do not transfer too much.
*/
*/
for
(
i
=
0
;
i
<
len
;
i
++
)
for
(
i
=
0
;
i
<
len
;
i
++
)
{
{
sgbuf
=
kmap_atomic
(
sg
[
i
].
page
,
KM_BIO_SRC_IRQ
)
+
sg
[
i
].
offset
;
sgbuf
=
kmap_atomic
(
sg
[
i
].
page
,
KM_BIO_SRC_IRQ
)
+
sg
[
i
].
offset
;
if
(
size
<
sg
[
i
].
length
)
if
(
size
<
sg
[
i
].
length
)
memcpy
(
sgbuf
,
dmabuf
,
size
);
memcpy
(
sgbuf
,
dmabuf
,
size
);
...
@@ -387,46 +383,38 @@ static inline void wbsd_dma_to_sg(struct wbsd_host* host, struct mmc_data* data)
...
@@ -387,46 +383,38 @@ static inline void wbsd_dma_to_sg(struct wbsd_host* host, struct mmc_data* data)
* Command handling
* Command handling
*/
*/
static
inline
void
wbsd_get_short_reply
(
struct
wbsd_host
*
host
,
static
inline
void
wbsd_get_short_reply
(
struct
wbsd_host
*
host
,
struct
mmc_command
*
cmd
)
struct
mmc_command
*
cmd
)
{
{
/*
/*
* Correct response type?
* Correct response type?
*/
*/
if
(
wbsd_read_index
(
host
,
WBSD_IDX_RSPLEN
)
!=
WBSD_RSP_SHORT
)
if
(
wbsd_read_index
(
host
,
WBSD_IDX_RSPLEN
)
!=
WBSD_RSP_SHORT
)
{
{
cmd
->
error
=
MMC_ERR_INVALID
;
cmd
->
error
=
MMC_ERR_INVALID
;
return
;
return
;
}
}
cmd
->
resp
[
0
]
=
cmd
->
resp
[
0
]
=
wbsd_read_index
(
host
,
WBSD_IDX_RESP12
)
<<
24
;
wbsd_read_index
(
host
,
WBSD_IDX_RESP12
)
<<
24
;
cmd
->
resp
[
0
]
|=
wbsd_read_index
(
host
,
WBSD_IDX_RESP13
)
<<
16
;
cmd
->
resp
[
0
]
|=
cmd
->
resp
[
0
]
|=
wbsd_read_index
(
host
,
WBSD_IDX_RESP14
)
<<
8
;
wbsd_read_index
(
host
,
WBSD_IDX_RESP13
)
<<
16
;
cmd
->
resp
[
0
]
|=
wbsd_read_index
(
host
,
WBSD_IDX_RESP15
)
<<
0
;
cmd
->
resp
[
0
]
|=
cmd
->
resp
[
1
]
=
wbsd_read_index
(
host
,
WBSD_IDX_RESP16
)
<<
24
;
wbsd_read_index
(
host
,
WBSD_IDX_RESP14
)
<<
8
;
cmd
->
resp
[
0
]
|=
wbsd_read_index
(
host
,
WBSD_IDX_RESP15
)
<<
0
;
cmd
->
resp
[
1
]
=
wbsd_read_index
(
host
,
WBSD_IDX_RESP16
)
<<
24
;
}
}
static
inline
void
wbsd_get_long_reply
(
struct
wbsd_host
*
host
,
static
inline
void
wbsd_get_long_reply
(
struct
wbsd_host
*
host
,
struct
mmc_command
*
cmd
)
struct
mmc_command
*
cmd
)
{
{
int
i
;
int
i
;
/*
/*
* Correct response type?
* Correct response type?
*/
*/
if
(
wbsd_read_index
(
host
,
WBSD_IDX_RSPLEN
)
!=
WBSD_RSP_LONG
)
if
(
wbsd_read_index
(
host
,
WBSD_IDX_RSPLEN
)
!=
WBSD_RSP_LONG
)
{
{
cmd
->
error
=
MMC_ERR_INVALID
;
cmd
->
error
=
MMC_ERR_INVALID
;
return
;
return
;
}
}
for
(
i
=
0
;
i
<
4
;
i
++
)
for
(
i
=
0
;
i
<
4
;
i
++
)
{
{
cmd
->
resp
[
i
]
=
cmd
->
resp
[
i
]
=
wbsd_read_index
(
host
,
WBSD_IDX_RESP1
+
i
*
4
)
<<
24
;
wbsd_read_index
(
host
,
WBSD_IDX_RESP1
+
i
*
4
)
<<
24
;
cmd
->
resp
[
i
]
|=
cmd
->
resp
[
i
]
|=
...
@@ -438,7 +426,7 @@ static inline void wbsd_get_long_reply(struct wbsd_host* host,
...
@@ -438,7 +426,7 @@ static inline void wbsd_get_long_reply(struct wbsd_host* host,
}
}
}
}
static
void
wbsd_send_command
(
struct
wbsd_host
*
host
,
struct
mmc_command
*
cmd
)
static
void
wbsd_send_command
(
struct
wbsd_host
*
host
,
struct
mmc_command
*
cmd
)
{
{
int
i
;
int
i
;
u8
status
,
isr
;
u8
status
,
isr
;
...
@@ -456,7 +444,7 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
...
@@ -456,7 +444,7 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
* Send the command (CRC calculated by host).
* Send the command (CRC calculated by host).
*/
*/
outb
(
cmd
->
opcode
,
host
->
base
+
WBSD_CMDR
);
outb
(
cmd
->
opcode
,
host
->
base
+
WBSD_CMDR
);
for
(
i
=
3
;
i
>=
0
;
i
--
)
for
(
i
=
3
;
i
>=
0
;
i
--
)
outb
((
cmd
->
arg
>>
(
i
*
8
))
&
0xff
,
host
->
base
+
WBSD_CMDR
);
outb
((
cmd
->
arg
>>
(
i
*
8
))
&
0xff
,
host
->
base
+
WBSD_CMDR
);
cmd
->
error
=
MMC_ERR_NONE
;
cmd
->
error
=
MMC_ERR_NONE
;
...
@@ -471,8 +459,7 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
...
@@ -471,8 +459,7 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
/*
/*
* Do we expect a reply?
* Do we expect a reply?
*/
*/
if
((
cmd
->
flags
&
MMC_RSP_MASK
)
!=
MMC_RSP_NONE
)
if
((
cmd
->
flags
&
MMC_RSP_MASK
)
!=
MMC_RSP_NONE
)
{
{
/*
/*
* Read back status.
* Read back status.
*/
*/
...
@@ -488,8 +475,7 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
...
@@ -488,8 +475,7 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
else
if
((
cmd
->
flags
&
MMC_RSP_CRC
)
&&
(
isr
&
WBSD_INT_CRC
))
else
if
((
cmd
->
flags
&
MMC_RSP_CRC
)
&&
(
isr
&
WBSD_INT_CRC
))
cmd
->
error
=
MMC_ERR_BADCRC
;
cmd
->
error
=
MMC_ERR_BADCRC
;
/* All ok */
/* All ok */
else
else
{
{
if
((
cmd
->
flags
&
MMC_RSP_MASK
)
==
MMC_RSP_SHORT
)
if
((
cmd
->
flags
&
MMC_RSP_MASK
)
==
MMC_RSP_SHORT
)
wbsd_get_short_reply
(
host
,
cmd
);
wbsd_get_short_reply
(
host
,
cmd
);
else
else
...
@@ -504,10 +490,10 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
...
@@ -504,10 +490,10 @@ static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd)
* Data functions
* Data functions
*/
*/
static
void
wbsd_empty_fifo
(
struct
wbsd_host
*
host
)
static
void
wbsd_empty_fifo
(
struct
wbsd_host
*
host
)
{
{
struct
mmc_data
*
data
=
host
->
mrq
->
cmd
->
data
;
struct
mmc_data
*
data
=
host
->
mrq
->
cmd
->
data
;
char
*
buffer
;
char
*
buffer
;
int
i
,
fsr
,
fifo
;
int
i
,
fsr
,
fifo
;
/*
/*
...
@@ -522,8 +508,7 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
...
@@ -522,8 +508,7 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
* Drain the fifo. This has a tendency to loop longer
* Drain the fifo. This has a tendency to loop longer
* than the FIFO length (usually one block).
* than the FIFO length (usually one block).
*/
*/
while
(
!
((
fsr
=
inb
(
host
->
base
+
WBSD_FSR
))
&
WBSD_FIFO_EMPTY
))
while
(
!
((
fsr
=
inb
(
host
->
base
+
WBSD_FSR
))
&
WBSD_FIFO_EMPTY
))
{
{
/*
/*
* The size field in the FSR is broken so we have to
* The size field in the FSR is broken so we have to
* do some guessing.
* do some guessing.
...
@@ -535,8 +520,7 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
...
@@ -535,8 +520,7 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
else
else
fifo
=
1
;
fifo
=
1
;
for
(
i
=
0
;
i
<
fifo
;
i
++
)
for
(
i
=
0
;
i
<
fifo
;
i
++
)
{
{
*
buffer
=
inb
(
host
->
base
+
WBSD_DFR
);
*
buffer
=
inb
(
host
->
base
+
WBSD_DFR
);
buffer
++
;
buffer
++
;
host
->
offset
++
;
host
->
offset
++
;
...
@@ -547,8 +531,7 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
...
@@ -547,8 +531,7 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
/*
/*
* Transfer done?
* Transfer done?
*/
*/
if
(
data
->
bytes_xfered
==
host
->
size
)
if
(
data
->
bytes_xfered
==
host
->
size
)
{
{
wbsd_kunmap_sg
(
host
);
wbsd_kunmap_sg
(
host
);
return
;
return
;
}
}
...
@@ -556,15 +539,13 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
...
@@ -556,15 +539,13 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
/*
/*
* End of scatter list entry?
* End of scatter list entry?
*/
*/
if
(
host
->
remain
==
0
)
if
(
host
->
remain
==
0
)
{
{
wbsd_kunmap_sg
(
host
);
wbsd_kunmap_sg
(
host
);
/*
/*
* Get next entry. Check if last.
* Get next entry. Check if last.
*/
*/
if
(
!
wbsd_next_sg
(
host
))
if
(
!
wbsd_next_sg
(
host
))
{
{
/*
/*
* We should never reach this point.
* We should never reach this point.
* It means that we're trying to
* It means that we're trying to
...
@@ -594,10 +575,10 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
...
@@ -594,10 +575,10 @@ static void wbsd_empty_fifo(struct wbsd_host* host)
tasklet_schedule
(
&
host
->
fifo_tasklet
);
tasklet_schedule
(
&
host
->
fifo_tasklet
);
}
}
static
void
wbsd_fill_fifo
(
struct
wbsd_host
*
host
)
static
void
wbsd_fill_fifo
(
struct
wbsd_host
*
host
)
{
{
struct
mmc_data
*
data
=
host
->
mrq
->
cmd
->
data
;
struct
mmc_data
*
data
=
host
->
mrq
->
cmd
->
data
;
char
*
buffer
;
char
*
buffer
;
int
i
,
fsr
,
fifo
;
int
i
,
fsr
,
fifo
;
/*
/*
...
@@ -613,8 +594,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
...
@@ -613,8 +594,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
* Fill the fifo. This has a tendency to loop longer
* Fill the fifo. This has a tendency to loop longer
* than the FIFO length (usually one block).
* than the FIFO length (usually one block).
*/
*/
while
(
!
((
fsr
=
inb
(
host
->
base
+
WBSD_FSR
))
&
WBSD_FIFO_FULL
))
while
(
!
((
fsr
=
inb
(
host
->
base
+
WBSD_FSR
))
&
WBSD_FIFO_FULL
))
{
{
/*
/*
* The size field in the FSR is broken so we have to
* The size field in the FSR is broken so we have to
* do some guessing.
* do some guessing.
...
@@ -626,8 +606,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
...
@@ -626,8 +606,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
else
else
fifo
=
15
;
fifo
=
15
;
for
(
i
=
16
;
i
>
fifo
;
i
--
)
for
(
i
=
16
;
i
>
fifo
;
i
--
)
{
{
outb
(
*
buffer
,
host
->
base
+
WBSD_DFR
);
outb
(
*
buffer
,
host
->
base
+
WBSD_DFR
);
buffer
++
;
buffer
++
;
host
->
offset
++
;
host
->
offset
++
;
...
@@ -638,8 +617,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
...
@@ -638,8 +617,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
/*
/*
* Transfer done?
* Transfer done?
*/
*/
if
(
data
->
bytes_xfered
==
host
->
size
)
if
(
data
->
bytes_xfered
==
host
->
size
)
{
{
wbsd_kunmap_sg
(
host
);
wbsd_kunmap_sg
(
host
);
return
;
return
;
}
}
...
@@ -647,15 +625,13 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
...
@@ -647,15 +625,13 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
/*
/*
* End of scatter list entry?
* End of scatter list entry?
*/
*/
if
(
host
->
remain
==
0
)
if
(
host
->
remain
==
0
)
{
{
wbsd_kunmap_sg
(
host
);
wbsd_kunmap_sg
(
host
);
/*
/*
* Get next entry. Check if last.
* Get next entry. Check if last.
*/
*/
if
(
!
wbsd_next_sg
(
host
))
if
(
!
wbsd_next_sg
(
host
))
{
{
/*
/*
* We should never reach this point.
* We should never reach this point.
* It means that we're trying to
* It means that we're trying to
...
@@ -684,7 +660,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
...
@@ -684,7 +660,7 @@ static void wbsd_fill_fifo(struct wbsd_host* host)
tasklet_schedule
(
&
host
->
fifo_tasklet
);
tasklet_schedule
(
&
host
->
fifo_tasklet
);
}
}
static
void
wbsd_prepare_data
(
struct
wbsd_host
*
host
,
struct
mmc_data
*
data
)
static
void
wbsd_prepare_data
(
struct
wbsd_host
*
host
,
struct
mmc_data
*
data
)
{
{
u16
blksize
;
u16
blksize
;
u8
setup
;
u8
setup
;
...
@@ -706,8 +682,10 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
...
@@ -706,8 +682,10 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
*/
*/
if
(
data
->
timeout_ns
>
127000000
)
if
(
data
->
timeout_ns
>
127000000
)
wbsd_write_index
(
host
,
WBSD_IDX_TAAC
,
127
);
wbsd_write_index
(
host
,
WBSD_IDX_TAAC
,
127
);
else
else
{
wbsd_write_index
(
host
,
WBSD_IDX_TAAC
,
data
->
timeout_ns
/
1000000
);
wbsd_write_index
(
host
,
WBSD_IDX_TAAC
,
data
->
timeout_ns
/
1000000
);
}
if
(
data
->
timeout_clks
>
255
)
if
(
data
->
timeout_clks
>
255
)
wbsd_write_index
(
host
,
WBSD_IDX_NSAC
,
255
);
wbsd_write_index
(
host
,
WBSD_IDX_NSAC
,
255
);
...
@@ -722,23 +700,18 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
...
@@ -722,23 +700,18 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
* Space for CRC must be included in the size.
* Space for CRC must be included in the size.
* Two bytes are needed for each data line.
* Two bytes are needed for each data line.
*/
*/
if
(
host
->
bus_width
==
MMC_BUS_WIDTH_1
)
if
(
host
->
bus_width
==
MMC_BUS_WIDTH_1
)
{
{
blksize
=
(
1
<<
data
->
blksz_bits
)
+
2
;
blksize
=
(
1
<<
data
->
blksz_bits
)
+
2
;
wbsd_write_index
(
host
,
WBSD_IDX_PBSMSB
,
(
blksize
>>
4
)
&
0xF0
);
wbsd_write_index
(
host
,
WBSD_IDX_PBSMSB
,
(
blksize
>>
4
)
&
0xF0
);
wbsd_write_index
(
host
,
WBSD_IDX_PBSLSB
,
blksize
&
0xFF
);
wbsd_write_index
(
host
,
WBSD_IDX_PBSLSB
,
blksize
&
0xFF
);
}
}
else
if
(
host
->
bus_width
==
MMC_BUS_WIDTH_4
)
{
else
if
(
host
->
bus_width
==
MMC_BUS_WIDTH_4
)
{
blksize
=
(
1
<<
data
->
blksz_bits
)
+
2
*
4
;
blksize
=
(
1
<<
data
->
blksz_bits
)
+
2
*
4
;
wbsd_write_index
(
host
,
WBSD_IDX_PBSMSB
,
((
blksize
>>
4
)
&
0xF0
)
wbsd_write_index
(
host
,
WBSD_IDX_PBSMSB
,
|
WBSD_DATA_WIDTH
);
((
blksize
>>
4
)
&
0xF0
)
|
WBSD_DATA_WIDTH
);
wbsd_write_index
(
host
,
WBSD_IDX_PBSLSB
,
blksize
&
0xFF
);
wbsd_write_index
(
host
,
WBSD_IDX_PBSLSB
,
blksize
&
0xFF
);
}
}
else
{
else
{
data
->
error
=
MMC_ERR_INVALID
;
data
->
error
=
MMC_ERR_INVALID
;
return
;
return
;
}
}
...
@@ -755,14 +728,12 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
...
@@ -755,14 +728,12 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
/*
/*
* DMA transfer?
* DMA transfer?
*/
*/
if
(
host
->
dma
>=
0
)
if
(
host
->
dma
>=
0
)
{
{
/*
/*
* The buffer for DMA is only 64 kB.
* The buffer for DMA is only 64 kB.
*/
*/
BUG_ON
(
host
->
size
>
0x10000
);
BUG_ON
(
host
->
size
>
0x10000
);
if
(
host
->
size
>
0x10000
)
if
(
host
->
size
>
0x10000
)
{
{
data
->
error
=
MMC_ERR_INVALID
;
data
->
error
=
MMC_ERR_INVALID
;
return
;
return
;
}
}
...
@@ -794,9 +765,7 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
...
@@ -794,9 +765,7 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
* Enable DMA on the host.
* Enable DMA on the host.
*/
*/
wbsd_write_index
(
host
,
WBSD_IDX_DMA
,
WBSD_DMA_ENABLE
);
wbsd_write_index
(
host
,
WBSD_IDX_DMA
,
WBSD_DMA_ENABLE
);
}
}
else
{
else
{
/*
/*
* This flag is used to keep printk
* This flag is used to keep printk
* output to a minimum.
* output to a minimum.
...
@@ -817,13 +786,10 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
...
@@ -817,13 +786,10 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
* Set up FIFO threshold levels (and fill
* Set up FIFO threshold levels (and fill
* buffer if doing a write).
* buffer if doing a write).
*/
*/
if
(
data
->
flags
&
MMC_DATA_READ
)
if
(
data
->
flags
&
MMC_DATA_READ
)
{
{
wbsd_write_index
(
host
,
WBSD_IDX_FIFOEN
,
wbsd_write_index
(
host
,
WBSD_IDX_FIFOEN
,
WBSD_FIFOEN_FULL
|
8
);
WBSD_FIFOEN_FULL
|
8
);
}
}
else
{
else
{
wbsd_write_index
(
host
,
WBSD_IDX_FIFOEN
,
wbsd_write_index
(
host
,
WBSD_IDX_FIFOEN
,
WBSD_FIFOEN_EMPTY
|
8
);
WBSD_FIFOEN_EMPTY
|
8
);
wbsd_fill_fifo
(
host
);
wbsd_fill_fifo
(
host
);
...
@@ -833,7 +799,7 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
...
@@ -833,7 +799,7 @@ static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data)
data
->
error
=
MMC_ERR_NONE
;
data
->
error
=
MMC_ERR_NONE
;
}
}
static
void
wbsd_finish_data
(
struct
wbsd_host
*
host
,
struct
mmc_data
*
data
)
static
void
wbsd_finish_data
(
struct
wbsd_host
*
host
,
struct
mmc_data
*
data
)
{
{
unsigned
long
dmaflags
;
unsigned
long
dmaflags
;
int
count
;
int
count
;
...
@@ -851,16 +817,14 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
...
@@ -851,16 +817,14 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
* Wait for the controller to leave data
* Wait for the controller to leave data
* transfer state.
* transfer state.
*/
*/
do
do
{
{
status
=
wbsd_read_index
(
host
,
WBSD_IDX_STATUS
);
status
=
wbsd_read_index
(
host
,
WBSD_IDX_STATUS
);
}
while
(
status
&
(
WBSD_BLOCK_READ
|
WBSD_BLOCK_WRITE
));
}
while
(
status
&
(
WBSD_BLOCK_READ
|
WBSD_BLOCK_WRITE
));
/*
/*
* DMA transfer?
* DMA transfer?
*/
*/
if
(
host
->
dma
>=
0
)
if
(
host
->
dma
>=
0
)
{
{
/*
/*
* Disable DMA on the host.
* Disable DMA on the host.
*/
*/
...
@@ -878,16 +842,13 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
...
@@ -878,16 +842,13 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
/*
/*
* Any leftover data?
* Any leftover data?
*/
*/
if
(
count
)
if
(
count
)
{
{
printk
(
KERN_ERR
"%s: Incomplete DMA transfer. "
printk
(
KERN_ERR
"%s: Incomplete DMA transfer. "
"%d bytes left.
\n
"
,
"%d bytes left.
\n
"
,
mmc_hostname
(
host
->
mmc
),
count
);
mmc_hostname
(
host
->
mmc
),
count
);
data
->
error
=
MMC_ERR_FAILED
;
data
->
error
=
MMC_ERR_FAILED
;
}
}
else
{
else
{
/*
/*
* Transfer data from DMA buffer to
* Transfer data from DMA buffer to
* SG list.
* SG list.
...
@@ -910,10 +871,10 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
...
@@ -910,10 +871,10 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data)
* *
* *
\*****************************************************************************/
\*****************************************************************************/
static
void
wbsd_request
(
struct
mmc_host
*
mmc
,
struct
mmc_request
*
mrq
)
static
void
wbsd_request
(
struct
mmc_host
*
mmc
,
struct
mmc_request
*
mrq
)
{
{
struct
wbsd_host
*
host
=
mmc_priv
(
mmc
);
struct
wbsd_host
*
host
=
mmc_priv
(
mmc
);
struct
mmc_command
*
cmd
;
struct
mmc_command
*
cmd
;
/*
/*
* Disable tasklets to avoid a deadlock.
* Disable tasklets to avoid a deadlock.
...
@@ -930,8 +891,7 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq)
...
@@ -930,8 +891,7 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq)
* If there is no card in the slot then
* If there is no card in the slot then
* timeout immediatly.
* timeout immediatly.
*/
*/
if
(
!
(
host
->
flags
&
WBSD_FCARD_PRESENT
))
if
(
!
(
host
->
flags
&
WBSD_FCARD_PRESENT
))
{
{
cmd
->
error
=
MMC_ERR_TIMEOUT
;
cmd
->
error
=
MMC_ERR_TIMEOUT
;
goto
done
;
goto
done
;
}
}
...
@@ -939,8 +899,7 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq)
...
@@ -939,8 +899,7 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq)
/*
/*
* Does the request include data?
* Does the request include data?
*/
*/
if
(
cmd
->
data
)
if
(
cmd
->
data
)
{
{
wbsd_prepare_data
(
host
,
cmd
->
data
);
wbsd_prepare_data
(
host
,
cmd
->
data
);
if
(
cmd
->
data
->
error
!=
MMC_ERR_NONE
)
if
(
cmd
->
data
->
error
!=
MMC_ERR_NONE
)
...
@@ -954,8 +913,7 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq)
...
@@ -954,8 +913,7 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq)
* will be finished after the data has
* will be finished after the data has
* transfered.
* transfered.
*/
*/
if
(
cmd
->
data
&&
(
cmd
->
error
==
MMC_ERR_NONE
))
if
(
cmd
->
data
&&
(
cmd
->
error
==
MMC_ERR_NONE
))
{
{
/*
/*
* Dirty fix for hardware bug.
* Dirty fix for hardware bug.
*/
*/
...
@@ -973,14 +931,14 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq)
...
@@ -973,14 +931,14 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq)
spin_unlock_bh
(
&
host
->
lock
);
spin_unlock_bh
(
&
host
->
lock
);
}
}
static
void
wbsd_set_ios
(
struct
mmc_host
*
mmc
,
struct
mmc_ios
*
ios
)
static
void
wbsd_set_ios
(
struct
mmc_host
*
mmc
,
struct
mmc_ios
*
ios
)
{
{
struct
wbsd_host
*
host
=
mmc_priv
(
mmc
);
struct
wbsd_host
*
host
=
mmc_priv
(
mmc
);
u8
clk
,
setup
,
pwr
;
u8
clk
,
setup
,
pwr
;
DBGF
(
"clock %uHz busmode %u powermode %u cs %u Vdd %u width %u
\n
"
,
DBGF
(
"clock %uHz busmode %u powermode %u cs %u Vdd %u width %u
\n
"
,
ios
->
clock
,
ios
->
bus_mode
,
ios
->
power_mode
,
ios
->
chip_select
,
ios
->
clock
,
ios
->
bus_mode
,
ios
->
power_mode
,
ios
->
chip_select
,
ios
->
vdd
,
ios
->
bus_width
);
ios
->
vdd
,
ios
->
bus_width
);
spin_lock_bh
(
&
host
->
lock
);
spin_lock_bh
(
&
host
->
lock
);
...
@@ -1004,8 +962,7 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
...
@@ -1004,8 +962,7 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
* Only write to the clock register when
* Only write to the clock register when
* there is an actual change.
* there is an actual change.
*/
*/
if
(
clk
!=
host
->
clk
)
if
(
clk
!=
host
->
clk
)
{
{
wbsd_write_index
(
host
,
WBSD_IDX_CLK
,
clk
);
wbsd_write_index
(
host
,
WBSD_IDX_CLK
,
clk
);
host
->
clk
=
clk
;
host
->
clk
=
clk
;
}
}
...
@@ -1013,8 +970,7 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
...
@@ -1013,8 +970,7 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
/*
/*
* Power up card.
* Power up card.
*/
*/
if
(
ios
->
power_mode
!=
MMC_POWER_OFF
)
if
(
ios
->
power_mode
!=
MMC_POWER_OFF
)
{
{
pwr
=
inb
(
host
->
base
+
WBSD_CSR
);
pwr
=
inb
(
host
->
base
+
WBSD_CSR
);
pwr
&=
~
WBSD_POWER_N
;
pwr
&=
~
WBSD_POWER_N
;
outb
(
pwr
,
host
->
base
+
WBSD_CSR
);
outb
(
pwr
,
host
->
base
+
WBSD_CSR
);
...
@@ -1026,23 +982,19 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
...
@@ -1026,23 +982,19 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
* that needs to be disabled.
* that needs to be disabled.
*/
*/
setup
=
wbsd_read_index
(
host
,
WBSD_IDX_SETUP
);
setup
=
wbsd_read_index
(
host
,
WBSD_IDX_SETUP
);
if
(
ios
->
chip_select
==
MMC_CS_HIGH
)
if
(
ios
->
chip_select
==
MMC_CS_HIGH
)
{
{
BUG_ON
(
ios
->
bus_width
!=
MMC_BUS_WIDTH_1
);
BUG_ON
(
ios
->
bus_width
!=
MMC_BUS_WIDTH_1
);
setup
|=
WBSD_DAT3_H
;
setup
|=
WBSD_DAT3_H
;
host
->
flags
|=
WBSD_FIGNORE_DETECT
;
host
->
flags
|=
WBSD_FIGNORE_DETECT
;
}
}
else
{
else
if
(
setup
&
WBSD_DAT3_H
)
{
{
if
(
setup
&
WBSD_DAT3_H
)
{
setup
&=
~
WBSD_DAT3_H
;
setup
&=
~
WBSD_DAT3_H
;
/*
/*
* We cannot resume card detection immediatly
* We cannot resume card detection immediatly
* because of capacitance and delays in the chip.
* because of capacitance and delays in the chip.
*/
*/
mod_timer
(
&
host
->
ignore_timer
,
jiffies
+
HZ
/
100
);
mod_timer
(
&
host
->
ignore_timer
,
jiffies
+
HZ
/
100
);
}
}
}
}
wbsd_write_index
(
host
,
WBSD_IDX_SETUP
,
setup
);
wbsd_write_index
(
host
,
WBSD_IDX_SETUP
,
setup
);
...
@@ -1056,9 +1008,9 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
...
@@ -1056,9 +1008,9 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
spin_unlock_bh
(
&
host
->
lock
);
spin_unlock_bh
(
&
host
->
lock
);
}
}
static
int
wbsd_get_ro
(
struct
mmc_host
*
mmc
)
static
int
wbsd_get_ro
(
struct
mmc_host
*
mmc
)
{
{
struct
wbsd_host
*
host
=
mmc_priv
(
mmc
);
struct
wbsd_host
*
host
=
mmc_priv
(
mmc
);
u8
csr
;
u8
csr
;
spin_lock_bh
(
&
host
->
lock
);
spin_lock_bh
(
&
host
->
lock
);
...
@@ -1096,7 +1048,7 @@ static struct mmc_host_ops wbsd_ops = {
...
@@ -1096,7 +1048,7 @@ static struct mmc_host_ops wbsd_ops = {
static
void
wbsd_reset_ignore
(
unsigned
long
data
)
static
void
wbsd_reset_ignore
(
unsigned
long
data
)
{
{
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
data
;
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
data
;
BUG_ON
(
host
==
NULL
);
BUG_ON
(
host
==
NULL
);
...
@@ -1119,7 +1071,7 @@ static void wbsd_reset_ignore(unsigned long data)
...
@@ -1119,7 +1071,7 @@ static void wbsd_reset_ignore(unsigned long data)
* Tasklets
* Tasklets
*/
*/
static
inline
struct
mmc_data
*
wbsd_get_data
(
struct
wbsd_host
*
host
)
static
inline
struct
mmc_data
*
wbsd_get_data
(
struct
wbsd_host
*
host
)
{
{
WARN_ON
(
!
host
->
mrq
);
WARN_ON
(
!
host
->
mrq
);
if
(
!
host
->
mrq
)
if
(
!
host
->
mrq
)
...
@@ -1138,14 +1090,13 @@ static inline struct mmc_data* wbsd_get_data(struct wbsd_host* host)
...
@@ -1138,14 +1090,13 @@ static inline struct mmc_data* wbsd_get_data(struct wbsd_host* host)
static
void
wbsd_tasklet_card
(
unsigned
long
param
)
static
void
wbsd_tasklet_card
(
unsigned
long
param
)
{
{
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
u8
csr
;
u8
csr
;
int
delay
=
-
1
;
int
delay
=
-
1
;
spin_lock
(
&
host
->
lock
);
spin_lock
(
&
host
->
lock
);
if
(
host
->
flags
&
WBSD_FIGNORE_DETECT
)
if
(
host
->
flags
&
WBSD_FIGNORE_DETECT
)
{
{
spin_unlock
(
&
host
->
lock
);
spin_unlock
(
&
host
->
lock
);
return
;
return
;
}
}
...
@@ -1153,23 +1104,18 @@ static void wbsd_tasklet_card(unsigned long param)
...
@@ -1153,23 +1104,18 @@ static void wbsd_tasklet_card(unsigned long param)
csr
=
inb
(
host
->
base
+
WBSD_CSR
);
csr
=
inb
(
host
->
base
+
WBSD_CSR
);
WARN_ON
(
csr
==
0xff
);
WARN_ON
(
csr
==
0xff
);
if
(
csr
&
WBSD_CARDPRESENT
)
if
(
csr
&
WBSD_CARDPRESENT
)
{
{
if
(
!
(
host
->
flags
&
WBSD_FCARD_PRESENT
))
{
if
(
!
(
host
->
flags
&
WBSD_FCARD_PRESENT
))
{
DBG
(
"Card inserted
\n
"
);
DBG
(
"Card inserted
\n
"
);
host
->
flags
|=
WBSD_FCARD_PRESENT
;
host
->
flags
|=
WBSD_FCARD_PRESENT
;
delay
=
500
;
delay
=
500
;
}
}
}
}
else
if
(
host
->
flags
&
WBSD_FCARD_PRESENT
)
{
else
if
(
host
->
flags
&
WBSD_FCARD_PRESENT
)
{
DBG
(
"Card removed
\n
"
);
DBG
(
"Card removed
\n
"
);
host
->
flags
&=
~
WBSD_FCARD_PRESENT
;
host
->
flags
&=
~
WBSD_FCARD_PRESENT
;
if
(
host
->
mrq
)
if
(
host
->
mrq
)
{
{
printk
(
KERN_ERR
"%s: Card removed during transfer!
\n
"
,
printk
(
KERN_ERR
"%s: Card removed during transfer!
\n
"
,
mmc_hostname
(
host
->
mmc
));
mmc_hostname
(
host
->
mmc
));
wbsd_reset
(
host
);
wbsd_reset
(
host
);
...
@@ -1193,8 +1139,8 @@ static void wbsd_tasklet_card(unsigned long param)
...
@@ -1193,8 +1139,8 @@ static void wbsd_tasklet_card(unsigned long param)
static
void
wbsd_tasklet_fifo
(
unsigned
long
param
)
static
void
wbsd_tasklet_fifo
(
unsigned
long
param
)
{
{
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
struct
mmc_data
*
data
;
struct
mmc_data
*
data
;
spin_lock
(
&
host
->
lock
);
spin_lock
(
&
host
->
lock
);
...
@@ -1213,8 +1159,7 @@ static void wbsd_tasklet_fifo(unsigned long param)
...
@@ -1213,8 +1159,7 @@ static void wbsd_tasklet_fifo(unsigned long param)
/*
/*
* Done?
* Done?
*/
*/
if
(
host
->
size
==
data
->
bytes_xfered
)
if
(
host
->
size
==
data
->
bytes_xfered
)
{
{
wbsd_write_index
(
host
,
WBSD_IDX_FIFOEN
,
0
);
wbsd_write_index
(
host
,
WBSD_IDX_FIFOEN
,
0
);
tasklet_schedule
(
&
host
->
finish_tasklet
);
tasklet_schedule
(
&
host
->
finish_tasklet
);
}
}
...
@@ -1225,8 +1170,8 @@ static void wbsd_tasklet_fifo(unsigned long param)
...
@@ -1225,8 +1170,8 @@ static void wbsd_tasklet_fifo(unsigned long param)
static
void
wbsd_tasklet_crc
(
unsigned
long
param
)
static
void
wbsd_tasklet_crc
(
unsigned
long
param
)
{
{
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
struct
mmc_data
*
data
;
struct
mmc_data
*
data
;
spin_lock
(
&
host
->
lock
);
spin_lock
(
&
host
->
lock
);
...
@@ -1249,8 +1194,8 @@ static void wbsd_tasklet_crc(unsigned long param)
...
@@ -1249,8 +1194,8 @@ static void wbsd_tasklet_crc(unsigned long param)
static
void
wbsd_tasklet_timeout
(
unsigned
long
param
)
static
void
wbsd_tasklet_timeout
(
unsigned
long
param
)
{
{
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
struct
mmc_data
*
data
;
struct
mmc_data
*
data
;
spin_lock
(
&
host
->
lock
);
spin_lock
(
&
host
->
lock
);
...
@@ -1273,8 +1218,8 @@ static void wbsd_tasklet_timeout(unsigned long param)
...
@@ -1273,8 +1218,8 @@ static void wbsd_tasklet_timeout(unsigned long param)
static
void
wbsd_tasklet_finish
(
unsigned
long
param
)
static
void
wbsd_tasklet_finish
(
unsigned
long
param
)
{
{
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
struct
mmc_data
*
data
;
struct
mmc_data
*
data
;
spin_lock
(
&
host
->
lock
);
spin_lock
(
&
host
->
lock
);
...
@@ -1294,14 +1239,13 @@ static void wbsd_tasklet_finish(unsigned long param)
...
@@ -1294,14 +1239,13 @@ static void wbsd_tasklet_finish(unsigned long param)
static
void
wbsd_tasklet_block
(
unsigned
long
param
)
static
void
wbsd_tasklet_block
(
unsigned
long
param
)
{
{
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
struct
wbsd_host
*
host
=
(
struct
wbsd_host
*
)
param
;
struct
mmc_data
*
data
;
struct
mmc_data
*
data
;
spin_lock
(
&
host
->
lock
);
spin_lock
(
&
host
->
lock
);
if
((
wbsd_read_index
(
host
,
WBSD_IDX_CRCSTATUS
)
&
WBSD_CRC_MASK
)
!=
if
((
wbsd_read_index
(
host
,
WBSD_IDX_CRCSTATUS
)
&
WBSD_CRC_MASK
)
!=
WBSD_CRC_OK
)
WBSD_CRC_OK
)
{
{
data
=
wbsd_get_data
(
host
);
data
=
wbsd_get_data
(
host
);
if
(
!
data
)
if
(
!
data
)
goto
end
;
goto
end
;
...
@@ -1323,7 +1267,7 @@ static void wbsd_tasklet_block(unsigned long param)
...
@@ -1323,7 +1267,7 @@ static void wbsd_tasklet_block(unsigned long param)
static
irqreturn_t
wbsd_irq
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
static
irqreturn_t
wbsd_irq
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
{
struct
wbsd_host
*
host
=
dev_id
;
struct
wbsd_host
*
host
=
dev_id
;
int
isr
;
int
isr
;
isr
=
inb
(
host
->
base
+
WBSD_ISR
);
isr
=
inb
(
host
->
base
+
WBSD_ISR
);
...
@@ -1365,10 +1309,10 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs)
...
@@ -1365,10 +1309,10 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs)
* Allocate/free MMC structure.
* Allocate/free MMC structure.
*/
*/
static
int
__devinit
wbsd_alloc_mmc
(
struct
device
*
dev
)
static
int
__devinit
wbsd_alloc_mmc
(
struct
device
*
dev
)
{
{
struct
mmc_host
*
mmc
;
struct
mmc_host
*
mmc
;
struct
wbsd_host
*
host
;
struct
wbsd_host
*
host
;
/*
/*
* Allocate MMC structure.
* Allocate MMC structure.
...
@@ -1388,7 +1332,7 @@ static int __devinit wbsd_alloc_mmc(struct device* dev)
...
@@ -1388,7 +1332,7 @@ static int __devinit wbsd_alloc_mmc(struct device* dev)
mmc
->
ops
=
&
wbsd_ops
;
mmc
->
ops
=
&
wbsd_ops
;
mmc
->
f_min
=
375000
;
mmc
->
f_min
=
375000
;
mmc
->
f_max
=
24000000
;
mmc
->
f_max
=
24000000
;
mmc
->
ocr_avail
=
MMC_VDD_32_33
|
MMC_VDD_33_34
;
mmc
->
ocr_avail
=
MMC_VDD_32_33
|
MMC_VDD_33_34
;
mmc
->
caps
=
MMC_CAP_4_BIT_DATA
;
mmc
->
caps
=
MMC_CAP_4_BIT_DATA
;
spin_lock_init
(
&
host
->
lock
);
spin_lock_init
(
&
host
->
lock
);
...
@@ -1424,10 +1368,10 @@ static int __devinit wbsd_alloc_mmc(struct device* dev)
...
@@ -1424,10 +1368,10 @@ static int __devinit wbsd_alloc_mmc(struct device* dev)
return
0
;
return
0
;
}
}
static
void
__devexit
wbsd_free_mmc
(
struct
device
*
dev
)
static
void
__devexit
wbsd_free_mmc
(
struct
device
*
dev
)
{
{
struct
mmc_host
*
mmc
;
struct
mmc_host
*
mmc
;
struct
wbsd_host
*
host
;
struct
wbsd_host
*
host
;
mmc
=
dev_get_drvdata
(
dev
);
mmc
=
dev_get_drvdata
(
dev
);
if
(
!
mmc
)
if
(
!
mmc
)
...
@@ -1447,7 +1391,7 @@ static void __devexit wbsd_free_mmc(struct device* dev)
...
@@ -1447,7 +1391,7 @@ static void __devexit wbsd_free_mmc(struct device* dev)
* Scan for known chip id:s
* Scan for known chip id:s
*/
*/
static
int
__devinit
wbsd_scan
(
struct
wbsd_host
*
host
)
static
int
__devinit
wbsd_scan
(
struct
wbsd_host
*
host
)
{
{
int
i
,
j
,
k
;
int
i
,
j
,
k
;
int
id
;
int
id
;
...
@@ -1477,16 +1421,14 @@ static int __devinit wbsd_scan(struct wbsd_host* host)
...
@@ -1477,16 +1421,14 @@ static int __devinit wbsd_scan(struct wbsd_host* host)
wbsd_lock_config
(
host
);
wbsd_lock_config
(
host
);
for
(
k
=
0
;
k
<
ARRAY_SIZE
(
valid_ids
);
k
++
)
{
for
(
k
=
0
;
k
<
ARRAY_SIZE
(
valid_ids
);
k
++
)
{
if
(
id
==
valid_ids
[
k
])
if
(
id
==
valid_ids
[
k
])
{
{
host
->
chip_id
=
id
;
host
->
chip_id
=
id
;
return
0
;
return
0
;
}
}
}
}
if
(
id
!=
0xFFFF
)
if
(
id
!=
0xFFFF
)
{
{
DBG
(
"Unknown hardware (id %x) found at %x
\n
"
,
DBG
(
"Unknown hardware (id %x) found at %x
\n
"
,
id
,
config_ports
[
i
]);
id
,
config_ports
[
i
]);
}
}
...
@@ -1505,7 +1447,7 @@ static int __devinit wbsd_scan(struct wbsd_host* host)
...
@@ -1505,7 +1447,7 @@ static int __devinit wbsd_scan(struct wbsd_host* host)
* Allocate/free io port ranges
* Allocate/free io port ranges
*/
*/
static
int
__devinit
wbsd_request_region
(
struct
wbsd_host
*
host
,
int
base
)
static
int
__devinit
wbsd_request_region
(
struct
wbsd_host
*
host
,
int
base
)
{
{
if
(
io
&
0x7
)
if
(
io
&
0x7
)
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -1518,7 +1460,7 @@ static int __devinit wbsd_request_region(struct wbsd_host* host, int base)
...
@@ -1518,7 +1460,7 @@ static int __devinit wbsd_request_region(struct wbsd_host* host, int base)
return
0
;
return
0
;
}
}
static
void
__devexit
wbsd_release_regions
(
struct
wbsd_host
*
host
)
static
void
__devexit
wbsd_release_regions
(
struct
wbsd_host
*
host
)
{
{
if
(
host
->
base
)
if
(
host
->
base
)
release_region
(
host
->
base
,
8
);
release_region
(
host
->
base
,
8
);
...
@@ -1535,7 +1477,7 @@ static void __devexit wbsd_release_regions(struct wbsd_host* host)
...
@@ -1535,7 +1477,7 @@ static void __devexit wbsd_release_regions(struct wbsd_host* host)
* Allocate/free DMA port and buffer
* Allocate/free DMA port and buffer
*/
*/
static
void
__devinit
wbsd_request_dma
(
struct
wbsd_host
*
host
,
int
dma
)
static
void
__devinit
wbsd_request_dma
(
struct
wbsd_host
*
host
,
int
dma
)
{
{
if
(
dma
<
0
)
if
(
dma
<
0
)
return
;
return
;
...
@@ -1579,8 +1521,8 @@ static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma)
...
@@ -1579,8 +1521,8 @@ static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma)
*/
*/
BUG_ON
(
1
);
BUG_ON
(
1
);
dma_unmap_single
(
host
->
mmc
->
dev
,
host
->
dma_addr
,
WBSD_DMA_SIZE
,
dma_unmap_single
(
host
->
mmc
->
dev
,
host
->
dma_addr
,
DMA_BIDIRECTIONAL
);
WBSD_DMA_SIZE
,
DMA_BIDIRECTIONAL
);
host
->
dma_addr
=
(
dma_addr_t
)
NULL
;
host
->
dma_addr
=
(
dma_addr_t
)
NULL
;
kfree
(
host
->
dma_buffer
);
kfree
(
host
->
dma_buffer
);
...
@@ -1594,11 +1536,12 @@ static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma)
...
@@ -1594,11 +1536,12 @@ static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma)
"Falling back on FIFO.
\n
"
,
dma
);
"Falling back on FIFO.
\n
"
,
dma
);
}
}
static
void
__devexit
wbsd_release_dma
(
struct
wbsd_host
*
host
)
static
void
__devexit
wbsd_release_dma
(
struct
wbsd_host
*
host
)
{
{
if
(
host
->
dma_addr
)
if
(
host
->
dma_addr
)
{
dma_unmap_single
(
host
->
mmc
->
dev
,
host
->
dma_addr
,
WBSD_DMA_SIZE
,
dma_unmap_single
(
host
->
mmc
->
dev
,
host
->
dma_addr
,
DMA_BIDIRECTIONAL
);
WBSD_DMA_SIZE
,
DMA_BIDIRECTIONAL
);
}
kfree
(
host
->
dma_buffer
);
kfree
(
host
->
dma_buffer
);
if
(
host
->
dma
>=
0
)
if
(
host
->
dma
>=
0
)
free_dma
(
host
->
dma
);
free_dma
(
host
->
dma
);
...
@@ -1612,7 +1555,7 @@ static void __devexit wbsd_release_dma(struct wbsd_host* host)
...
@@ -1612,7 +1555,7 @@ static void __devexit wbsd_release_dma(struct wbsd_host* host)
* Allocate/free IRQ.
* Allocate/free IRQ.
*/
*/
static
int
__devinit
wbsd_request_irq
(
struct
wbsd_host
*
host
,
int
irq
)
static
int
__devinit
wbsd_request_irq
(
struct
wbsd_host
*
host
,
int
irq
)
{
{
int
ret
;
int
ret
;
...
@@ -1629,17 +1572,23 @@ static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq)
...
@@ -1629,17 +1572,23 @@ static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq)
/*
/*
* Set up tasklets.
* Set up tasklets.
*/
*/
tasklet_init
(
&
host
->
card_tasklet
,
wbsd_tasklet_card
,
(
unsigned
long
)
host
);
tasklet_init
(
&
host
->
card_tasklet
,
wbsd_tasklet_card
,
tasklet_init
(
&
host
->
fifo_tasklet
,
wbsd_tasklet_fifo
,
(
unsigned
long
)
host
);
(
unsigned
long
)
host
);
tasklet_init
(
&
host
->
crc_tasklet
,
wbsd_tasklet_crc
,
(
unsigned
long
)
host
);
tasklet_init
(
&
host
->
fifo_tasklet
,
wbsd_tasklet_fifo
,
tasklet_init
(
&
host
->
timeout_tasklet
,
wbsd_tasklet_timeout
,
(
unsigned
long
)
host
);
(
unsigned
long
)
host
);
tasklet_init
(
&
host
->
finish_tasklet
,
wbsd_tasklet_finish
,
(
unsigned
long
)
host
);
tasklet_init
(
&
host
->
crc_tasklet
,
wbsd_tasklet_crc
,
tasklet_init
(
&
host
->
block_tasklet
,
wbsd_tasklet_block
,
(
unsigned
long
)
host
);
(
unsigned
long
)
host
);
tasklet_init
(
&
host
->
timeout_tasklet
,
wbsd_tasklet_timeout
,
(
unsigned
long
)
host
);
tasklet_init
(
&
host
->
finish_tasklet
,
wbsd_tasklet_finish
,
(
unsigned
long
)
host
);
tasklet_init
(
&
host
->
block_tasklet
,
wbsd_tasklet_block
,
(
unsigned
long
)
host
);
return
0
;
return
0
;
}
}
static
void
__devexit
wbsd_release_irq
(
struct
wbsd_host
*
host
)
static
void
__devexit
wbsd_release_irq
(
struct
wbsd_host
*
host
)
{
{
if
(
!
host
->
irq
)
if
(
!
host
->
irq
)
return
;
return
;
...
@@ -1660,7 +1609,7 @@ static void __devexit wbsd_release_irq(struct wbsd_host* host)
...
@@ -1660,7 +1609,7 @@ static void __devexit wbsd_release_irq(struct wbsd_host* host)
* Allocate all resources for the host.
* Allocate all resources for the host.
*/
*/
static
int
__devinit
wbsd_request_resources
(
struct
wbsd_host
*
host
,
static
int
__devinit
wbsd_request_resources
(
struct
wbsd_host
*
host
,
int
base
,
int
irq
,
int
dma
)
int
base
,
int
irq
,
int
dma
)
{
{
int
ret
;
int
ret
;
...
@@ -1691,7 +1640,7 @@ static int __devinit wbsd_request_resources(struct wbsd_host* host,
...
@@ -1691,7 +1640,7 @@ static int __devinit wbsd_request_resources(struct wbsd_host* host,
* Release all resources for the host.
* Release all resources for the host.
*/
*/
static
void
__devexit
wbsd_release_resources
(
struct
wbsd_host
*
host
)
static
void
__devexit
wbsd_release_resources
(
struct
wbsd_host
*
host
)
{
{
wbsd_release_dma
(
host
);
wbsd_release_dma
(
host
);
wbsd_release_irq
(
host
);
wbsd_release_irq
(
host
);
...
@@ -1702,7 +1651,7 @@ static void __devexit wbsd_release_resources(struct wbsd_host* host)
...
@@ -1702,7 +1651,7 @@ static void __devexit wbsd_release_resources(struct wbsd_host* host)
* Configure the resources the chip should use.
* Configure the resources the chip should use.
*/
*/
static
void
wbsd_chip_config
(
struct
wbsd_host
*
host
)
static
void
wbsd_chip_config
(
struct
wbsd_host
*
host
)
{
{
wbsd_unlock_config
(
host
);
wbsd_unlock_config
(
host
);
...
@@ -1746,7 +1695,7 @@ static void wbsd_chip_config(struct wbsd_host* host)
...
@@ -1746,7 +1695,7 @@ static void wbsd_chip_config(struct wbsd_host* host)
* Check that configured resources are correct.
* Check that configured resources are correct.
*/
*/
static
int
wbsd_chip_validate
(
struct
wbsd_host
*
host
)
static
int
wbsd_chip_validate
(
struct
wbsd_host
*
host
)
{
{
int
base
,
irq
,
dma
;
int
base
,
irq
,
dma
;
...
@@ -1786,7 +1735,7 @@ static int wbsd_chip_validate(struct wbsd_host* host)
...
@@ -1786,7 +1735,7 @@ static int wbsd_chip_validate(struct wbsd_host* host)
* Powers down the SD function
* Powers down the SD function
*/
*/
static
void
wbsd_chip_poweroff
(
struct
wbsd_host
*
host
)
static
void
wbsd_chip_poweroff
(
struct
wbsd_host
*
host
)
{
{
wbsd_unlock_config
(
host
);
wbsd_unlock_config
(
host
);
...
@@ -1802,11 +1751,11 @@ static void wbsd_chip_poweroff(struct wbsd_host* host)
...
@@ -1802,11 +1751,11 @@ static void wbsd_chip_poweroff(struct wbsd_host* host)
* *
* *
\*****************************************************************************/
\*****************************************************************************/
static
int
__devinit
wbsd_init
(
struct
device
*
dev
,
int
base
,
int
irq
,
int
dma
,
static
int
__devinit
wbsd_init
(
struct
device
*
dev
,
int
base
,
int
irq
,
int
dma
,
int
pnp
)
int
pnp
)
{
{
struct
wbsd_host
*
host
=
NULL
;
struct
wbsd_host
*
host
=
NULL
;
struct
mmc_host
*
mmc
=
NULL
;
struct
mmc_host
*
mmc
=
NULL
;
int
ret
;
int
ret
;
ret
=
wbsd_alloc_mmc
(
dev
);
ret
=
wbsd_alloc_mmc
(
dev
);
...
@@ -1820,16 +1769,12 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
...
@@ -1820,16 +1769,12 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
* Scan for hardware.
* Scan for hardware.
*/
*/
ret
=
wbsd_scan
(
host
);
ret
=
wbsd_scan
(
host
);
if
(
ret
)
if
(
ret
)
{
{
if
(
pnp
&&
(
ret
==
-
ENODEV
))
{
if
(
pnp
&&
(
ret
==
-
ENODEV
))
{
printk
(
KERN_WARNING
DRIVER_NAME
printk
(
KERN_WARNING
DRIVER_NAME
": Unable to confirm device presence. You may "
": Unable to confirm device presence. You may "
"experience lock-ups.
\n
"
);
"experience lock-ups.
\n
"
);
}
}
else
{
else
{
wbsd_free_mmc
(
dev
);
wbsd_free_mmc
(
dev
);
return
ret
;
return
ret
;
}
}
...
@@ -1839,8 +1784,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
...
@@ -1839,8 +1784,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
* Request resources.
* Request resources.
*/
*/
ret
=
wbsd_request_resources
(
host
,
io
,
irq
,
dma
);
ret
=
wbsd_request_resources
(
host
,
io
,
irq
,
dma
);
if
(
ret
)
if
(
ret
)
{
{
wbsd_release_resources
(
host
);
wbsd_release_resources
(
host
);
wbsd_free_mmc
(
dev
);
wbsd_free_mmc
(
dev
);
return
ret
;
return
ret
;
...
@@ -1849,18 +1793,15 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
...
@@ -1849,18 +1793,15 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
/*
/*
* See if chip needs to be configured.
* See if chip needs to be configured.
*/
*/
if
(
pnp
)
if
(
pnp
)
{
{
if
((
host
->
config
!=
0
)
&&
!
wbsd_chip_validate
(
host
))
{
if
((
host
->
config
!=
0
)
&&
!
wbsd_chip_validate
(
host
))
{
printk
(
KERN_WARNING
DRIVER_NAME
printk
(
KERN_WARNING
DRIVER_NAME
": PnP active but chip not configured! "
": PnP active but chip not configured! "
"You probably have a buggy BIOS. "
"You probably have a buggy BIOS. "
"Configuring chip manually.
\n
"
);
"Configuring chip manually.
\n
"
);
wbsd_chip_config
(
host
);
wbsd_chip_config
(
host
);
}
}
}
}
else
else
wbsd_chip_config
(
host
);
wbsd_chip_config
(
host
);
/*
/*
...
@@ -1868,8 +1809,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
...
@@ -1868,8 +1809,7 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
* Not tested.
* Not tested.
*/
*/
#ifdef CONFIG_PM
#ifdef CONFIG_PM
if
(
host
->
config
)
if
(
host
->
config
)
{
{
wbsd_unlock_config
(
host
);
wbsd_unlock_config
(
host
);
wbsd_write_config
(
host
,
WBSD_CONF_PME
,
0xA0
);
wbsd_write_config
(
host
,
WBSD_CONF_PME
,
0xA0
);
wbsd_lock_config
(
host
);
wbsd_lock_config
(
host
);
...
@@ -1902,10 +1842,10 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
...
@@ -1902,10 +1842,10 @@ static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma,
return
0
;
return
0
;
}
}
static
void
__devexit
wbsd_shutdown
(
struct
device
*
dev
,
int
pnp
)
static
void
__devexit
wbsd_shutdown
(
struct
device
*
dev
,
int
pnp
)
{
{
struct
mmc_host
*
mmc
=
dev_get_drvdata
(
dev
);
struct
mmc_host
*
mmc
=
dev_get_drvdata
(
dev
);
struct
wbsd_host
*
host
;
struct
wbsd_host
*
host
;
if
(
!
mmc
)
if
(
!
mmc
)
return
;
return
;
...
@@ -1929,12 +1869,12 @@ static void __devexit wbsd_shutdown(struct device* dev, int pnp)
...
@@ -1929,12 +1869,12 @@ static void __devexit wbsd_shutdown(struct device* dev, int pnp)
* Non-PnP
* Non-PnP
*/
*/
static
int
__devinit
wbsd_probe
(
struct
platform_device
*
dev
)
static
int
__devinit
wbsd_probe
(
struct
platform_device
*
dev
)
{
{
return
wbsd_init
(
&
dev
->
dev
,
io
,
irq
,
dma
,
0
);
return
wbsd_init
(
&
dev
->
dev
,
io
,
irq
,
dma
,
0
);
}
}
static
int
__devexit
wbsd_remove
(
struct
platform_device
*
dev
)
static
int
__devexit
wbsd_remove
(
struct
platform_device
*
dev
)
{
{
wbsd_shutdown
(
&
dev
->
dev
,
0
);
wbsd_shutdown
(
&
dev
->
dev
,
0
);
...
@@ -1948,7 +1888,7 @@ static int __devexit wbsd_remove(struct platform_device* dev)
...
@@ -1948,7 +1888,7 @@ static int __devexit wbsd_remove(struct platform_device* dev)
#ifdef CONFIG_PNP
#ifdef CONFIG_PNP
static
int
__devinit
static
int
__devinit
wbsd_pnp_probe
(
struct
pnp_dev
*
pnpdev
,
const
struct
pnp_device_id
*
dev_id
)
wbsd_pnp_probe
(
struct
pnp_dev
*
pnpdev
,
const
struct
pnp_device_id
*
dev_id
)
{
{
int
io
,
irq
,
dma
;
int
io
,
irq
,
dma
;
...
@@ -1967,7 +1907,7 @@ wbsd_pnp_probe(struct pnp_dev * pnpdev, const struct pnp_device_id *dev_id)
...
@@ -1967,7 +1907,7 @@ wbsd_pnp_probe(struct pnp_dev * pnpdev, const struct pnp_device_id *dev_id)
return
wbsd_init
(
&
pnpdev
->
dev
,
io
,
irq
,
dma
,
1
);
return
wbsd_init
(
&
pnpdev
->
dev
,
io
,
irq
,
dma
,
1
);
}
}
static
void
__devexit
wbsd_pnp_remove
(
struct
pnp_dev
*
dev
)
static
void
__devexit
wbsd_pnp_remove
(
struct
pnp_dev
*
dev
)
{
{
wbsd_shutdown
(
&
dev
->
dev
,
1
);
wbsd_shutdown
(
&
dev
->
dev
,
1
);
}
}
...
@@ -1980,37 +1920,54 @@ static void __devexit wbsd_pnp_remove(struct pnp_dev * dev)
...
@@ -1980,37 +1920,54 @@ static void __devexit wbsd_pnp_remove(struct pnp_dev * dev)
#ifdef CONFIG_PM
#ifdef CONFIG_PM
static
int
wbsd_suspend
(
struct
platform_device
*
dev
,
pm_message_t
state
)
static
int
wbsd_suspend
(
struct
wbsd_host
*
host
,
pm_message_t
state
)
{
BUG_ON
(
host
==
NULL
);
return
mmc_suspend_host
(
host
->
mmc
,
state
);
}
static
int
wbsd_resume
(
struct
wbsd_host
*
host
)
{
BUG_ON
(
host
==
NULL
);
wbsd_init_device
(
host
);
return
mmc_resume_host
(
host
->
mmc
);
}
static
int
wbsd_platform_suspend
(
struct
platform_device
*
dev
,
pm_message_t
state
)
{
{
struct
mmc_host
*
mmc
=
platform_get_drvdata
(
dev
);
struct
mmc_host
*
mmc
=
platform_get_drvdata
(
dev
);
struct
wbsd_host
*
host
;
struct
wbsd_host
*
host
;
int
ret
;
int
ret
;
if
(
!
mmc
)
if
(
mmc
==
NULL
)
return
0
;
return
0
;
DBG
(
"Suspending...
\n
"
);
DBGF
(
"Suspending...
\n
"
);
ret
=
mmc_suspend_host
(
mmc
,
state
);
if
(
!
ret
)
return
ret
;
host
=
mmc_priv
(
mmc
);
host
=
mmc_priv
(
mmc
);
ret
=
wbsd_suspend
(
host
,
state
);
if
(
ret
)
return
ret
;
wbsd_chip_poweroff
(
host
);
wbsd_chip_poweroff
(
host
);
return
0
;
return
0
;
}
}
static
int
wbsd_resume
(
struct
platform_device
*
dev
)
static
int
wbsd_
platform_
resume
(
struct
platform_device
*
dev
)
{
{
struct
mmc_host
*
mmc
=
platform_get_drvdata
(
dev
);
struct
mmc_host
*
mmc
=
platform_get_drvdata
(
dev
);
struct
wbsd_host
*
host
;
struct
wbsd_host
*
host
;
if
(
!
mmc
)
if
(
mmc
==
NULL
)
return
0
;
return
0
;
DBG
(
"Resuming...
\n
"
);
DBG
F
(
"Resuming...
\n
"
);
host
=
mmc_priv
(
mmc
);
host
=
mmc_priv
(
mmc
);
...
@@ -2021,15 +1978,68 @@ static int wbsd_resume(struct platform_device *dev)
...
@@ -2021,15 +1978,68 @@ static int wbsd_resume(struct platform_device *dev)
*/
*/
mdelay
(
5
);
mdelay
(
5
);
wbsd_init_device
(
host
);
return
wbsd_resume
(
host
);
}
#ifdef CONFIG_PNP
static
int
wbsd_pnp_suspend
(
struct
pnp_dev
*
pnp_dev
,
pm_message_t
state
)
{
struct
mmc_host
*
mmc
=
dev_get_drvdata
(
&
pnp_dev
->
dev
);
struct
wbsd_host
*
host
;
if
(
mmc
==
NULL
)
return
0
;
DBGF
(
"Suspending...
\n
"
);
host
=
mmc_priv
(
mmc
);
return
wbsd_suspend
(
host
,
state
);
}
static
int
wbsd_pnp_resume
(
struct
pnp_dev
*
pnp_dev
)
{
struct
mmc_host
*
mmc
=
dev_get_drvdata
(
&
pnp_dev
->
dev
);
struct
wbsd_host
*
host
;
if
(
mmc
==
NULL
)
return
0
;
DBGF
(
"Resuming...
\n
"
);
return
mmc_resume_host
(
mmc
);
host
=
mmc_priv
(
mmc
);
/*
* See if chip needs to be configured.
*/
if
(
host
->
config
!=
0
)
{
if
(
!
wbsd_chip_validate
(
host
))
{
printk
(
KERN_WARNING
DRIVER_NAME
": PnP active but chip not configured! "
"You probably have a buggy BIOS. "
"Configuring chip manually.
\n
"
);
wbsd_chip_config
(
host
);
}
}
/*
* Allow device to initialise itself properly.
*/
mdelay
(
5
);
return
wbsd_resume
(
host
);
}
}
#endif
/* CONFIG_PNP */
#else
/* CONFIG_PM */
#else
/* CONFIG_PM */
#define wbsd_suspend NULL
#define wbsd_platform_suspend NULL
#define wbsd_resume NULL
#define wbsd_platform_resume NULL
#define wbsd_pnp_suspend NULL
#define wbsd_pnp_resume NULL
#endif
/* CONFIG_PM */
#endif
/* CONFIG_PM */
...
@@ -2039,8 +2049,8 @@ static struct platform_driver wbsd_driver = {
...
@@ -2039,8 +2049,8 @@ static struct platform_driver wbsd_driver = {
.
probe
=
wbsd_probe
,
.
probe
=
wbsd_probe
,
.
remove
=
__devexit_p
(
wbsd_remove
),
.
remove
=
__devexit_p
(
wbsd_remove
),
.
suspend
=
wbsd_suspend
,
.
suspend
=
wbsd_
platform_
suspend
,
.
resume
=
wbsd_resume
,
.
resume
=
wbsd_
platform_
resume
,
.
driver
=
{
.
driver
=
{
.
name
=
DRIVER_NAME
,
.
name
=
DRIVER_NAME
,
},
},
...
@@ -2053,6 +2063,9 @@ static struct pnp_driver wbsd_pnp_driver = {
...
@@ -2053,6 +2063,9 @@ static struct pnp_driver wbsd_pnp_driver = {
.
id_table
=
pnp_dev_table
,
.
id_table
=
pnp_dev_table
,
.
probe
=
wbsd_pnp_probe
,
.
probe
=
wbsd_pnp_probe
,
.
remove
=
__devexit_p
(
wbsd_pnp_remove
),
.
remove
=
__devexit_p
(
wbsd_pnp_remove
),
.
suspend
=
wbsd_pnp_suspend
,
.
resume
=
wbsd_pnp_resume
,
};
};
#endif
/* CONFIG_PNP */
#endif
/* CONFIG_PNP */
...
@@ -2072,31 +2085,26 @@ static int __init wbsd_drv_init(void)
...
@@ -2072,31 +2085,26 @@ static int __init wbsd_drv_init(void)
#ifdef CONFIG_PNP
#ifdef CONFIG_PNP
if
(
!
nopnp
)
if
(
!
nopnp
)
{
{
result
=
pnp_register_driver
(
&
wbsd_pnp_driver
);
result
=
pnp_register_driver
(
&
wbsd_pnp_driver
);
if
(
result
<
0
)
if
(
result
<
0
)
return
result
;
return
result
;
}
}
#endif
/* CONFIG_PNP */
#endif
/* CONFIG_PNP */
if
(
nopnp
)
if
(
nopnp
)
{
{
result
=
platform_driver_register
(
&
wbsd_driver
);
result
=
platform_driver_register
(
&
wbsd_driver
);
if
(
result
<
0
)
if
(
result
<
0
)
return
result
;
return
result
;
wbsd_device
=
platform_device_alloc
(
DRIVER_NAME
,
-
1
);
wbsd_device
=
platform_device_alloc
(
DRIVER_NAME
,
-
1
);
if
(
!
wbsd_device
)
if
(
!
wbsd_device
)
{
{
platform_driver_unregister
(
&
wbsd_driver
);
platform_driver_unregister
(
&
wbsd_driver
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
result
=
platform_device_add
(
wbsd_device
);
result
=
platform_device_add
(
wbsd_device
);
if
(
result
)
if
(
result
)
{
{
platform_device_put
(
wbsd_device
);
platform_device_put
(
wbsd_device
);
platform_driver_unregister
(
&
wbsd_driver
);
platform_driver_unregister
(
&
wbsd_driver
);
return
result
;
return
result
;
...
@@ -2115,8 +2123,7 @@ static void __exit wbsd_drv_exit(void)
...
@@ -2115,8 +2123,7 @@ static void __exit wbsd_drv_exit(void)
#endif
/* CONFIG_PNP */
#endif
/* CONFIG_PNP */
if
(
nopnp
)
if
(
nopnp
)
{
{
platform_device_unregister
(
wbsd_device
);
platform_device_unregister
(
wbsd_device
);
platform_driver_unregister
(
&
wbsd_driver
);
platform_driver_unregister
(
&
wbsd_driver
);
...
...
include/linux/mmc/mmc.h
View file @
8e9c238c
...
@@ -27,14 +27,15 @@ struct mmc_command {
...
@@ -27,14 +27,15 @@ struct mmc_command {
#define MMC_RSP_MASK (3 << 0)
#define MMC_RSP_MASK (3 << 0)
#define MMC_RSP_CRC (1 << 3)
/* expect valid crc */
#define MMC_RSP_CRC (1 << 3)
/* expect valid crc */
#define MMC_RSP_BUSY (1 << 4)
/* card may send busy */
#define MMC_RSP_BUSY (1 << 4)
/* card may send busy */
#define MMC_RSP_OPCODE (1 << 5)
/* response contains opcode */
/*
/*
* These are the response types, and correspond to valid bit
* These are the response types, and correspond to valid bit
* patterns of the above flags. One additional valid pattern
* patterns of the above flags. One additional valid pattern
* is all zeros, which means we don't expect a response.
* is all zeros, which means we don't expect a response.
*/
*/
#define MMC_RSP_R1 (MMC_RSP_SHORT|MMC_RSP_CRC)
#define MMC_RSP_R1 (MMC_RSP_SHORT|MMC_RSP_CRC
|MMC_RSP_OPCODE
)
#define MMC_RSP_R1B (MMC_RSP_SHORT|MMC_RSP_CRC|MMC_RSP_BUSY)
#define MMC_RSP_R1B (MMC_RSP_SHORT|MMC_RSP_CRC|MMC_RSP_
OPCODE|MMC_RSP_
BUSY)
#define MMC_RSP_R2 (MMC_RSP_LONG|MMC_RSP_CRC)
#define MMC_RSP_R2 (MMC_RSP_LONG|MMC_RSP_CRC)
#define MMC_RSP_R3 (MMC_RSP_SHORT)
#define MMC_RSP_R3 (MMC_RSP_SHORT)
#define MMC_RSP_R6 (MMC_RSP_SHORT|MMC_RSP_CRC)
#define MMC_RSP_R6 (MMC_RSP_SHORT|MMC_RSP_CRC)
...
@@ -64,6 +65,7 @@ struct mmc_data {
...
@@ -64,6 +65,7 @@ struct mmc_data {
#define MMC_DATA_WRITE (1 << 8)
#define MMC_DATA_WRITE (1 << 8)
#define MMC_DATA_READ (1 << 9)
#define MMC_DATA_READ (1 << 9)
#define MMC_DATA_STREAM (1 << 10)
#define MMC_DATA_STREAM (1 << 10)
#define MMC_DATA_MULTI (1 << 11)
unsigned
int
bytes_xfered
;
unsigned
int
bytes_xfered
;
...
...
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