Lines Matching +full:3 +full:- +full:tuples

1 // SPDX-License-Identifier: GPL-2.0-only
3 * cistpl.c -- 16-bit PCMCIA Card Information Structure parser
45 (mantissa[(((v)>>3)&15)-1] * exponent[(v)&7] / 10)
48 (mantissa[((v)>>3)&15] * exponent[(v)&7] / 10)
51 /* Upper limit on reasonable # of tuples */
57 /* 16-bit CIS? */
63 mutex_lock(&s->ops_mutex); in release_cis_mem()
64 if (s->cis_mem.flags & MAP_ACTIVE) { in release_cis_mem()
65 s->cis_mem.flags &= ~MAP_ACTIVE; in release_cis_mem()
66 s->ops->set_mem_map(s, &s->cis_mem); in release_cis_mem()
67 if (s->cis_mem.res) { in release_cis_mem()
68 release_resource(s->cis_mem.res); in release_cis_mem()
69 kfree(s->cis_mem.res); in release_cis_mem()
70 s->cis_mem.res = NULL; in release_cis_mem()
72 iounmap(s->cis_virt); in release_cis_mem()
73 s->cis_virt = NULL; in release_cis_mem()
75 mutex_unlock(&s->ops_mutex); in release_cis_mem()
79 * set_cis_map() - map the card memory at "card_offset" into virtual space.
89 pccard_mem_map *mem = &s->cis_mem; in set_cis_map()
92 if (!(s->features & SS_CAP_STATIC_MAP) && (mem->res == NULL)) { in set_cis_map()
93 mem->res = pcmcia_find_mem_region(0, s->map_size, in set_cis_map()
94 s->map_size, 0, s); in set_cis_map()
95 if (mem->res == NULL) { in set_cis_map()
96 dev_notice(&s->dev, "cs: unable to map card memory!\n"); in set_cis_map()
99 s->cis_virt = NULL; in set_cis_map()
102 if (!(s->features & SS_CAP_STATIC_MAP) && (!s->cis_virt)) in set_cis_map()
103 s->cis_virt = ioremap(mem->res->start, s->map_size); in set_cis_map()
105 mem->card_start = card_offset; in set_cis_map()
106 mem->flags = flags; in set_cis_map()
108 ret = s->ops->set_mem_map(s, mem); in set_cis_map()
110 iounmap(s->cis_virt); in set_cis_map()
111 s->cis_virt = NULL; in set_cis_map()
115 if (s->features & SS_CAP_STATIC_MAP) { in set_cis_map()
116 if (s->cis_virt) in set_cis_map()
117 iounmap(s->cis_virt); in set_cis_map()
118 s->cis_virt = ioremap(mem->static_start, s->map_size); in set_cis_map()
121 return s->cis_virt; in set_cis_map()
130 * pcmcia_read_cis_mem() - low-level function to read CIS memory
140 dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len); in pcmcia_read_cis_mem()
154 dev_dbg(&s->dev, "could not map memory\n"); in pcmcia_read_cis_mem()
156 return -1; in pcmcia_read_cis_mem()
164 for ( ; len > 0; len--, buf++) in pcmcia_read_cis_mem()
170 dev_dbg(&s->dev, in pcmcia_read_cis_mem()
173 return -1; in pcmcia_read_cis_mem()
183 card_offset = addr & ~(s->map_size-1); in pcmcia_read_cis_mem()
187 dev_dbg(&s->dev, "could not map memory\n"); in pcmcia_read_cis_mem()
189 return -1; in pcmcia_read_cis_mem()
191 end = sys + s->map_size; in pcmcia_read_cis_mem()
192 sys = sys + (addr & (s->map_size-1)); in pcmcia_read_cis_mem()
193 for ( ; len > 0; len--, buf++, sys += inc) { in pcmcia_read_cis_mem()
198 card_offset += s->map_size; in pcmcia_read_cis_mem()
202 dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n", in pcmcia_read_cis_mem()
204 *(u_char *)(ptr+2), *(u_char *)(ptr+3)); in pcmcia_read_cis_mem()
210 * pcmcia_write_cis_mem() - low-level function to write CIS memory
212 * Probably only useful for writing one-byte registers. Must be called
221 dev_dbg(&s->dev, in pcmcia_write_cis_mem()
236 dev_dbg(&s->dev, "could not map memory\n"); in pcmcia_write_cis_mem()
237 return -EINVAL; in pcmcia_write_cis_mem()
245 for ( ; len > 0; len--, buf++) in pcmcia_write_cis_mem()
257 card_offset = addr & ~(s->map_size-1); in pcmcia_write_cis_mem()
261 dev_dbg(&s->dev, "could not map memory\n"); in pcmcia_write_cis_mem()
262 return -EINVAL; in pcmcia_write_cis_mem()
265 end = sys + s->map_size; in pcmcia_write_cis_mem()
266 sys = sys + (addr & (s->map_size-1)); in pcmcia_write_cis_mem()
267 for ( ; len > 0; len--, buf++, sys += inc) { in pcmcia_write_cis_mem()
272 card_offset += s->map_size; in pcmcia_write_cis_mem()
281 * read_cis_cache() - read CIS memory or its associated cache
293 if (s->state & SOCKET_CARDBUS) in read_cis_cache()
294 return -EINVAL; in read_cis_cache()
296 mutex_lock(&s->ops_mutex); in read_cis_cache()
297 if (s->fake_cis) { in read_cis_cache()
298 if (s->fake_cis_len >= addr+len) in read_cis_cache()
299 memcpy(ptr, s->fake_cis+addr, len); in read_cis_cache()
302 ret = -EINVAL; in read_cis_cache()
304 mutex_unlock(&s->ops_mutex); in read_cis_cache()
308 list_for_each_entry(cis, &s->cis_cache, node) { in read_cis_cache()
309 if (cis->addr == addr && cis->len == len && cis->attr == attr) { in read_cis_cache()
310 memcpy(ptr, cis->cache, len); in read_cis_cache()
311 mutex_unlock(&s->ops_mutex); in read_cis_cache()
322 cis->addr = addr; in read_cis_cache()
323 cis->len = len; in read_cis_cache()
324 cis->attr = attr; in read_cis_cache()
325 memcpy(cis->cache, ptr, len); in read_cis_cache()
326 list_add(&cis->node, &s->cis_cache); in read_cis_cache()
329 mutex_unlock(&s->ops_mutex); in read_cis_cache()
339 mutex_lock(&s->ops_mutex); in remove_cis_cache()
340 list_for_each_entry(cis, &s->cis_cache, node) in remove_cis_cache()
341 if (cis->addr == addr && cis->len == len && cis->attr == attr) { in remove_cis_cache()
342 list_del(&cis->node); in remove_cis_cache()
346 mutex_unlock(&s->ops_mutex); in remove_cis_cache()
350 * destroy_cis_cache() - destroy the CIS cache
361 list_for_each_safe(l, n, &s->cis_cache) { in destroy_cis_cache()
363 list_del(&cis->node); in destroy_cis_cache()
369 * verify_cis_cache() - does the CIS match what is in the CIS cache?
377 if (s->state & SOCKET_CARDBUS) in verify_cis_cache()
378 return -EINVAL; in verify_cis_cache()
382 dev_warn(&s->dev, "no memory for verifying CIS\n"); in verify_cis_cache()
383 return -ENOMEM; in verify_cis_cache()
385 mutex_lock(&s->ops_mutex); in verify_cis_cache()
386 list_for_each_entry(cis, &s->cis_cache, node) { in verify_cis_cache()
387 int len = cis->len; in verify_cis_cache()
392 ret = pcmcia_read_cis_mem(s, cis->attr, cis->addr, len, buf); in verify_cis_cache()
393 if (ret || memcmp(buf, cis->cache, len) != 0) { in verify_cis_cache()
395 mutex_unlock(&s->ops_mutex); in verify_cis_cache()
396 return -1; in verify_cis_cache()
400 mutex_unlock(&s->ops_mutex); in verify_cis_cache()
405 * pcmcia_replace_cis() - use a replacement CIS instead of the card's CIS
414 dev_warn(&s->dev, "replacement CIS too big\n"); in pcmcia_replace_cis()
415 return -EINVAL; in pcmcia_replace_cis()
417 mutex_lock(&s->ops_mutex); in pcmcia_replace_cis()
418 kfree(s->fake_cis); in pcmcia_replace_cis()
419 s->fake_cis = kmalloc(len, GFP_KERNEL); in pcmcia_replace_cis()
420 if (s->fake_cis == NULL) { in pcmcia_replace_cis()
421 dev_warn(&s->dev, "no memory to replace CIS\n"); in pcmcia_replace_cis()
422 mutex_unlock(&s->ops_mutex); in pcmcia_replace_cis()
423 return -ENOMEM; in pcmcia_replace_cis()
425 s->fake_cis_len = len; in pcmcia_replace_cis()
426 memcpy(s->fake_cis, data, len); in pcmcia_replace_cis()
427 dev_info(&s->dev, "Using replacement CIS\n"); in pcmcia_replace_cis()
428 mutex_unlock(&s->ops_mutex); in pcmcia_replace_cis()
432 /* The high-level CIS tuple services */
437 u_int mfc_fn:3;
441 #define LINK_SPACE(f) (((struct tuple_flags *)(&(f)))->link_space)
442 #define HAS_LINK(f) (((struct tuple_flags *)(&(f)))->has_link)
443 #define MFC_FN(f) (((struct tuple_flags *)(&(f)))->mfc_fn)
444 #define SPACE(f) (((struct tuple_flags *)(&(f)))->space)
450 return -EINVAL; in pccard_get_first_tuple()
452 if (!(s->state & SOCKET_PRESENT) || (s->state & SOCKET_CARDBUS)) in pccard_get_first_tuple()
453 return -ENODEV; in pccard_get_first_tuple()
454 tuple->TupleLink = tuple->Flags = 0; in pccard_get_first_tuple()
457 tuple->CISOffset = tuple->LinkOffset = 0; in pccard_get_first_tuple()
458 SPACE(tuple->Flags) = HAS_LINK(tuple->Flags) = 1; in pccard_get_first_tuple()
460 if ((s->functions > 1) && !(tuple->Attributes & TUPLE_RETURN_COMMON)) { in pccard_get_first_tuple()
461 cisdata_t req = tuple->DesiredTuple; in pccard_get_first_tuple()
462 tuple->DesiredTuple = CISTPL_LONGLINK_MFC; in pccard_get_first_tuple()
464 tuple->DesiredTuple = CISTPL_LINKTARGET; in pccard_get_first_tuple()
466 return -ENOSPC; in pccard_get_first_tuple()
468 tuple->CISOffset = tuple->TupleLink = 0; in pccard_get_first_tuple()
469 tuple->DesiredTuple = req; in pccard_get_first_tuple()
480 if (MFC_FN(tuple->Flags)) { in follow_link()
482 ret = read_cis_cache(s, LINK_SPACE(tuple->Flags), in follow_link()
483 tuple->LinkOffset, 5, link); in follow_link()
485 return -1; in follow_link()
487 SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR); in follow_link()
489 tuple->LinkOffset += 5; in follow_link()
490 MFC_FN(tuple->Flags)--; in follow_link()
491 } else if (HAS_LINK(tuple->Flags)) { in follow_link()
492 ofs = tuple->LinkOffset; in follow_link()
493 SPACE(tuple->Flags) = LINK_SPACE(tuple->Flags); in follow_link()
494 HAS_LINK(tuple->Flags) = 0; in follow_link()
496 return -1; in follow_link()
498 if (SPACE(tuple->Flags)) { in follow_link()
501 ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link); in follow_link()
503 return -1; in follow_link()
504 if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) && in follow_link()
505 (strncmp(link+2, "CIS", 3) == 0)) in follow_link()
507 remove_cis_cache(s, SPACE(tuple->Flags), ofs, 5); in follow_link()
511 ret = read_cis_cache(s, SPACE(tuple->Flags), ofs, 5, link); in follow_link()
513 return -1; in follow_link()
514 if ((link[0] == CISTPL_LINKTARGET) && (link[1] >= 3) && in follow_link()
515 (strncmp(link+2, "CIS", 3) == 0)) in follow_link()
517 remove_cis_cache(s, SPACE(tuple->Flags), ofs, 5); in follow_link()
518 return -1; in follow_link()
529 return -EINVAL; in pccard_get_next_tuple()
530 if (!(s->state & SOCKET_PRESENT) || (s->state & SOCKET_CARDBUS)) in pccard_get_next_tuple()
531 return -ENODEV; in pccard_get_next_tuple()
533 link[1] = tuple->TupleLink; in pccard_get_next_tuple()
534 ofs = tuple->CISOffset + tuple->TupleLink; in pccard_get_next_tuple()
535 attr = SPACE(tuple->Flags); in pccard_get_next_tuple()
543 return -1; in pccard_get_next_tuple()
554 return -ENOSPC; in pccard_get_next_tuple()
555 attr = SPACE(tuple->Flags); in pccard_get_next_tuple()
558 return -1; in pccard_get_next_tuple()
570 HAS_LINK(tuple->Flags) = 1; in pccard_get_next_tuple()
571 LINK_SPACE(tuple->Flags) = attr | IS_ATTR; in pccard_get_next_tuple()
573 &tuple->LinkOffset); in pccard_get_next_tuple()
575 return -1; in pccard_get_next_tuple()
578 HAS_LINK(tuple->Flags) = 1; in pccard_get_next_tuple()
579 LINK_SPACE(tuple->Flags) = attr & ~IS_ATTR; in pccard_get_next_tuple()
581 &tuple->LinkOffset); in pccard_get_next_tuple()
583 return -1; in pccard_get_next_tuple()
586 HAS_LINK(tuple->Flags) = 1; in pccard_get_next_tuple()
587 LINK_SPACE(tuple->Flags) = IS_ATTR | in pccard_get_next_tuple()
589 tuple->LinkOffset = 0; in pccard_get_next_tuple()
592 tuple->LinkOffset = ofs + 3; in pccard_get_next_tuple()
593 LINK_SPACE(tuple->Flags) = attr; in pccard_get_next_tuple()
599 return -1; in pccard_get_next_tuple()
600 MFC_FN(tuple->Flags) = tmp; in pccard_get_next_tuple()
603 MFC_FN(tuple->Flags) = 1; in pccard_get_next_tuple()
604 tuple->LinkOffset += function * 5; in pccard_get_next_tuple()
608 HAS_LINK(tuple->Flags) = 0; in pccard_get_next_tuple()
611 if ((tuple->Attributes & TUPLE_RETURN_LINK) && in pccard_get_next_tuple()
612 (tuple->DesiredTuple == RETURN_FIRST_TUPLE)) in pccard_get_next_tuple()
615 if (tuple->DesiredTuple == RETURN_FIRST_TUPLE) in pccard_get_next_tuple()
618 if (link[0] == tuple->DesiredTuple) in pccard_get_next_tuple()
623 dev_dbg(&s->dev, "cs: overrun in pcmcia_get_next_tuple\n"); in pccard_get_next_tuple()
624 return -ENOSPC; in pccard_get_next_tuple()
627 tuple->TupleCode = link[0]; in pccard_get_next_tuple()
628 tuple->TupleLink = link[1]; in pccard_get_next_tuple()
629 tuple->CISOffset = ofs + 2; in pccard_get_next_tuple()
639 return -EINVAL; in pccard_get_tuple_data()
641 if (tuple->TupleLink < tuple->TupleOffset) in pccard_get_tuple_data()
642 return -ENOSPC; in pccard_get_tuple_data()
643 len = tuple->TupleLink - tuple->TupleOffset; in pccard_get_tuple_data()
644 tuple->TupleDataLen = tuple->TupleLink; in pccard_get_tuple_data()
647 ret = read_cis_cache(s, SPACE(tuple->Flags), in pccard_get_tuple_data()
648 tuple->CISOffset + tuple->TupleOffset, in pccard_get_tuple_data()
649 min(len, (u_int) tuple->TupleDataMax), in pccard_get_tuple_data()
650 tuple->TupleData); in pccard_get_tuple_data()
652 return -1; in pccard_get_tuple_data()
657 /* Parsing routines for individual tuples */
665 p = (u_char *)tuple->TupleData; in parse_device()
666 q = p + tuple->TupleDataLen; in parse_device()
668 device->ndev = 0; in parse_device()
673 device->dev[i].type = (*p >> 4); in parse_device()
674 device->dev[i].wp = (*p & 0x08) ? 1 : 0; in parse_device()
677 device->dev[i].speed = 0; in parse_device()
680 device->dev[i].speed = 250; in parse_device()
683 device->dev[i].speed = 200; in parse_device()
685 case 3: in parse_device()
686 device->dev[i].speed = 150; in parse_device()
689 device->dev[i].speed = 100; in parse_device()
693 return -EINVAL; in parse_device()
694 device->dev[i].speed = SPEED_CVT(*p); in parse_device()
697 return -EINVAL; in parse_device()
700 return -EINVAL; in parse_device()
704 return -EINVAL; in parse_device()
709 return -EINVAL; in parse_device()
710 device->dev[i].size = ((*p >> 3) + 1) * (512 << (scale*2)); in parse_device()
711 device->ndev++; in parse_device()
723 if (tuple->TupleDataLen < 5) in parse_checksum()
724 return -EINVAL; in parse_checksum()
725 p = (u_char *) tuple->TupleData; in parse_checksum()
726 csum->addr = tuple->CISOffset + get_unaligned_le16(p) - 2; in parse_checksum()
727 csum->len = get_unaligned_le16(p + 2); in parse_checksum()
728 csum->sum = *(p + 4); in parse_checksum()
735 if (tuple->TupleDataLen < 4) in parse_longlink()
736 return -EINVAL; in parse_longlink()
737 link->addr = get_unaligned_le32(tuple->TupleData); in parse_longlink()
747 p = (u_char *)tuple->TupleData; in parse_longlink_mfc()
749 link->nfn = *p; p++; in parse_longlink_mfc()
750 if (tuple->TupleDataLen <= link->nfn*5) in parse_longlink_mfc()
751 return -EINVAL; in parse_longlink_mfc()
752 for (i = 0; i < link->nfn; i++) { in parse_longlink_mfc()
753 link->fn[i].space = *p; p++; in parse_longlink_mfc()
754 link->fn[i].addr = get_unaligned_le32(p); in parse_longlink_mfc()
767 return -EINVAL; in parse_strings()
779 return -EINVAL; in parse_strings()
789 return (ns == max) ? 0 : -EINVAL; in parse_strings()
797 p = (u_char *)tuple->TupleData; in parse_vers_1()
798 q = p + tuple->TupleDataLen; in parse_vers_1()
800 vers_1->major = *p; p++; in parse_vers_1()
801 vers_1->minor = *p; p++; in parse_vers_1()
803 return -EINVAL; in parse_vers_1()
806 vers_1->str, vers_1->ofs, &vers_1->ns); in parse_vers_1()
814 p = (u_char *)tuple->TupleData; in parse_altstr()
815 q = p + tuple->TupleDataLen; in parse_altstr()
818 altstr->str, altstr->ofs, &altstr->ns); in parse_altstr()
827 p = (u_char *)tuple->TupleData; in parse_jedec()
828 q = p + tuple->TupleDataLen; in parse_jedec()
831 if (p > q-2) in parse_jedec()
833 jedec->id[nid].mfr = p[0]; in parse_jedec()
834 jedec->id[nid].info = p[1]; in parse_jedec()
837 jedec->nid = nid; in parse_jedec()
844 if (tuple->TupleDataLen < 4) in parse_manfid()
845 return -EINVAL; in parse_manfid()
846 m->manf = get_unaligned_le16(tuple->TupleData); in parse_manfid()
847 m->card = get_unaligned_le16(tuple->TupleData + 2); in parse_manfid()
855 if (tuple->TupleDataLen < 2) in parse_funcid()
856 return -EINVAL; in parse_funcid()
857 p = (u_char *)tuple->TupleData; in parse_funcid()
858 f->func = p[0]; in parse_funcid()
859 f->sysinit = p[1]; in parse_funcid()
868 if (tuple->TupleDataLen < 1) in parse_funce()
869 return -EINVAL; in parse_funce()
870 p = (u_char *)tuple->TupleData; in parse_funce()
871 f->type = p[0]; in parse_funce()
872 for (i = 1; i < tuple->TupleDataLen; i++) in parse_funce()
873 f->data[i-1] = p[i]; in parse_funce()
883 p = (u_char *)tuple->TupleData; in parse_config()
886 if (tuple->TupleDataLen < rasz+rmsz+4) in parse_config()
887 return -EINVAL; in parse_config()
888 config->last_idx = *(++p); in parse_config()
890 config->base = 0; in parse_config()
892 config->base += p[i] << (8*i); in parse_config()
895 config->rmask[i] = 0; in parse_config()
897 config->rmask[i>>2] += p[i] << (8*(i%4)); in parse_config()
898 config->subtuples = tuple->TupleDataLen - (rasz+rmsz+4); in parse_config()
913 pwr->present = *p; in parse_power()
914 pwr->flags = 0; in parse_power()
917 if (pwr->present & (1<<i)) { in parse_power()
920 pwr->param[i] = POWER_CVT(*p); in parse_power()
926 pwr->param[i] += in parse_power()
929 pwr->flags |= CISTPL_POWER_HIGHZ_OK; in parse_power()
931 pwr->param[i] = 0; in parse_power()
933 pwr->flags |= CISTPL_POWER_HIGHZ_REQ; in parse_power()
950 if ((scale & 3) != 3) { in parse_timing()
953 timing->wait = SPEED_CVT(*p); in parse_timing()
954 timing->waitscale = exponent[scale & 3]; in parse_timing()
956 timing->wait = 0; in parse_timing()
961 timing->ready = SPEED_CVT(*p); in parse_timing()
962 timing->rdyscale = exponent[scale & 7]; in parse_timing()
964 timing->ready = 0; in parse_timing()
965 scale >>= 3; in parse_timing()
969 timing->reserved = SPEED_CVT(*p); in parse_timing()
970 timing->rsvscale = exponent[scale]; in parse_timing()
972 timing->reserved = 0; in parse_timing()
984 io->flags = *p; in parse_io()
987 io->nwin = 1; in parse_io()
988 io->win[0].base = 0; in parse_io()
989 io->win[0].len = (1 << (io->flags & CISTPL_IO_LINES_MASK)); in parse_io()
995 io->nwin = (*p & 0x0f) + 1; in parse_io()
997 if (bsz == 3) in parse_io()
1000 if (lsz == 3) in parse_io()
1004 for (i = 0; i < io->nwin; i++) { in parse_io()
1005 io->win[i].base = 0; in parse_io()
1006 io->win[i].len = 1; in parse_io()
1010 io->win[i].base += *p << (j*8); in parse_io()
1015 io->win[i].len += *p << (j*8); in parse_io()
1030 mem->nwin = (*p & 0x07) + 1; in parse_mem()
1031 lsz = (*p & 0x18) >> 3; in parse_mem()
1037 for (i = 0; i < mem->nwin; i++) { in parse_mem()
1055 mem->win[i].len = len << 8; in parse_mem()
1056 mem->win[i].card_addr = ca << 8; in parse_mem()
1057 mem->win[i].host_addr = ha << 8; in parse_mem()
1067 irq->IRQInfo1 = *p; p++; in parse_irq()
1068 if (irq->IRQInfo1 & IRQ_INFO2_VALID) { in parse_irq()
1071 irq->IRQInfo2 = (p[1]<<8) + p[0]; in parse_irq()
1083 p = tuple->TupleData; in parse_cftable_entry()
1084 q = p + tuple->TupleDataLen; in parse_cftable_entry()
1085 entry->index = *p & 0x3f; in parse_cftable_entry()
1086 entry->flags = 0; in parse_cftable_entry()
1088 entry->flags |= CISTPL_CFTABLE_DEFAULT; in parse_cftable_entry()
1091 return -EINVAL; in parse_cftable_entry()
1093 entry->flags |= CISTPL_CFTABLE_BVDS; in parse_cftable_entry()
1095 entry->flags |= CISTPL_CFTABLE_WP; in parse_cftable_entry()
1097 entry->flags |= CISTPL_CFTABLE_RDYBSY; in parse_cftable_entry()
1099 entry->flags |= CISTPL_CFTABLE_MWAIT; in parse_cftable_entry()
1100 entry->interface = *p & 0x0f; in parse_cftable_entry()
1102 entry->interface = 0; in parse_cftable_entry()
1106 return -EINVAL; in parse_cftable_entry()
1110 if ((features & 3) > 0) { in parse_cftable_entry()
1111 p = parse_power(p, q, &entry->vcc); in parse_cftable_entry()
1113 return -EINVAL; in parse_cftable_entry()
1115 entry->vcc.present = 0; in parse_cftable_entry()
1116 if ((features & 3) > 1) { in parse_cftable_entry()
1117 p = parse_power(p, q, &entry->vpp1); in parse_cftable_entry()
1119 return -EINVAL; in parse_cftable_entry()
1121 entry->vpp1.present = 0; in parse_cftable_entry()
1122 if ((features & 3) > 2) { in parse_cftable_entry()
1123 p = parse_power(p, q, &entry->vpp2); in parse_cftable_entry()
1125 return -EINVAL; in parse_cftable_entry()
1127 entry->vpp2.present = 0; in parse_cftable_entry()
1131 p = parse_timing(p, q, &entry->timing); in parse_cftable_entry()
1133 return -EINVAL; in parse_cftable_entry()
1135 entry->timing.wait = 0; in parse_cftable_entry()
1136 entry->timing.ready = 0; in parse_cftable_entry()
1137 entry->timing.reserved = 0; in parse_cftable_entry()
1142 p = parse_io(p, q, &entry->io); in parse_cftable_entry()
1144 return -EINVAL; in parse_cftable_entry()
1146 entry->io.nwin = 0; in parse_cftable_entry()
1150 p = parse_irq(p, q, &entry->irq); in parse_cftable_entry()
1152 return -EINVAL; in parse_cftable_entry()
1154 entry->irq.IRQInfo1 = 0; in parse_cftable_entry()
1158 entry->mem.nwin = 0; in parse_cftable_entry()
1161 entry->mem.nwin = 1; in parse_cftable_entry()
1162 entry->mem.win[0].len = get_unaligned_le16(p) << 8; in parse_cftable_entry()
1163 entry->mem.win[0].card_addr = 0; in parse_cftable_entry()
1164 entry->mem.win[0].host_addr = 0; in parse_cftable_entry()
1167 return -EINVAL; in parse_cftable_entry()
1170 entry->mem.nwin = 1; in parse_cftable_entry()
1171 entry->mem.win[0].len = get_unaligned_le16(p) << 8; in parse_cftable_entry()
1172 entry->mem.win[0].card_addr = get_unaligned_le16(p + 2) << 8; in parse_cftable_entry()
1173 entry->mem.win[0].host_addr = 0; in parse_cftable_entry()
1176 return -EINVAL; in parse_cftable_entry()
1179 p = parse_mem(p, q, &entry->mem); in parse_cftable_entry()
1181 return -EINVAL; in parse_cftable_entry()
1188 return -EINVAL; in parse_cftable_entry()
1189 entry->flags |= (*p << 8); in parse_cftable_entry()
1192 return -EINVAL; in parse_cftable_entry()
1196 entry->subtuples = q-p; in parse_cftable_entry()
1207 p = (u_char *)tuple->TupleData; in parse_device_geo()
1208 q = p + tuple->TupleDataLen; in parse_device_geo()
1211 if (p > q-6) in parse_device_geo()
1213 geo->geo[n].buswidth = p[0]; in parse_device_geo()
1214 geo->geo[n].erase_block = 1 << (p[1]-1); in parse_device_geo()
1215 geo->geo[n].read_block = 1 << (p[2]-1); in parse_device_geo()
1216 geo->geo[n].write_block = 1 << (p[3]-1); in parse_device_geo()
1217 geo->geo[n].partition = 1 << (p[4]-1); in parse_device_geo()
1218 geo->geo[n].interleave = 1 << (p[5]-1); in parse_device_geo()
1221 geo->ngeo = n; in parse_device_geo()
1230 if (tuple->TupleDataLen < 10) in parse_vers_2()
1231 return -EINVAL; in parse_vers_2()
1233 p = tuple->TupleData; in parse_vers_2()
1234 q = p + tuple->TupleDataLen; in parse_vers_2()
1236 v2->vers = p[0]; in parse_vers_2()
1237 v2->comply = p[1]; in parse_vers_2()
1238 v2->dindex = get_unaligned_le16(p + 2); in parse_vers_2()
1239 v2->vspec8 = p[6]; in parse_vers_2()
1240 v2->vspec9 = p[7]; in parse_vers_2()
1241 v2->nhdr = p[8]; in parse_vers_2()
1243 return parse_strings(p, q, 2, v2->str, &v2->vendor, NULL); in parse_vers_2()
1252 p = tuple->TupleData; in parse_org()
1253 q = p + tuple->TupleDataLen; in parse_org()
1255 return -EINVAL; in parse_org()
1256 org->data_org = *p; in parse_org()
1258 return -EINVAL; in parse_org()
1260 org->desc[i] = *p; in parse_org()
1264 return -EINVAL; in parse_org()
1274 if (tuple->TupleDataLen < 10) in parse_format()
1275 return -EINVAL; in parse_format()
1277 p = tuple->TupleData; in parse_format()
1279 fmt->type = p[0]; in parse_format()
1280 fmt->edc = p[1]; in parse_format()
1281 fmt->offset = get_unaligned_le32(p + 2); in parse_format()
1282 fmt->length = get_unaligned_le32(p + 6); in parse_format()
1292 if (tuple->TupleDataLen > tuple->TupleDataMax) in pcmcia_parse_tuple()
1293 return -EINVAL; in pcmcia_parse_tuple()
1294 switch (tuple->TupleCode) { in pcmcia_parse_tuple()
1297 ret = parse_device(tuple, &parse->device); in pcmcia_parse_tuple()
1300 ret = parse_checksum(tuple, &parse->checksum); in pcmcia_parse_tuple()
1304 ret = parse_longlink(tuple, &parse->longlink); in pcmcia_parse_tuple()
1307 ret = parse_longlink_mfc(tuple, &parse->longlink_mfc); in pcmcia_parse_tuple()
1310 ret = parse_vers_1(tuple, &parse->version_1); in pcmcia_parse_tuple()
1313 ret = parse_altstr(tuple, &parse->altstr); in pcmcia_parse_tuple()
1317 ret = parse_jedec(tuple, &parse->jedec); in pcmcia_parse_tuple()
1320 ret = parse_manfid(tuple, &parse->manfid); in pcmcia_parse_tuple()
1323 ret = parse_funcid(tuple, &parse->funcid); in pcmcia_parse_tuple()
1326 ret = parse_funce(tuple, &parse->funce); in pcmcia_parse_tuple()
1329 ret = parse_config(tuple, &parse->config); in pcmcia_parse_tuple()
1332 ret = parse_cftable_entry(tuple, &parse->cftable_entry); in pcmcia_parse_tuple()
1336 ret = parse_device_geo(tuple, &parse->device_geo); in pcmcia_parse_tuple()
1339 ret = parse_vers_2(tuple, &parse->vers_2); in pcmcia_parse_tuple()
1342 ret = parse_org(tuple, &parse->org); in pcmcia_parse_tuple()
1346 ret = parse_format(tuple, &parse->format); in pcmcia_parse_tuple()
1353 ret = -EINVAL; in pcmcia_parse_tuple()
1364 * pccard_validate_cis() - check whether card has a sensible CIS
1366 * @info: returns the number of tuples in the (valid) CIS, or 0
1369 * returns the number of tuples in the CIS, or 0 if the CIS looks bad. The
1370 * checks include making sure several critical tuples are present and
1371 * valid; seeing if the total number of tuples is reasonable; and
1372 * looking for tuples that use reserved codes.
1384 return -EINVAL; in pccard_validate_cis()
1386 if (s->functions || !(s->state & SOCKET_PRESENT)) { in pccard_validate_cis()
1388 return -EINVAL; in pccard_validate_cis()
1392 mutex_lock(&s->ops_mutex); in pccard_validate_cis()
1394 mutex_unlock(&s->ops_mutex); in pccard_validate_cis()
1398 dev_warn(&s->dev, "no memory to validate CIS\n"); in pccard_validate_cis()
1399 return -ENOMEM; in pccard_validate_cis()
1404 dev_warn(&s->dev, "no memory to validate CIS\n"); in pccard_validate_cis()
1405 return -ENOMEM; in pccard_validate_cis()
1409 tuple->DesiredTuple = RETURN_FIRST_TUPLE; in pccard_validate_cis()
1410 tuple->Attributes = TUPLE_RETURN_COMMON; in pccard_validate_cis()
1417 if ((tuple->TupleCode == CISTPL_DEVICE) || in pccard_validate_cis()
1423 tuple, for card identification. Certain old D-Link and Linksys in pccard_validate_cis()
1427 (pccard_read_tuple(s, BIND_FN_ALL, CISTPL_VERS_2, p) != -ENOSPC)) in pccard_validate_cis()
1437 if (((tuple->TupleCode > 0x23) && (tuple->TupleCode < 0x40)) || in pccard_validate_cis()
1438 ((tuple->TupleCode > 0x47) && (tuple->TupleCode < 0x80)) || in pccard_validate_cis()
1439 ((tuple->TupleCode > 0x90) && (tuple->TupleCode < 0xff))) in pccard_validate_cis()
1451 mutex_lock(&s->ops_mutex); in pccard_validate_cis()
1453 mutex_unlock(&s->ops_mutex); in pccard_validate_cis()
1458 ret = -EIO; in pccard_validate_cis()
1460 ret = -EFAULT; in pccard_validate_cis()
1485 return -ENOMEM; in pccard_extract_cis()
1489 ret = -ENOMEM; in pccard_extract_cis()
1555 count = size - off; in pccard_show_cis()
1559 if (!(s->state & SOCKET_PRESENT)) in pccard_show_cis()
1560 return -ENODEV; in pccard_show_cis()
1561 if (!s->functions && pccard_validate_cis(s, &chains)) in pccard_show_cis()
1562 return -EIO; in pccard_show_cis()
1564 return -ENODATA; in pccard_show_cis()
1587 return -EINVAL; in pccard_store_cis()
1590 return -EINVAL; in pccard_store_cis()
1592 if (!(s->state & SOCKET_PRESENT)) in pccard_store_cis()
1593 return -ENODEV; in pccard_store_cis()
1597 return -EIO; in pccard_store_cis()