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
6e58ddeb
Commit
6e58ddeb
authored
Sep 18, 2004
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://bk.arm.linux.org.uk/linux-2.6-mmc
into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents
6e544044
201ee40f
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
143 additions
and
61 deletions
+143
-61
drivers/mmc/mmc.c
drivers/mmc/mmc.c
+110
-47
drivers/mmc/mmc_sysfs.c
drivers/mmc/mmc_sysfs.c
+18
-8
include/linux/mmc/card.h
include/linux/mmc/card.h
+15
-6
No files found.
drivers/mmc/mmc.c
View file @
6e58ddeb
...
...
@@ -300,58 +300,121 @@ static u32 mmc_select_voltage(struct mmc_host *host, u32 ocr)
return
ocr
;
}
static
void
mmc_decode_cid
(
struct
mmc_cid
*
cid
,
u32
*
resp
)
#define UNSTUFF_BITS(resp,start,size) \
({ \
const u32 __mask = (1 << (size)) - 1; \
const int __off = 3 - ((start) / 32); \
const int __shft = (start) & 31; \
u32 __res; \
\
__res = resp[__off] >> __shft; \
if ((size) + __shft >= 32) \
__res |= resp[__off-1] << (32 - __shft); \
__res & __mask; \
})
/*
* Given the decoded CSD structure, decode the raw CID to our CID structure.
*/
static
void
mmc_decode_cid
(
struct
mmc_card
*
card
)
{
memset
(
cid
,
0
,
sizeof
(
struct
mmc_cid
));
cid
->
manfid
=
resp
[
0
]
>>
8
;
cid
->
prod_name
[
0
]
=
resp
[
0
];
cid
->
prod_name
[
1
]
=
resp
[
1
]
>>
24
;
cid
->
prod_name
[
2
]
=
resp
[
1
]
>>
16
;
cid
->
prod_name
[
3
]
=
resp
[
1
]
>>
8
;
cid
->
prod_name
[
4
]
=
resp
[
1
];
cid
->
prod_name
[
5
]
=
resp
[
2
]
>>
24
;
cid
->
prod_name
[
6
]
=
resp
[
2
]
>>
16
;
cid
->
prod_name
[
7
]
=
'\0'
;
cid
->
hwrev
=
(
resp
[
2
]
>>
12
)
&
15
;
cid
->
fwrev
=
(
resp
[
2
]
>>
8
)
&
15
;
cid
->
serial
=
(
resp
[
2
]
&
255
)
<<
16
|
(
resp
[
3
]
>>
16
);
cid
->
month
=
(
resp
[
3
]
>>
12
)
&
15
;
cid
->
year
=
(
resp
[
3
]
>>
8
)
&
15
;
u32
*
resp
=
card
->
raw_cid
;
memset
(
&
card
->
cid
,
0
,
sizeof
(
struct
mmc_cid
));
/*
* The selection of the format here is guesswork based upon
* information people have sent to date.
*/
switch
(
card
->
csd
.
mmca_vsn
)
{
case
0
:
/* MMC v1.? */
case
1
:
/* MMC v1.4 */
card
->
cid
.
manfid
=
UNSTUFF_BITS
(
resp
,
104
,
24
);
card
->
cid
.
prod_name
[
0
]
=
UNSTUFF_BITS
(
resp
,
96
,
8
);
card
->
cid
.
prod_name
[
1
]
=
UNSTUFF_BITS
(
resp
,
88
,
8
);
card
->
cid
.
prod_name
[
2
]
=
UNSTUFF_BITS
(
resp
,
80
,
8
);
card
->
cid
.
prod_name
[
3
]
=
UNSTUFF_BITS
(
resp
,
72
,
8
);
card
->
cid
.
prod_name
[
4
]
=
UNSTUFF_BITS
(
resp
,
64
,
8
);
card
->
cid
.
prod_name
[
5
]
=
UNSTUFF_BITS
(
resp
,
56
,
8
);
card
->
cid
.
prod_name
[
6
]
=
UNSTUFF_BITS
(
resp
,
48
,
8
);
card
->
cid
.
hwrev
=
UNSTUFF_BITS
(
resp
,
44
,
4
);
card
->
cid
.
fwrev
=
UNSTUFF_BITS
(
resp
,
40
,
4
);
card
->
cid
.
serial
=
UNSTUFF_BITS
(
resp
,
16
,
24
);
card
->
cid
.
month
=
UNSTUFF_BITS
(
resp
,
12
,
4
);
card
->
cid
.
year
=
UNSTUFF_BITS
(
resp
,
8
,
4
)
+
1997
;
break
;
case
2
:
/* MMC v2.x ? */
case
3
:
/* MMC v3.x ? */
card
->
cid
.
manfid
=
UNSTUFF_BITS
(
resp
,
120
,
8
);
card
->
cid
.
oemid
=
UNSTUFF_BITS
(
resp
,
104
,
16
);
card
->
cid
.
prod_name
[
0
]
=
UNSTUFF_BITS
(
resp
,
96
,
8
);
card
->
cid
.
prod_name
[
1
]
=
UNSTUFF_BITS
(
resp
,
88
,
8
);
card
->
cid
.
prod_name
[
2
]
=
UNSTUFF_BITS
(
resp
,
80
,
8
);
card
->
cid
.
prod_name
[
3
]
=
UNSTUFF_BITS
(
resp
,
72
,
8
);
card
->
cid
.
prod_name
[
4
]
=
UNSTUFF_BITS
(
resp
,
64
,
8
);
card
->
cid
.
prod_name
[
5
]
=
UNSTUFF_BITS
(
resp
,
56
,
8
);
card
->
cid
.
serial
=
UNSTUFF_BITS
(
resp
,
16
,
32
);
card
->
cid
.
month
=
UNSTUFF_BITS
(
resp
,
12
,
4
);
card
->
cid
.
year
=
UNSTUFF_BITS
(
resp
,
8
,
4
)
+
1997
;
break
;
default:
printk
(
"%s: card has unknown MMCA version %d
\n
"
,
card
->
host
->
host_name
,
card
->
csd
.
mmca_vsn
);
mmc_card_set_bad
(
card
);
break
;
}
}
static
void
mmc_decode_csd
(
struct
mmc_csd
*
csd
,
u32
*
resp
)
/*
* Given a 128-bit response, decode to our card CSD structure.
*/
static
void
mmc_decode_csd
(
struct
mmc_card
*
card
)
{
unsigned
int
e
,
m
;
struct
mmc_csd
*
csd
=
&
card
->
csd
;
unsigned
int
e
,
m
,
csd_struct
;
u32
*
resp
=
card
->
raw_csd
;
csd
->
mmc_prot
=
(
resp
[
0
]
>>
26
)
&
15
;
m
=
(
resp
[
0
]
>>
19
)
&
15
;
e
=
(
resp
[
0
]
>>
16
)
&
7
;
/*
* We only understand CSD structure v1.1 and v2.
* v2 has extra information in bits 15, 11 and 10.
*/
csd_struct
=
UNSTUFF_BITS
(
resp
,
126
,
2
);
if
(
csd_struct
!=
1
&&
csd_struct
!=
2
)
{
printk
(
"%s: unrecognised CSD structure version %d
\n
"
,
card
->
host
->
host_name
,
csd_struct
);
mmc_card_set_bad
(
card
);
return
;
}
csd
->
mmca_vsn
=
UNSTUFF_BITS
(
resp
,
122
,
4
);
m
=
UNSTUFF_BITS
(
resp
,
115
,
4
);
e
=
UNSTUFF_BITS
(
resp
,
112
,
3
);
csd
->
tacc_ns
=
(
tacc_exp
[
e
]
*
tacc_mant
[
m
]
+
9
)
/
10
;
csd
->
tacc_clks
=
((
resp
[
0
]
>>
8
)
&
255
)
*
100
;
csd
->
tacc_clks
=
UNSTUFF_BITS
(
resp
,
104
,
8
)
*
100
;
m
=
(
resp
[
0
]
>>
3
)
&
15
;
e
=
resp
[
0
]
&
7
;
m
=
UNSTUFF_BITS
(
resp
,
99
,
4
)
;
e
=
UNSTUFF_BITS
(
resp
,
96
,
3
)
;
csd
->
max_dtr
=
tran_exp
[
e
]
*
tran_mant
[
m
];
csd
->
cmdclass
=
(
resp
[
1
]
>>
20
)
&
0xfff
;
csd
->
cmdclass
=
UNSTUFF_BITS
(
resp
,
84
,
12
)
;
e
=
(
resp
[
2
]
>>
15
)
&
7
;
m
=
(
resp
[
1
]
<<
2
|
resp
[
2
]
>>
30
)
&
0x3fff
;
e
=
UNSTUFF_BITS
(
resp
,
47
,
3
)
;
m
=
UNSTUFF_BITS
(
resp
,
62
,
12
)
;
csd
->
capacity
=
(
1
+
m
)
<<
(
e
+
2
);
csd
->
read_blkbits
=
(
resp
[
1
]
>>
16
)
&
15
;
csd
->
read_blkbits
=
UNSTUFF_BITS
(
resp
,
80
,
4
)
;
}
/*
* Locate a MMC card on this MMC host given a CID.
* Locate a MMC card on this MMC host given a
raw
CID.
*/
static
struct
mmc_card
*
mmc_find_card
(
struct
mmc_host
*
host
,
struct
mmc_cid
*
cid
)
static
struct
mmc_card
*
mmc_find_card
(
struct
mmc_host
*
host
,
u32
*
raw_cid
)
{
struct
mmc_card
*
card
;
list_for_each_entry
(
card
,
&
host
->
cards
,
node
)
{
if
(
memcmp
(
&
card
->
cid
,
cid
,
sizeof
(
struct
mmc
_cid
))
==
0
)
if
(
memcmp
(
card
->
raw_cid
,
raw_cid
,
sizeof
(
card
->
raw
_cid
))
==
0
)
return
card
;
}
return
NULL
;
...
...
@@ -361,7 +424,7 @@ mmc_find_card(struct mmc_host *host, struct mmc_cid *cid)
* Allocate a new MMC card, and assign a unique RCA.
*/
static
struct
mmc_card
*
mmc_alloc_card
(
struct
mmc_host
*
host
,
struct
mmc_cid
*
cid
,
unsigned
int
*
frca
)
mmc_alloc_card
(
struct
mmc_host
*
host
,
u32
*
raw_
cid
,
unsigned
int
*
frca
)
{
struct
mmc_card
*
card
,
*
c
;
unsigned
int
rca
=
*
frca
;
...
...
@@ -371,7 +434,7 @@ mmc_alloc_card(struct mmc_host *host, struct mmc_cid *cid, unsigned int *frca)
return
ERR_PTR
(
-
ENOMEM
);
mmc_init_card
(
card
,
host
);
memcpy
(
&
card
->
cid
,
cid
,
sizeof
(
struct
mmc
_cid
));
memcpy
(
card
->
raw_cid
,
raw_cid
,
sizeof
(
card
->
raw
_cid
));
again:
list_for_each_entry
(
c
,
&
host
->
cards
,
node
)
...
...
@@ -456,7 +519,7 @@ static int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
* to be discovered. Add new cards to the list.
*
* Create a mmc_card entry for each discovered card, assigning
* it an RCA, and save the
CID
.
* it an RCA, and save the
raw CID for decoding later
.
*/
static
void
mmc_discover_cards
(
struct
mmc_host
*
host
)
{
...
...
@@ -465,7 +528,6 @@ static void mmc_discover_cards(struct mmc_host *host)
while
(
1
)
{
struct
mmc_command
cmd
;
struct
mmc_cid
cid
;
cmd
.
opcode
=
MMC_ALL_SEND_CID
;
cmd
.
arg
=
0
;
...
...
@@ -482,11 +544,9 @@ static void mmc_discover_cards(struct mmc_host *host)
break
;
}
mmc_decode_cid
(
&
cid
,
cmd
.
resp
);
card
=
mmc_find_card
(
host
,
&
cid
);
card
=
mmc_find_card
(
host
,
cmd
.
resp
);
if
(
!
card
)
{
card
=
mmc_alloc_card
(
host
,
&
cid
,
&
first_rca
);
card
=
mmc_alloc_card
(
host
,
cmd
.
resp
,
&
first_rca
);
if
(
IS_ERR
(
card
))
{
err
=
PTR_ERR
(
card
);
break
;
...
...
@@ -502,7 +562,7 @@ static void mmc_discover_cards(struct mmc_host *host)
err
=
mmc_wait_for_cmd
(
host
,
&
cmd
,
CMD_RETRIES
);
if
(
err
!=
MMC_ERR_NONE
)
card
->
state
|=
MMC_STATE_DEAD
;
mmc_card_set_dead
(
card
)
;
}
}
...
...
@@ -523,11 +583,14 @@ static void mmc_read_csds(struct mmc_host *host)
err
=
mmc_wait_for_cmd
(
host
,
&
cmd
,
CMD_RETRIES
);
if
(
err
!=
MMC_ERR_NONE
)
{
card
->
state
|=
MMC_STATE_DEAD
;
mmc_card_set_dead
(
card
)
;
continue
;
}
mmc_decode_csd
(
&
card
->
csd
,
cmd
.
resp
);
memcpy
(
card
->
raw_csd
,
cmd
.
resp
,
sizeof
(
card
->
raw_csd
));
mmc_decode_csd
(
card
);
mmc_decode_cid
(
card
);
}
}
...
...
@@ -573,7 +636,7 @@ static void mmc_check_cards(struct mmc_host *host)
if
(
err
==
MMC_ERR_NONE
)
continue
;
card
->
state
|=
MMC_STATE_DEAD
;
mmc_card_set_dead
(
card
)
;
}
}
...
...
@@ -678,9 +741,9 @@ static void mmc_rescan(void *data)
*/
if
(
!
mmc_card_present
(
card
)
&&
!
mmc_card_dead
(
card
))
{
if
(
mmc_register_card
(
card
))
card
->
state
|=
MMC_STATE_DEAD
;
mmc_card_set_dead
(
card
)
;
else
card
->
state
|=
MMC_STATE_PRESENT
;
mmc_card_set_present
(
card
)
;
}
/*
...
...
drivers/mmc/mmc_sysfs.c
View file @
6e58ddeb
...
...
@@ -31,11 +31,12 @@ static void mmc_release_card(struct device *dev)
/*
* This currently matches any MMC driver to any MMC card - drivers
* themselves make the decision whether to drive this card in their
* probe method.
* probe method.
However, we force "bad" cards to fail.
*/
static
int
mmc_bus_match
(
struct
device
*
dev
,
struct
device_driver
*
drv
)
{
return
1
;
struct
mmc_card
*
card
=
dev_to_mmc_card
(
dev
);
return
!
mmc_card_bad
(
card
);
}
static
int
...
...
@@ -66,8 +67,9 @@ mmc_bus_hotplug(struct device *dev, char **envp, int num_envp, char *buf,
i
=
0
;
add_env
(
"MMC_CCC=%s"
,
ccc
);
add_env
(
"MMC_MANFID=%03x"
,
card
->
cid
.
manfid
);
add_env
(
"MMC_SLOT_NAME=%s"
,
card
->
dev
.
bus_id
);
add_env
(
"MMC_MANFID=%06x"
,
card
->
cid
.
manfid
);
add_env
(
"MMC_NAME=%s"
,
mmc_card_name
(
card
));
add_env
(
"MMC_OEMID=%04x"
,
card
->
cid
.
oemid
);
return
0
;
}
...
...
@@ -157,20 +159,28 @@ static ssize_t mmc_dev_show_##name (struct device *dev, char *buf) \
} \
static DEVICE_ATTR(name, S_IRUGO, mmc_dev_show_##name, NULL)
MMC_ATTR
(
date
,
"%02d/%04d
\n
"
,
card
->
cid
.
month
,
1997
+
card
->
cid
.
year
);
MMC_ATTR
(
cid
,
"%08x%08x%08x%08x
\n
"
,
card
->
raw_cid
[
0
],
card
->
raw_cid
[
1
],
card
->
raw_cid
[
2
],
card
->
raw_cid
[
3
]);
MMC_ATTR
(
csd
,
"%08x%08x%08x%08x
\n
"
,
card
->
raw_csd
[
0
],
card
->
raw_csd
[
1
],
card
->
raw_csd
[
2
],
card
->
raw_csd
[
3
]);
MMC_ATTR
(
date
,
"%02d/%04d
\n
"
,
card
->
cid
.
month
,
card
->
cid
.
year
);
MMC_ATTR
(
fwrev
,
"0x%x
\n
"
,
card
->
cid
.
fwrev
);
MMC_ATTR
(
hwrev
,
"0x%x
\n
"
,
card
->
cid
.
hwrev
);
MMC_ATTR
(
manfid
,
"0x%03x
\n
"
,
card
->
cid
.
manfid
);
MMC_ATTR
(
serial
,
"0x%06x
\n
"
,
card
->
cid
.
serial
);
MMC_ATTR
(
manfid
,
"0x%06x
\n
"
,
card
->
cid
.
manfid
);
MMC_ATTR
(
name
,
"%s
\n
"
,
card
->
cid
.
prod_name
);
MMC_ATTR
(
oemid
,
"0x%04x
\n
"
,
card
->
cid
.
oemid
);
MMC_ATTR
(
serial
,
"0x%08x
\n
"
,
card
->
cid
.
serial
);
static
struct
device_attribute
*
mmc_dev_attributes
[]
=
{
&
dev_attr_cid
,
&
dev_attr_csd
,
&
dev_attr_date
,
&
dev_attr_fwrev
,
&
dev_attr_hwrev
,
&
dev_attr_manfid
,
&
dev_attr_serial
,
&
dev_attr_name
,
&
dev_attr_oemid
,
&
dev_attr_serial
,
};
/*
...
...
include/linux/mmc/card.h
View file @
6e58ddeb
...
...
@@ -14,16 +14,17 @@
struct
mmc_cid
{
unsigned
int
manfid
;
unsigned
int
serial
;
char
prod_name
[
8
];
unsigned
int
serial
;
unsigned
short
oemid
;
unsigned
short
year
;
unsigned
char
hwrev
;
unsigned
char
fwrev
;
unsigned
char
month
;
unsigned
char
year
;
};
struct
mmc_csd
{
unsigned
char
mmc
_prot
;
unsigned
char
mmc
a_vsn
;
unsigned
short
cmdclass
;
unsigned
short
tacc_clks
;
unsigned
int
tacc_ns
;
...
...
@@ -43,14 +44,22 @@ struct mmc_card {
struct
device
dev
;
/* the device */
unsigned
int
rca
;
/* relative card address of device */
unsigned
int
state
;
/* (our) card state */
#define MMC_STATE_PRESENT (1<<0)
#define MMC_STATE_DEAD (1<<1)
#define MMC_STATE_PRESENT (1<<0)
/* present in sysfs */
#define MMC_STATE_DEAD (1<<1)
/* device no longer in stack */
#define MMC_STATE_BAD (1<<2)
/* unrecognised device */
u32
raw_cid
[
4
];
/* raw card CID */
u32
raw_csd
[
4
];
/* raw card CSD */
struct
mmc_cid
cid
;
/* card identification */
struct
mmc_csd
csd
;
/* card specific */
};
#define mmc_card_dead(c) ((c)->state & MMC_STATE_DEAD)
#define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT)
#define mmc_card_dead(c) ((c)->state & MMC_STATE_DEAD)
#define mmc_card_bad(c) ((c)->state & MMC_STATE_BAD)
#define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT)
#define mmc_card_set_dead(c) ((c)->state |= MMC_STATE_DEAD)
#define mmc_card_set_bad(c) ((c)->state |= MMC_STATE_BAD)
#define mmc_card_name(c) ((c)->cid.prod_name)
#define mmc_card_id(c) ((c)->dev.bus_id)
...
...
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