use dmb/dsb from asm/cpu.h file.
[AROS.git] / workbench / libs / pccard / tuple.c
blobea19a978a8c45da7032a10d682c14393baa0daa9
1 /*
2 Copyright © 2011, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 /*
8 File: tuple.c
9 Copyright (C) 1999 David A. Hinds
10 Copyright (C) 2001,2002 Neil Cafferkey
12 Licensed under the AROS PUBLIC LICENSE (APL) Version 1.1
17 #include <exec/memory.h>
18 #include <utility/tagitem.h>
20 #include <proto/exec.h>
21 #include <proto/utility.h>
22 #include <proto/pccard.h>
24 #include "pccard_intern.h"
26 #define MAX_TUPLE PCCARD_TPL_ORG
28 #define MAX_POWER_COUNT 3
29 #define POWER_PARAM_COUNT 7
30 #define TIMING_COUNT 3
32 #define MAX_REGION_COUNT 4
35 static const struct TagItem device_tag_list[]=
37 {PCCARD_RegionCount,0},
38 {PCCARD_RegionLists,0},
39 {TAG_END}
43 static const struct TagItem longlinkcb_tag_list[]=
45 {TAG_END}
49 static const struct TagItem configcb_tag_list[]=
51 {TAG_END}
55 static const struct TagItem cftableentrycb_tag_list[]=
57 {TAG_END}
61 static const struct TagItem longlinkmfc_tag_list[]=
63 {TAG_END}
67 static const struct TagItem bar_tag_list[]=
69 {TAG_END}
73 static const struct TagItem checksum_tag_list[]=
75 {TAG_END}
79 static const struct TagItem longlinka_tag_list[]=
81 {TAG_END}
85 static const struct TagItem longlinkc_tag_list[]=
87 {TAG_END}
91 static const struct TagItem linktarget_tag_list[]=
93 {TAG_END}
97 static const struct TagItem nolink_tag_list[]=
99 {TAG_END}
103 static const struct TagItem vers1_tag_list[]=
105 {PCCARD_MajorVersion,0},
106 {PCCARD_MinorVersion,0},
107 {PCCARD_InfoStringCount,0},
108 {PCCARD_InfoStrings,0},
109 {TAG_END}
113 static const struct TagItem altstr_tag_list[]=
115 {TAG_END}
119 static const struct TagItem jedecc_tag_list[]=
121 {TAG_END}
125 static const struct TagItem jedeca_tag_list[]=
127 {TAG_END}
131 static const struct TagItem config_tag_list[]=
133 {PCCARD_RegisterBase,0},
134 {PCCARD_ModeCount,0},
135 {TAG_END}
139 static const struct TagItem cftableentry_tag_list[]=
141 {PCCARD_ModeNo,0},
142 {PCCARD_Flags,0},
143 {PCCARD_VCCPowerTags,0},
144 {PCCARD_VPP1PowerTags,0},
145 {PCCARD_VPP2PowerTags,0},
146 {PCCARD_WaitTimingTags,0},
147 {PCCARD_ReadyTimingTags,0},
148 {PCCARD_ReservedTimingTags,0},
149 {PCCARD_IOFlags,0},
150 {PCCARD_IOLineCount,0},
151 {PCCARD_IOWinCount,0},
152 {PCCARD_IOWinBases,0},
153 {PCCARD_IOWinLengths,0},
154 {PCCARD_IRQFlags,0},
155 {PCCARD_IRQMask,0},
156 {PCCARD_MemWinCount,0},
157 {PCCARD_MemWinBases,0},
158 {PCCARD_MemWinHostBases,0},
159 {PCCARD_MemWinLengths,0},
160 {TAG_END}
164 static const struct TagItem deviceoc_tag_list[]=
166 {TAG_END}
170 static const struct TagItem deviceoa_tag_list[]=
172 {TAG_END}
176 static const struct TagItem devicegeo_tag_list[]=
178 {TAG_END}
182 static const struct TagItem devicegeoa_tag_list[]=
184 {TAG_END}
188 static const struct TagItem manfid_tag_list[]=
190 {PCCARD_Maker,0},
191 {PCCARD_Product,0},
192 {TAG_END}
196 static const struct TagItem funcid_tag_list[]=
198 {PCCARD_Type,0},
199 {PCCARD_Flags,0},
200 {TAG_END}
204 static const struct TagItem funce_tag_list[]=
206 {TAG_END}
210 static const struct TagItem swil_tag_list[]=
212 {TAG_END}
216 static const struct TagItem vers2_tag_list[]=
218 {TAG_END}
222 static const struct TagItem format_tag_list[]=
224 {TAG_END}
228 static const struct TagItem geometry_tag_list[]=
230 {TAG_END}
234 static const struct TagItem byteorder_tag_list[]=
236 {TAG_END}
240 static const struct TagItem date_tag_list[]=
242 {TAG_END}
246 static const struct TagItem battery_tag_list[]=
248 {TAG_END}
252 static const struct TagItem org_tag_list[]=
254 {TAG_END}
258 static const struct TagItem *const tag_lists[]=
260 NULL,
261 device_tag_list,
262 longlinkcb_tag_list,
263 NULL,
264 configcb_tag_list,
265 cftableentrycb_tag_list,
266 longlinkmfc_tag_list,
267 bar_tag_list,
268 NULL,
269 NULL,
270 NULL,
271 NULL,
272 NULL,
273 NULL,
274 NULL,
275 NULL,
276 checksum_tag_list,
277 longlinka_tag_list,
278 longlinkc_tag_list,
279 linktarget_tag_list,
280 nolink_tag_list,
281 vers1_tag_list,
282 altstr_tag_list,
283 device_tag_list,
284 jedecc_tag_list,
285 jedeca_tag_list,
286 config_tag_list,
287 cftableentry_tag_list,
288 deviceoc_tag_list,
289 deviceoa_tag_list,
290 devicegeo_tag_list,
291 devicegeoa_tag_list,
292 manfid_tag_list,
293 funcid_tag_list,
294 funce_tag_list,
295 swil_tag_list,
296 NULL,
297 NULL,
298 NULL,
299 NULL,
300 NULL,
301 NULL,
302 NULL,
303 NULL,
304 NULL,
305 NULL,
306 NULL,
307 NULL,
308 NULL,
309 NULL,
310 NULL,
311 NULL,
312 NULL,
313 NULL,
314 NULL,
315 NULL,
316 NULL,
317 NULL,
318 NULL,
319 NULL,
320 NULL,
321 NULL,
322 NULL,
323 NULL,
324 vers2_tag_list,
325 format_tag_list,
326 geometry_tag_list,
327 byteorder_tag_list,
328 date_tag_list,
329 battery_tag_list,
330 org_tag_list
334 static const struct TagItem power_tag_list[]=
336 {PCCARD_NominalVoltage,0},
337 {PCCARD_MinVoltage,0},
338 {PCCARD_MaxVoltage,0},
339 {PCCARD_StaticCurrent,0},
340 {PCCARD_AverageCurrent,0},
341 {PCCARD_PeakCurrent,0},
342 {PCCARD_DownCurrent,0},
343 {PCCARD_Flags,0},
344 {TAG_END}
348 static const struct TagItem timing_tag_list[]=
350 {PCCARD_Value,0},
351 {PCCARD_Scale,0},
352 {TAG_END}
356 static const struct TagItem region_tag_list[]=
358 {PCCARD_Flags,0},
359 {PCCARD_Type,0},
360 {PCCARD_Speed,0},
361 {PCCARD_Base,0},
362 {PCCARD_Length,0},
363 {TAG_END}
367 static const Tag sublist_tags[]=
369 PCCARD_VCCPowerTags,
370 PCCARD_VPP1PowerTags,
371 PCCARD_VPP2PowerTags,
372 PCCARD_WaitTimingTags,
373 PCCARD_ReadyTimingTags,
374 PCCARD_ReservedTimingTags,
375 TAG_END
379 static const Tag array_tags[]=
381 PCCARD_IOWinBases,
382 PCCARD_IOWinLengths,
383 PCCARD_MemWinBases,
384 PCCARD_MemWinHostBases,
385 PCCARD_MemWinLengths,
386 TAG_END
390 static const Tag string_array_tags[]=
392 PCCARD_InfoStrings,
393 TAG_END
396 #if !defined(__AROS__)
397 static const Tag sublist_array_tags[]=
399 PCCARD_RegionLists,
400 TAG_END
402 #endif
404 static const UBYTE region_speeds[]=
406 0,250,200,150,100
410 static const UBYTE mantissas[]=
412 10,12,13,15,20,25,30,35,40,45,50,55,60,70,80,90
416 static const ULONG exponents[]=
418 1,10,100,1000,10000,100000,1000000,10000000
422 /* Convert an extended speed byte to a time in nanoseconds */
423 #define SPEED_CVT(v) \
424 (mantissas[(((v)>>3)&0xf)-1]*exponents[(v)&0x7]/10)
427 /* Convert a power byte to a current in 0.1 microamps */
428 #define POWER_CVT(v) \
429 (mantissas[((v)>>3)&0xf]*exponents[(v)&0x7]/10)
432 #define POWER_SCALE(v) (exponents[(v)&0x7])
436 static BOOL ParseDevice(const UBYTE *tuple,struct TagItem *tag_list,
437 struct PCCardBase *base);
438 static BOOL ParseVers1(const UBYTE *tuple,struct TagItem *tag_list,
439 struct PCCardBase *base);
440 static BOOL ParseConfig(const UBYTE *tuple,struct TagItem *tag_list,
441 struct PCCardBase *base);
442 static BOOL ParseCfTableEntry(const UBYTE *tuple,struct TagItem *tag_list,
443 struct PCCardBase *base);
444 static BOOL ParseManfID(const UBYTE *tuple,struct TagItem *tag_list,
445 struct PCCardBase *base);
446 static BOOL ParseFuncID(const UBYTE *tuple,struct TagItem *tag_list,
447 struct PCCardBase *base);
448 static BOOL ParseStrings(const UBYTE *tuple,struct TagItem *tag_list,
449 struct PCCardBase *base);
450 static ULONG StrLen(const TEXT *s);
454 /****** pccard.library/PCCard_GetTupleInfo *********************************
456 * NAME
457 * PCCard_GetTupleInfo -- Parse a CIS tuple.
459 * SYNOPSIS
460 * tag_list = PCCard_GetTupleInfo(tuple)
461 * D0 A0
463 * struct TagItem *PCCard_GetTupleInfo(UBYTE *);
465 * FUNCTION
466 * Reads the information held within a CIS tuple and presents it in the
467 * form of a tag list. The returned tag list is read-only and must be
468 * relinquished via PCCard_FreeTupleInfo().
470 * The tags available for each tuple type are described below.
472 * PCCARD_TPL_DEVICE/PCCARD_TPL_DEVICEA:
473 * PCCARD_RegionCount - The number of memory regions in either
474 * common memory (PCCARD_TPL_DEVICE) or attribute memory
475 * (PCCARD_TPL_DEVICEA).
476 * PCCARD_RegionLists - An array of tag lists, one for each memory
477 * region. Each sub-list may have the following tags:
478 * PCCARD_Flags - Currently only PCCARD_REGIONF_WP (write
479 * protection) is defined.
480 * PCCARD_Type - Region's memory type.
481 * PCCARD_Speed - Speed in nanoseconds.
482 * PCCARD_Base - Offset of start of region.
483 * PCCARD_Length - Length of region.
485 * PCCARD_TPL_VERS1:
486 * PCCARD_MajorVersion - ?
487 * PCCARD_MinorVersion - ?
488 * PCCARD_InfoStringCount - Number of strings available.
489 * PCCARD_InfoStrings - An array of card information strings.
491 * PCCARD_TPL_CONFIG:
492 * PCCARD_RegisterBase - Offset within attribute memory of
493 * configuration registers.
494 * PCCARD_ModeCount - Number of operating modes.
496 * PCCARD_TPL_CFTABLEENTRY:
497 * PCCARD_ModeNo - Value to write to the COR to select this mode.
498 * PCCARD_Flags - See pccard.h for details.
499 * PCCARD_VCCPowerTags - Tag list for VCC power. The following tags
500 * may be present (voltages in 10-uV units, currents in 100-nA
501 * units):
502 * PCCARD_NominalVoltage - Nominal supply voltage.
503 * PCCARD_MinVoltage - Maximum supply voltage.
504 * PCCARD_MaxVoltage - Minimum supply voltage.
505 * PCCARD_StaticCurrent - Continuous supply current required.
506 * PCCARD_AverageCurrent - Maximum current averaged over one
507 * second.
508 * PCCARD_PeakCurrent - Maximum current averaged over 10 ms.
509 * PCCARD_DownCurrent - Current required in power-down mode.
510 * PCCARD_Flags - See pccard.h for details.
511 * PCCARD_VPP1PowerTags - Tag list for VPP1 power. Uses the same
512 * tags as PCCARD_VCCPowerTags.
513 * PCCARD_VPP2PowerTags - Tag list for VPP2 power. Uses the same
514 * tags as PCCARD_VCCPowerTags.
515 * PCCARD_WaitTimingTags - Tag list for wait timing. The following
516 * tags may be present:
517 * PCCARD_Value - Base value/mantissa (in nanoseconds).
518 * PCCARD_Scale - Multiplier/exponent to be applied to
519 * PCCARD_Value.
520 * PCCARD_ReadyTimingTags - Tag list for ready timing. Uses the
521 * same tags as PCCARD_WaitTimingTags.
522 * PCCARD_ReservedTimingTags - Tag list for reserved timing. Uses
523 * the same tags as PCCARD_WaitTimingTags.
524 * PCCARD_IOFlags - See pccard.h for details.
525 * PCCARD_IOLineCount - Number of IO lines decoded by the card.
526 * PCCARD_IOWinCount - Number of IO windows.
527 * PCCARD_IOWinBases - An array of ULONGs giving the window bases
528 * as offsets into the card's IO space.
529 * PCCARD_IOWinLengths - An array of ULONGs giving the lengths of
530 * the IO windows.
531 * PCCARD_IRQFlags - See pccard.h for details.
532 * PCCARD_IRQMask - Interrupt numbers that may be used.
533 * PCCARD_MemWinCount - Number of memory windows.
534 * PCCARD_MemWinBases - An array of ULONGs giving the window bases
535 * as offsets into the card's memory space.
536 * PCCARD_MemWinHostBases - An array of ULONGs giving the window
537 * bases as offsets into the host memory space.
538 * PCCARD_MemWinLengths - An array of ULONGs giving the lengths of
539 * the memory windows.
541 * PCCARD_TPL_MANFID:
542 * PCCARD_Maker - The card's manufacturer ID.
543 * PCCARD_Product - The card's product ID relative to its
544 * manufacturer.
546 * PCCARD_TPL_FUNCID:
547 * PCCARD_Type - The card's function, eg. network or memory.
548 * PCCARD_Flags - Card initialisation flags.
550 * INPUTS
551 * tuple - Pointer to the tuple.
553 * RESULT
554 * tag_list - A tag list containing the tuple's properties.
556 * EXAMPLE
558 * NOTES
560 * BUGS
562 * SEE ALSO
563 * PCCard_FreeTupleInfo()
565 ****************************************************************************
569 AROS_LH1(struct TagItem *, PCCard_GetTupleInfo,
570 AROS_LHA(const UBYTE*, tuple, A0),
571 struct PCCardBase *, PCCardBase, 5, PCCard)
573 AROS_LIBFUNC_INIT
575 BOOL success=TRUE;
576 struct TagItem *tag_list=NULL;
577 UBYTE tuple_type;
579 tuple_type=tuple[0];
580 if(tuple_type<=MAX_TUPLE)
581 tag_list=CloneTagItems(tag_lists[tuple_type]);
582 if(tag_list==NULL)
583 success=FALSE;
585 if(success)
587 switch(tuple_type)
589 case PCCARD_TPL_DEVICE:
590 case PCCARD_TPL_DEVICEA:
591 ParseDevice(tuple,tag_list,PCCardBase);
592 break;
593 case PCCARD_TPL_VERS1:
594 ParseVers1(tuple,tag_list,PCCardBase);
595 break;
596 case PCCARD_TPL_CONFIG:
597 ParseConfig(tuple,tag_list,PCCardBase);
598 break;
599 case PCCARD_TPL_CFTABLEENTRY:
600 ParseCfTableEntry(tuple,tag_list,PCCardBase);
601 break;
602 case PCCARD_TPL_MANFID:
603 ParseManfID(tuple,tag_list,PCCardBase);
604 break;
605 case PCCARD_TPL_FUNCID:
606 ParseFuncID(tuple,tag_list,PCCardBase);
607 break;
608 default:
609 break;
613 return tag_list;
615 AROS_LIBFUNC_EXIT
620 static BOOL ParseDevice(const UBYTE *tuple,struct TagItem *tag_list,
621 struct PCCardBase *base)
623 BOOL success=TRUE;
624 struct TagItem **lists,*sub_tag_list,*sub_tag;
625 ULONG flags=0,speed=0,region_base=0,region_length;
626 UBYTE region_count;
628 /* Allocate tag-list array */
630 tuple+=2;
632 lists=AllocVec(sizeof(struct TagItem *)*(MAX_REGION_COUNT+1),
633 MEMF_PUBLIC|MEMF_CLEAR);
634 if(lists==NULL)
635 success=FALSE;
637 /* Get region info */
639 if(success)
642 for(region_count=0;*tuple!=0xff;region_count++)
644 sub_tag_list=CloneTagItems(region_tag_list);
645 if(sub_tag_list==NULL)
646 success=FALSE;
648 if(success)
650 lists[region_count]=sub_tag_list;
652 /* Get flags and region type */
654 if((*tuple&0x8)!=0)
655 flags=PCCARD_REGIONF_WP;
656 NextTagItem(&sub_tag_list)->ti_Data=flags;
657 NextTagItem(&sub_tag_list)->ti_Data=*tuple>>4;
659 /* Get speed */
661 sub_tag=NextTagItem(&sub_tag_list);
662 switch(*tuple&0x7)
664 case 0:
665 sub_tag->ti_Tag=TAG_IGNORE;
666 break;
667 case 7:
668 tuple++;
669 speed=SPEED_CVT(*tuple);
670 break;
671 default:
672 speed=region_speeds[*tuple&0x7];
674 sub_tag->ti_Data=speed;
675 tuple++;
677 /* Get base and length */
679 NextTagItem(&sub_tag_list)->ti_Data=region_base;
680 region_length=((*tuple>>3)+1)*(512<<((*tuple&0x7)*2));
681 NextTagItem(&sub_tag_list)->ti_Data=region_length;
682 region_base+=region_length;
683 tuple++;
687 NextTagItem(&tag_list)->ti_Data=region_count;
690 return success;
695 static BOOL ParseVers1(const UBYTE *tuple,struct TagItem *tag_list,
696 struct PCCardBase *base)
698 /* Get version no. */
700 tuple+=2;
701 NextTagItem(&tag_list)->ti_Data=*tuple++;
702 NextTagItem(&tag_list)->ti_Data=*tuple++;
704 /* Get info strings */
706 return ParseStrings(tuple,tag_list,base);
711 static BOOL ParseConfig(const UBYTE *tuple,struct TagItem *tag_list,
712 struct PCCardBase *base)
714 ULONG reg_base=0;
715 UBYTE base_size;
716 const UBYTE *p,*q;
718 p=tuple+2;
719 base_size=(*p++)&0x3;
721 FindTagItem(PCCARD_ModeCount,tag_list)->ti_Data=*(p++);
723 for(q=p+base_size;q>=p;q--)
725 reg_base<<=8;
726 reg_base|=*q;
729 FindTagItem(PCCARD_RegisterBase,tag_list)->ti_Data=reg_base;
731 return TRUE;
736 static BOOL ParseCfTableEntry(const UBYTE *tuple,struct TagItem *tag_list,
737 struct PCCardBase *base)
739 ULONG n,flags=0,scale,*win_bases = NULL,*host_bases = NULL,*win_lengths = NULL;
740 UBYTE base_size,length_size,i=0,j,present,power_count,features,
741 timing_scales[TIMING_COUNT],win_count=0,sub_flags=0,sizes=0,mask=0;
742 const UBYTE *p,*q;
743 struct TagItem *tag,*temp_tag=tag_list,*temp_sub_tag,*sub_tag,
744 *sub_tag_list;
745 BOOL success=TRUE;
747 /* Get mode no. */
749 p=tuple+2;
750 NextTagItem(&temp_tag)->ti_Data=*p&0x3f;
752 if(*p&0x40)
753 flags|=PCCARD_CFTABLEF_DEFAULT;
754 if(*p&0x80)
755 p++;
757 NextTagItem(&temp_tag)->ti_Data=flags;
759 features=*(++p);
760 p++;
762 /* Parse power data */
764 for(power_count=features&0x3;i<MAX_POWER_COUNT;i++)
766 tag=NextTagItem(&temp_tag);
768 if(i<power_count)
770 temp_sub_tag=sub_tag_list=CloneTagItems(power_tag_list);
771 if(sub_tag_list==NULL)
772 success=FALSE;
774 if(success)
776 present=*(p++);
777 flags=0;
778 for(j=0;j<POWER_PARAM_COUNT;j++)
780 sub_tag=NextTagItem(&temp_sub_tag);
782 if((present&1)!=0)
784 n=POWER_CVT(*p);
785 scale=POWER_SCALE(*p);
786 while((*(p++)&0x80)!=0)
788 if((*p&0x7f)<100)
789 n+=(*p&0x7f)*scale/100;
790 else if(*p==0x7d)
791 flags|=PCCARD_POWERF_HIGHZOK;
792 else if(*p==0x7e)
793 n=0;
794 else if(*p==0x7f)
795 flags|=PCCARD_POWERF_HIGHZREQ;
797 sub_tag->ti_Data=n;
799 else
800 sub_tag->ti_Tag=TAG_IGNORE;
802 present>>=1;
804 NextTagItem(&temp_sub_tag)->ti_Data=flags;
807 tag->ti_Data=(UPINT)sub_tag_list;
809 else
810 tag->ti_Tag=TAG_IGNORE;
813 /* Parse timing data */
815 if((features&0x4)!=0)
817 scale=*(p++);
818 scale<<=1;
819 scale|=0x1;
820 for(i=0;i<TIMING_COUNT;i++)
822 timing_scales[i]=scale&0x7;
823 scale>>=3;
825 if(timing_scales[0]!=7)
826 timing_scales[0]>>=1;
828 for(i=0;i<TIMING_COUNT;i++)
830 tag=NextTagItem(&temp_tag);
832 if(timing_scales[i]!=7)
834 temp_sub_tag=sub_tag_list=CloneTagItems(timing_tag_list);
835 if(sub_tag_list==NULL)
836 success=FALSE;
838 if(success)
840 p++;
841 NextTagItem(&temp_sub_tag)->ti_Data=SPEED_CVT(*p);
842 NextTagItem(&temp_sub_tag)->ti_Data=
843 exponents[timing_scales[i]];
846 tag->ti_Data=(UPINT)sub_tag_list;
848 else
849 tag->ti_Tag=TAG_IGNORE;
852 p++;
854 else
856 tag=NextTagItem(&temp_tag);
857 tag->ti_Tag=TAG_SKIP;
858 tag->ti_Data=TIMING_COUNT-1;
859 temp_tag=tag;
862 /* Parse IO windows data */
864 if((features&0x8)!=0)
866 sub_flags=*p;
868 if((sub_flags&0x80)!=0)
870 p++;
871 sizes=*(p++);
872 win_count=(sizes&0xf)+1;
873 sizes>>=4;
874 base_size=1<<((sizes&0x3)-1);
875 sizes>>=2;
876 length_size=1<<((sizes&0x3)-1);
878 else
880 win_count=1;
883 win_bases=AllocVec(win_count*sizeof(ULONG),MEMF_PUBLIC);
884 win_lengths=AllocVec(win_count*sizeof(ULONG),MEMF_PUBLIC);
885 if((win_bases==NULL)||(win_lengths==NULL))
886 success=FALSE;
888 if(success)
890 if((sub_flags&0x80)!=0)
892 for(i=0;i<win_count;i++)
894 for(n=0,q=p+base_size;q>p;n|=*(--q))
895 n<<=8;
896 win_bases[i]=n;
897 p+=base_size;
899 for(n=0,q=p+length_size;q>p;n|=*(--q))
900 n<<=8;
901 win_lengths[i]=n+1;
902 p+=length_size;
905 else
907 *win_bases=0;
908 *win_lengths=1<<(sub_flags&0x1f);
913 tag=NextTagItem(&temp_tag);
914 if((features&0x8)==0)
915 tag->ti_Tag=TAG_IGNORE;
916 tag->ti_Data=sub_flags&(PCCARD_IOF_8BIT|PCCARD_IOF_16BIT);
918 tag=NextTagItem(&temp_tag);
919 if((features&0x8)==0)
920 tag->ti_Tag=TAG_IGNORE;
921 tag->ti_Data=sub_flags&0x1f;
923 tag=NextTagItem(&temp_tag);
924 if((features&0x8)==0)
925 tag->ti_Tag=TAG_IGNORE;
926 tag->ti_Data=win_count;
928 tag=NextTagItem(&temp_tag);
929 if((features&0x8)==0)
930 tag->ti_Tag=TAG_IGNORE;
931 tag->ti_Data=(UPINT)win_bases;
933 tag=NextTagItem(&temp_tag);
934 if((features&0x8)==0)
935 tag->ti_Tag=TAG_IGNORE;
936 tag->ti_Data=(UPINT)win_lengths;
938 /* Parse IRQ data */
940 if((features&0x10)!=0)
942 sub_flags=*(p++);
943 if((sub_flags&0x10)!=0)
945 mask=*(p++);
947 else
949 mask=1<<(sub_flags&0xf); /* TO DO: check if single interrupt is "desired" or "allowed" */
950 sub_flags&=0xe0;
954 tag=NextTagItem(&temp_tag);
955 if((features&0x10)==0)
956 tag->ti_Tag=TAG_IGNORE;
957 tag->ti_Data=sub_flags;
959 tag=NextTagItem(&temp_tag);
960 if((features&0x10)==0)
961 tag->ti_Tag=TAG_IGNORE;
962 tag->ti_Data=mask;
964 /* Parse memory windows data */
966 if((features&0x60)!=0)
968 if((features&0x60)==0x60)
970 sizes=*(p++);
971 win_count=(sizes&0x7)+1;
972 sizes>>=3;
973 length_size=sizes&0x3;
974 sizes>>=2;
975 base_size=sizes&0x3;
976 sizes&=0x4;
978 else
980 sizes=0;
981 win_count=1;
984 win_bases=AllocVec(win_count*sizeof(ULONG),MEMF_PUBLIC);
985 win_lengths=AllocVec(win_count*sizeof(ULONG),MEMF_PUBLIC);
986 if((win_bases==NULL)||(win_lengths==NULL))
987 success=FALSE;
989 if(sizes!=0)
991 host_bases=AllocVec(win_count*sizeof(ULONG),MEMF_PUBLIC);
992 if(host_bases==NULL)
993 success=FALSE;
996 if(success)
998 if((features&0x60)==0x60)
1000 for(i=0;i<win_count;i++)
1002 for(n=0,q=p+length_size;q>p;n<<=8)
1003 n|=*(--q);
1004 win_lengths[i]=n;
1005 p+=length_size;
1007 for(n=0,q=p+base_size;q>p;n<<=8)
1008 n|=*(--q);
1009 win_bases[i]=n;
1010 p+=base_size;
1012 if(sizes!=0)
1014 for(n=0,q=p+base_size;q>p;n<<=8)
1015 n|=*(--q);
1016 host_bases[i]=n;
1017 p+=base_size;
1021 else
1023 *win_lengths=(*p<<8)+(*(p+1)<<16);
1024 p+=2;
1026 if((features&0x40)!=0)
1028 *win_bases=(*p<<8)+(*(p+1)<<16);
1029 p+=2;
1031 else
1032 *win_bases=0;
1037 tag=NextTagItem(&temp_tag);
1038 if((features&0x60)==0)
1039 tag->ti_Tag=TAG_IGNORE;
1040 tag->ti_Data=win_count;
1042 tag=NextTagItem(&temp_tag);
1043 if((features&0x60)==0)
1044 tag->ti_Tag=TAG_IGNORE;
1045 tag->ti_Data=(UPINT)win_bases;
1047 tag=NextTagItem(&temp_tag);
1048 if(((features&0x60)==0)||(sizes==0))
1049 tag->ti_Tag=TAG_IGNORE;
1050 tag->ti_Data=(UPINT)host_bases;
1052 tag=NextTagItem(&temp_tag);
1053 if((features&0x60)==0)
1054 tag->ti_Tag=TAG_IGNORE;
1055 tag->ti_Data=(UPINT)win_lengths;
1057 /* Parse extra flags */
1059 if((features&0x80)!=0)
1060 flags|=*(p++);
1062 /* TO DO: parse extra flags and subtuples */
1065 /* Return */
1067 return success;
1072 static BOOL ParseManfID(const UBYTE *tuple,struct TagItem *tag_list,
1073 struct PCCardBase *base)
1075 /* Get manufacturer and product IDs */
1077 tuple+=2;
1078 NextTagItem(&tag_list)->ti_Data=LEWord(tuple);
1079 tuple+=2;
1080 NextTagItem(&tag_list)->ti_Data=LEWord(tuple);
1082 return TRUE;
1087 static BOOL ParseFuncID(const UBYTE *tuple,struct TagItem *tag_list,
1088 struct PCCardBase *base)
1090 /* Get function and intialisation info */
1092 tuple+=2;
1093 NextTagItem(&tag_list)->ti_Data=*tuple++;
1094 NextTagItem(&tag_list)->ti_Data=*tuple;
1096 return TRUE;
1101 /****** pccard.library/PCCard_FreeTupleInfo ********************************
1103 * NAME
1104 * PCCard_FreeTupleInfo -- Relinquish a CIS tuple tag list.
1106 * SYNOPSIS
1107 * PCCard_FreeTupleInfo(tag_list)
1108 * A0
1110 * VOID PCCard_FreeTupleInfo(struct TagItem *);
1112 * FUNCTION
1113 * Frees a tag list obtained via PCCard_GetTupleInfo().
1115 * INPUTS
1116 * tag_list - Tuple tag list (may be NULL).
1118 * RESULT
1119 * None.
1121 * EXAMPLE
1123 * NOTES
1125 * BUGS
1127 * SEE ALSO
1128 * PCCard_GetTupleInfo()
1130 ****************************************************************************
1134 AROS_LH1(void, PCCard_FreeTupleInfo,
1135 AROS_LHA(struct TagItem*, tag_list, A0),
1136 struct PCCardBase *, PCCardBase, 6, PCCard)
1138 AROS_LIBFUNC_INIT
1140 struct TagItem *tag,*temp_tag;
1141 TEXT **p;
1143 /* Free sub-tag lists and arrays */
1145 if(tag_list!=NULL)
1147 temp_tag=tag_list;
1148 while((tag=NextTagItem(&temp_tag))!=NULL)
1150 if(TagInArray(tag->ti_Tag,(Tag*)sublist_tags)&&(tag->ti_Data!=0))
1151 PCCard_FreeTupleInfo((APTR)tag->ti_Data);
1152 else if(TagInArray(tag->ti_Tag,(Tag*)array_tags))
1153 FreeVec((APTR)tag->ti_Data);
1154 else if(TagInArray(tag->ti_Tag,(Tag*)string_array_tags))
1156 for(p=(APTR)tag->ti_Data;*p!=NULL;p++)
1157 FreeVec(*p);
1162 /* Free main list and return */
1164 FreeTagItems(tag_list);
1165 return;
1167 AROS_LIBFUNC_EXIT
1172 static BOOL ParseStrings(const UBYTE *tuple,struct TagItem *tag_list,
1173 struct PCCardBase *base)
1175 UBYTE i=0,string_count=0,length;
1176 const UBYTE *p;
1177 BOOL success=TRUE;
1178 TEXT **strings;
1180 /* Count strings */
1182 for(p=tuple;*p!=0xff;p++)
1183 if(*p=='\0')
1184 string_count++;
1186 /* Allocate memory for and copy strings */
1188 strings=AllocVec((string_count+1)*sizeof(APTR),MEMF_PUBLIC|MEMF_CLEAR);
1189 if(strings==NULL)
1190 success=FALSE;
1192 if(success)
1194 for(p=tuple;i<string_count;i++)
1196 length=StrLen(p)+1;
1197 strings[i]=AllocVec(length,MEMF_PUBLIC);
1198 if(strings[i]!=NULL)
1199 CopyMem(p,strings[i],length);
1200 else
1201 success=FALSE;
1202 p+=length;
1206 NextTagItem(&tag_list)->ti_Data=string_count;
1207 NextTagItem(&tag_list)->ti_Data=(UPINT)strings;
1209 /* Return */
1211 return success;
1216 static ULONG StrLen(const TEXT *s)
1218 const TEXT *p;
1220 for(p=s;*p!='\0';p++);
1221 return p-s;