2 * linux/drivers/mmc/core/sdio_cis.c
4 * Author: Nicolas Pitre
5 * Created: June 11, 2007
6 * Copyright: MontaVista Software Inc.
8 * Copyright 2007 Pierre Ossman
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or (at
13 * your option) any later version.
16 #include <linux/kernel.h>
18 #include <linux/mmc/host.h>
19 #include <linux/mmc/sdio.h>
20 #include <linux/mmc/sdio_func.h>
25 static int cistpl_manfid(struct sdio_func
*func
,
26 const unsigned char *buf
,
30 func
->vendor
= buf
[0] | (buf
[1] << 8);
33 func
->device
= buf
[2] | (buf
[3] << 8);
40 unsigned char min_size
;
41 int (*parse
)(struct sdio_func
*, const unsigned char *buf
, unsigned size
);
44 static const struct cis_tpl cis_tpl_list
[] = {
45 { 0x15, 3, /* cistpl_vers_1 */ },
46 { 0x20, 4, cistpl_manfid
},
47 { 0x21, 2, /* cistpl_funcid */ },
48 { 0x22, 0, /* cistpl_funce */ },
51 int sdio_read_cis(struct sdio_func
*func
)
54 struct sdio_func_tuple
*this, **prev
;
57 for (i
= 0; i
< 3; i
++) {
59 ret
= mmc_io_rw_direct(func
->card
, 0, 0,
60 func
->num
* 0x100 + SDIO_FBR_CIS
+ i
, 0, &x
);
66 /* find the list tail */
67 for (prev
= &func
->tuples
; *prev
; prev
= &(*prev
)->next
);
70 unsigned char tpl_code
, tpl_link
;
72 ret
= mmc_io_rw_direct(func
->card
, 0, 0, ptr
++, 0, &tpl_code
);
76 /* 0xff means we're done */
80 ret
= mmc_io_rw_direct(func
->card
, 0, 0, ptr
++, 0, &tpl_link
);
84 this = kmalloc(sizeof(*this) + tpl_link
, GFP_KERNEL
);
88 for (i
= 0; i
< tpl_link
; i
++) {
89 ret
= mmc_io_rw_direct(func
->card
, 0, 0,
90 ptr
+ i
, 0, &this->data
[i
]);
99 for (i
= 0; i
< ARRAY_SIZE(cis_tpl_list
); i
++)
100 if (cis_tpl_list
[i
].code
== tpl_code
)
102 if (i
>= ARRAY_SIZE(cis_tpl_list
)) {
103 /* this tuple is unknown to the core */
105 this->code
= tpl_code
;
106 this->size
= tpl_link
;
110 "%s: queuing CIS tuple 0x%02x length %u\n",
111 sdio_func_id(func
), tpl_code
, tpl_link
);
113 const struct cis_tpl
*tpl
= cis_tpl_list
+ i
;
114 if (tpl_link
< tpl
->min_size
) {
116 "%s: bad CIS tuple 0x%02x (length = %u, expected >= %u)\n",
117 sdio_func_id(func
), tpl_code
, tpl_link
, tpl
->min_size
);
119 } else if (tpl
->parse
)
120 ret
= tpl
->parse(func
, this->data
, tpl_link
);
130 void sdio_free_cis(struct sdio_func
*func
)
132 struct sdio_func_tuple
*tuple
, *victim
;
134 tuple
= func
->tuples
;