Commit d700518a authored by Dominik Brodowski's avatar Dominik Brodowski

pcmcia: use read_cis_mem return value

Signed-off-by: default avatarDominik Brodowski <linux@dominikbrodowski.net>
parent a78621bb
...@@ -283,30 +283,32 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, ...@@ -283,30 +283,32 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
======================================================================*/ ======================================================================*/
static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, static int read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
size_t len, void *ptr) size_t len, void *ptr)
{ {
struct cis_cache_entry *cis; struct cis_cache_entry *cis;
int ret; int ret = 0;
if (s->state & SOCKET_CARDBUS) if (s->state & SOCKET_CARDBUS)
return; return -EINVAL;
mutex_lock(&s->ops_mutex); mutex_lock(&s->ops_mutex);
if (s->fake_cis) { if (s->fake_cis) {
if (s->fake_cis_len >= addr+len) if (s->fake_cis_len >= addr+len)
memcpy(ptr, s->fake_cis+addr, len); memcpy(ptr, s->fake_cis+addr, len);
else else {
memset(ptr, 0xff, len); memset(ptr, 0xff, len);
ret = -EINVAL;
}
mutex_unlock(&s->ops_mutex); mutex_unlock(&s->ops_mutex);
return; return ret;
} }
list_for_each_entry(cis, &s->cis_cache, node) { list_for_each_entry(cis, &s->cis_cache, node) {
if (cis->addr == addr && cis->len == len && cis->attr == attr) { if (cis->addr == addr && cis->len == len && cis->attr == attr) {
memcpy(ptr, cis->cache, len); memcpy(ptr, cis->cache, len);
mutex_unlock(&s->ops_mutex); mutex_unlock(&s->ops_mutex);
return; return 0;
} }
} }
mutex_unlock(&s->ops_mutex); mutex_unlock(&s->ops_mutex);
...@@ -326,6 +328,7 @@ static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr, ...@@ -326,6 +328,7 @@ static void read_cis_cache(struct pcmcia_socket *s, int attr, u_int addr,
mutex_unlock(&s->ops_mutex); mutex_unlock(&s->ops_mutex);
} }
} }
return ret;
} }
static void static void
...@@ -374,6 +377,7 @@ int verify_cis_cache(struct pcmcia_socket *s) ...@@ -374,6 +377,7 @@ int verify_cis_cache(struct pcmcia_socket *s)
{ {
struct cis_cache_entry *cis; struct cis_cache_entry *cis;
char *buf; char *buf;
int ret;
if (s->state & SOCKET_CARDBUS) if (s->state & SOCKET_CARDBUS)
return -EINVAL; return -EINVAL;
...@@ -390,9 +394,8 @@ int verify_cis_cache(struct pcmcia_socket *s) ...@@ -390,9 +394,8 @@ int verify_cis_cache(struct pcmcia_socket *s)
if (len > 256) if (len > 256)
len = 256; len = 256;
pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf); ret = pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf);
if (ret || memcmp(buf, cis->cache, len) != 0) {
if (memcmp(buf, cis->cache, len) != 0) {
kfree(buf); kfree(buf);
return -1; return -1;
} }
...@@ -425,6 +428,7 @@ int pcmcia_replace_cis(struct pcmcia_socket *s, ...@@ -425,6 +428,7 @@ int pcmcia_replace_cis(struct pcmcia_socket *s,
} }
s->fake_cis_len = len; s->fake_cis_len = len;
memcpy(s->fake_cis, data, len); memcpy(s->fake_cis, data, len);
dev_info(&s->dev, "Using replacement CIS\n");
mutex_unlock(&s->ops_mutex); mutex_unlock(&s->ops_mutex);
return 0; return 0;
} }
...@@ -478,11 +482,14 @@ static int follow_link(struct pcmcia_socket *s, tuple_t *tuple) ...@@ -478,11 +482,14 @@ static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
{ {
u_char link[5]; u_char link[5];
u_int ofs; u_int ofs;
int ret;
if (MFC_FN(tuple->Flags)) { if (MFC_FN(tuple->Flags)) {
/* Get indirect link from the MFC tuple */ /* Get indirect link from the MFC tuple */
read_cis_cache(s, LINK_SPACE(tuple->Flags), ret = read_cis_cache(s, LINK_SPACE(tuple->Flags),
tuple->LinkOffset, 5, link); tuple->LinkOffset, 5, link);
if (ret)
return -1;
ofs = get_unaligned_le32(link + 1); ofs = get_unaligned_le32(link + 1);
SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR); SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR);
/* Move to the next indirect link */ /* Move to the next indirect link */
...@@ -498,7 +505,9 @@ static int follow_link(struct pcmcia_socket *s, tuple_t *tuple) ...@@ -498,7 +505,9 @@ static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
if (SPACE(tuple->Flags)) { if (SPACE(tuple->Flags)) {
/* This is ugly, but a common CIS error is to code the long /* This is ugly, but a common CIS error is to code the long
link offset incorrectly, so we check the right spot... */ link offset incorrectly, so we check the right spot... */
read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link); ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
if (ret)
return -1;
if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) && if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) &&
(strncmp(link+2, "CIS", 3) == 0)) (strncmp(link+2, "CIS", 3) == 0))
return ofs; return ofs;
...@@ -506,7 +515,9 @@ static int follow_link(struct pcmcia_socket *s, tuple_t *tuple) ...@@ -506,7 +515,9 @@ static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
/* Then, we try the wrong spot... */ /* Then, we try the wrong spot... */
ofs = ofs >> 1; ofs = ofs >> 1;
} }
read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link); ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link);
if (ret)
return -1;
if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) && if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) &&
(strncmp(link+2, "CIS", 3) == 0)) (strncmp(link+2, "CIS", 3) == 0))
return ofs; return ofs;
...@@ -518,6 +529,7 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_ ...@@ -518,6 +529,7 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
{ {
u_char link[2], tmp; u_char link[2], tmp;
int ofs, i, attr; int ofs, i, attr;
int ret;
if (!s) if (!s)
return -EINVAL; return -EINVAL;
...@@ -532,7 +544,9 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_ ...@@ -532,7 +544,9 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
if (link[1] == 0xff) { if (link[1] == 0xff) {
link[0] = CISTPL_END; link[0] = CISTPL_END;
} else { } else {
read_cis_cache(s, attr, ofs, 2, link); ret = read_cis_cache(s, attr, ofs, 2, link);
if (ret)
return -1;
if (link[0] == CISTPL_NULL) { if (link[0] == CISTPL_NULL) {
ofs++; continue; ofs++; continue;
} }
...@@ -544,7 +558,9 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_ ...@@ -544,7 +558,9 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
if (ofs < 0) if (ofs < 0)
return -ENOSPC; return -ENOSPC;
attr = SPACE(tuple->Flags); attr = SPACE(tuple->Flags);
read_cis_cache(s, attr, ofs, 2, link); ret = read_cis_cache(s, attr, ofs, 2, link);
if (ret)
return -1;
} }
/* Is this a link tuple? Make a note of it */ /* Is this a link tuple? Make a note of it */
...@@ -558,12 +574,16 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_ ...@@ -558,12 +574,16 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
case CISTPL_LONGLINK_A: case CISTPL_LONGLINK_A:
HAS_LINK(tuple->Flags) = 1; HAS_LINK(tuple->Flags) = 1;
LINK_SPACE(tuple->Flags) = attr | IS_ATTR; LINK_SPACE(tuple->Flags) = attr | IS_ATTR;
read_cis_cache(s, attr, ofs+2, 4, &tuple->LinkOffset); ret = read_cis_cache(s, attr, ofs+2, 4, &tuple->LinkOffset);
if (ret)
return -1;
break; break;
case CISTPL_LONGLINK_C: case CISTPL_LONGLINK_C:
HAS_LINK(tuple->Flags) = 1; HAS_LINK(tuple->Flags) = 1;
LINK_SPACE(tuple->Flags) = attr & ~IS_ATTR; LINK_SPACE(tuple->Flags) = attr & ~IS_ATTR;
read_cis_cache(s, attr, ofs+2, 4, &tuple->LinkOffset); ret = read_cis_cache(s, attr, ofs+2, 4, &tuple->LinkOffset);
if (ret)
return -1;
break; break;
case CISTPL_INDIRECT: case CISTPL_INDIRECT:
HAS_LINK(tuple->Flags) = 1; HAS_LINK(tuple->Flags) = 1;
...@@ -575,7 +595,9 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_ ...@@ -575,7 +595,9 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
LINK_SPACE(tuple->Flags) = attr; LINK_SPACE(tuple->Flags) = attr;
if (function == BIND_FN_ALL) { if (function == BIND_FN_ALL) {
/* Follow all the MFC links */ /* Follow all the MFC links */
read_cis_cache(s, attr, ofs+2, 1, &tmp); ret = read_cis_cache(s, attr, ofs+2, 1, &tmp);
if (ret)
return -1;
MFC_FN(tuple->Flags) = tmp; MFC_FN(tuple->Flags) = tmp;
} else { } else {
/* Follow exactly one of the links */ /* Follow exactly one of the links */
...@@ -616,6 +638,7 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_ ...@@ -616,6 +638,7 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple) int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple)
{ {
u_int len; u_int len;
int ret;
if (!s) if (!s)
return -EINVAL; return -EINVAL;
...@@ -626,9 +649,11 @@ int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple) ...@@ -626,9 +649,11 @@ int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple)
tuple->TupleDataLen = tuple->TupleLink; tuple->TupleDataLen = tuple->TupleLink;
if (len == 0) if (len == 0)
return 0; return 0;
read_cis_cache(s, SPACE(tuple->Flags), ret = read_cis_cache(s, SPACE(tuple->Flags),
tuple->CISOffset + tuple->TupleOffset, tuple->CISOffset + tuple->TupleOffset,
_MIN(len, tuple->TupleDataMax), tuple->TupleData); _MIN(len, tuple->TupleDataMax), tuple->TupleData);
if (ret)
return -1;
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment