Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / usr.sbin / acpitools / aml / aml_common.c
blobd2bf7ed0b5b10fe2afda383e4e45722a73a21c35
1 /* $NetBSD: aml_common.c,v 1.1 2007/01/14 04:36:13 christos Exp $ */
3 /*-
4 * Copyright (c) 1999 Takanori Watanabe
5 * Copyright (c) 1999, 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
6 * All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
29 * Id: aml_common.c,v 1.9 2000/08/09 14:47:43 iwasaki Exp
30 * $FreeBSD: src/usr.sbin/acpi/amldb/aml/aml_common.c,v 1.6 2000/11/09 06:24:45 iwasaki Exp $
32 #include <sys/cdefs.h>
33 __RCSID("$NetBSD: aml_common.c,v 1.1 2007/01/14 04:36:13 christos Exp $");
35 #include <sys/param.h>
37 #ifndef _KERNEL
38 #include <assert.h>
39 #include <err.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <unistd.h>
44 #else /* _KERNEL */
45 #include "opt_acpi.h"
46 #include <sys/kernel.h>
47 #include <sys/sysctl.h>
48 #include <sys/systm.h>
49 #include <sys/bus.h>
50 #include <machine/bus.h>
51 #include <dev/acpi/acpireg.h>
52 #include <dev/acpi/acpivar.h>
53 #ifndef ACPI_NO_OSDFUNC_INLINE
54 #include <machine/acpica_osd.h>
55 #endif /* !ACPI_NO_OSDFUNC_INLINE */
56 #endif /* !_KERNEL */
58 #include <acpi_common.h>
59 #include <aml/aml_common.h>
60 #include <aml/aml_env.h>
61 #include <aml/aml_evalobj.h>
62 #include <aml/aml_name.h>
63 #include <aml/aml_obj.h>
64 #include <aml/aml_parse.h>
65 #include <aml/aml_status.h>
66 #include <aml/aml_store.h>
68 /* for debugging */
69 #ifdef AML_DEBUG
70 int aml_debug = 1;
71 #else /* !AML_DEBUG */
72 int aml_debug = 0;
73 #endif /* AML_DEBUG */
74 #ifdef _KERNEL
75 SYSCTL_INT(_debug, OID_AUTO, aml_debug, CTLFLAG_RW, &aml_debug, 1, "");
76 #endif /* _KERNEL */
78 static void aml_print_nameseg(u_int8_t *dp);
80 static void
81 aml_print_nameseg(u_int8_t *dp)
84 if (dp[3] != '_') {
85 AML_DEBUGPRINT("%c%c%c%c", dp[0], dp[1], dp[2], dp[3]);
86 } else if (dp[2] != '_') {
87 AML_DEBUGPRINT("%c%c%c_", dp[0], dp[1], dp[2]);
88 } else if (dp[1] != '_') {
89 AML_DEBUGPRINT("%c%c__", dp[0], dp[1]);
90 } else if (dp[0] != '_') {
91 AML_DEBUGPRINT("%c___", dp[0]);
95 void
96 aml_print_namestring(u_int8_t *dp)
98 int segcount;
99 int i;
101 if (dp[0] == '\\') {
102 AML_DEBUGPRINT("%c", dp[0]);
103 dp++;
104 } else if (dp[0] == '^') {
105 while (dp[0] == '^') {
106 AML_DEBUGPRINT("%c", dp[0]);
107 dp++;
110 if (dp[0] == 0x00) { /* NullName */
111 /* AML_DEBUGPRINT("<null>"); */
112 dp++;
113 } else if (dp[0] == 0x2e) { /* DualNamePrefix */
114 aml_print_nameseg(dp + 1);
115 AML_DEBUGPRINT("%c", '.');
116 aml_print_nameseg(dp + 5);
117 } else if (dp[0] == 0x2f) { /* MultiNamePrefix */
118 segcount = dp[1];
119 for (i = 0, dp += 2; i < segcount; i++, dp += 4) {
120 if (i > 0) {
121 AML_DEBUGPRINT("%c", '.');
123 aml_print_nameseg(dp);
125 } else /* NameSeg */
126 aml_print_nameseg(dp);
130 aml_print_curname(struct aml_name *name)
132 struct aml_name *root;
134 root = aml_get_rootname();
135 if (name == root) {
136 AML_DEBUGPRINT("\\");
137 return (0);
138 } else {
139 aml_print_curname(name->parent);
141 aml_print_nameseg((unsigned char *)name->name);
142 AML_DEBUGPRINT(".");
143 return (0);
146 void
147 aml_print_indent(int indent)
149 int i;
151 for (i = 0; i < indent; i++)
152 AML_DEBUGPRINT(" ");
155 void
156 aml_showobject(union aml_object * obj)
158 int debug;
159 int i;
161 if (obj == NULL) {
162 printf("NO object\n");
163 return;
165 debug = aml_debug;
166 aml_debug = 1;
167 switch (obj->type) {
168 case aml_t_num:
169 printf("Num:0x%x\n", obj->num.number);
170 break;
171 case aml_t_processor:
172 printf("Processor:No %d,Port 0x%x length 0x%x\n",
173 obj->proc.id, obj->proc.addr, obj->proc.len);
174 break;
175 case aml_t_mutex:
176 printf("Mutex:Level %d\n", obj->mutex.level);
177 break;
178 case aml_t_powerres:
179 printf("PowerResource:Level %d Order %d\n",
180 obj->pres.level, obj->pres.order);
181 break;
182 case aml_t_opregion:
183 printf("OprationRegion:Busspace%d, Offset 0x%x Length 0x%x\n",
184 obj->opregion.space, obj->opregion.offset,
185 obj->opregion.length);
186 break;
187 case aml_t_field:
188 printf("Fieldelement:flag 0x%x offset 0x%x len 0x%x {",
189 obj->field.flags, obj->field.bitoffset,
190 obj->field.bitlen);
191 switch (obj->field.f.ftype) {
192 case f_t_field:
193 aml_print_namestring(obj->field.f.fld.regname);
194 break;
195 case f_t_index:
196 aml_print_namestring(obj->field.f.ifld.indexname);
197 printf(" ");
198 aml_print_namestring(obj->field.f.ifld.dataname);
199 break;
200 case f_t_bank:
201 aml_print_namestring(obj->field.f.bfld.regname);
202 printf(" ");
203 aml_print_namestring(obj->field.f.bfld.bankname);
204 printf("0x%x", obj->field.f.bfld.bankvalue);
205 break;
207 printf("}\n");
208 break;
209 case aml_t_method:
210 printf("Method: Arg %d From %p To %p\n", obj->meth.argnum,
211 obj->meth.from, obj->meth.to);
212 break;
213 case aml_t_buffer:
214 printf("Buffer: size:0x%x Data %p\n", obj->buffer.size,
215 obj->buffer.data);
216 break;
217 case aml_t_device:
218 printf("Device\n");
219 break;
220 case aml_t_bufferfield:
221 printf("Bufferfield:offset 0x%x len 0x%x Origin %p\n",
222 obj->bfld.bitoffset, obj->bfld.bitlen, obj->bfld.origin);
223 break;
224 case aml_t_string:
225 printf("String:%s\n", obj->str.string);
226 break;
227 case aml_t_package:
228 printf("Package:elements %d \n", obj->package.elements);
229 for (i = 0; i < obj->package.elements; i++) {
230 if (obj->package.objects[i] == NULL) {
231 break;
233 if (obj->package.objects[i]->type < 0) {
234 continue;
236 printf(" ");
237 aml_showobject(obj->package.objects[i]);
239 break;
240 case aml_t_therm:
241 printf("Thermalzone\n");
242 break;
243 case aml_t_event:
244 printf("Event\n");
245 break;
246 case aml_t_ddbhandle:
247 printf("DDBHANDLE\n");
248 break;
249 case aml_t_objref:
250 if (obj->objref.alias == 1) {
251 printf("Alias");
252 } else {
253 printf("Object reference");
254 if (obj->objref.offset >= 0) {
255 printf(" (offset 0x%x)", obj->objref.offset);
258 printf(" of ");
259 aml_showobject(obj->objref.ref);
260 break;
261 default:
262 printf("UNK ID=%d\n", obj->type);
265 aml_debug = debug;
268 void
269 aml_showtree(struct aml_name * aname, int lev)
271 int i;
272 struct aml_name *ptr;
273 char name[5];
275 for (i = 0; i < lev; i++) {
276 printf(" ");
278 strncpy(name, aname->name, 4);
279 name[4] = 0;
280 printf("%s ", name);
281 if (aname->property != NULL) {
282 aml_showobject(aname->property);
283 } else {
284 printf("\n");
286 for (ptr = aname->child; ptr; ptr = ptr->brother)
287 aml_showtree(ptr, lev + 1);
291 * Common Region I/O Stuff
294 static __inline u_int64_t
295 aml_adjust_bitmask(u_int32_t flags, u_int32_t bitlen)
297 u_int64_t bitmask;
299 switch (AML_FIELDFLAGS_ACCESSTYPE(flags)) {
300 case AML_FIELDFLAGS_ACCESS_ANYACC:
301 if (bitlen <= 8) {
302 bitmask = 0x000000ff;
303 break;
305 if (bitlen <= 16) {
306 bitmask = 0x0000ffff;
307 break;
309 bitmask = 0xffffffff;
310 break;
311 case AML_FIELDFLAGS_ACCESS_BYTEACC:
312 bitmask = 0x000000ff;
313 break;
314 case AML_FIELDFLAGS_ACCESS_WORDACC:
315 bitmask = 0x0000ffff;
316 break;
317 case AML_FIELDFLAGS_ACCESS_DWORDACC:
318 default:
319 bitmask = 0xffffffff;
320 break;
323 switch (bitlen) {
324 case 16:
325 bitmask |= 0x0000ffff;
326 break;
327 case 32:
328 bitmask |= 0xffffffff;
329 break;
332 return (bitmask);
335 u_int32_t
336 aml_adjust_readvalue(u_int32_t flags, u_int32_t bitoffset, u_int32_t bitlen,
337 u_int32_t orgval)
339 u_int32_t offset, retval;
340 u_int64_t bitmask;
342 offset = bitoffset; /* XXX bitoffset may change in this function! */
343 bitmask = aml_adjust_bitmask(flags, bitlen);
344 retval = (orgval >> offset) & (~(bitmask << bitlen)) & bitmask;
346 return (retval);
349 u_int32_t
350 aml_adjust_updatevalue(u_int32_t flags, u_int32_t bitoffset, u_int32_t bitlen,
351 u_int32_t orgval, u_int32_t value)
353 u_int32_t offset, retval;
354 u_int64_t bitmask;
356 offset = bitoffset; /* XXX bitoffset may change in this function! */
357 bitmask = aml_adjust_bitmask(flags, bitlen);
358 retval = orgval;
359 switch (AML_FIELDFLAGS_UPDATERULE(flags)) {
360 case AML_FIELDFLAGS_UPDATE_PRESERVE:
361 retval &= (~(((u_int64_t)1 << bitlen) - 1) << offset) |
362 (~(bitmask << offset));
363 break;
364 case AML_FIELDFLAGS_UPDATE_WRITEASONES:
365 retval = (~(((u_int64_t)1 << bitlen) - 1) << offset) |
366 (~(bitmask << offset));
367 retval &= bitmask; /* trim the upper bits */
368 break;
369 case AML_FIELDFLAGS_UPDATE_WRITEASZEROS:
370 retval = 0;
371 break;
372 default:
373 printf("illegal update rule: %d\n", flags);
374 return (orgval);
377 retval |= (value << (offset & bitmask));
378 return (retval);
382 * BufferField I/O
385 #define AML_BUFFER_INPUT 0
386 #define AML_BUFFER_OUTPUT 1
388 static int aml_bufferfield_io(int io, u_int32_t *valuep,
389 u_int8_t *origin, u_int32_t bitoffset,
390 u_int32_t bitlen);
392 static int
393 aml_bufferfield_io(int io, u_int32_t *valuep, u_int8_t *origin,
394 u_int32_t bitoffset, u_int32_t bitlen)
396 u_int8_t val, tmp, masklow, maskhigh;
397 u_int8_t offsetlow, offsethigh;
398 u_int8_t *addr;
399 u_int32_t value, readval;
400 u_int32_t byteoffset, bytelen, i;
402 masklow = maskhigh = 0xff;
403 val = readval = 0;
404 value = *valuep;
406 byteoffset = bitoffset / 8;
407 bytelen = bitlen / 8 + ((bitlen % 8) ? 1 : 0);
408 addr = origin + byteoffset;
410 /* simple I/O ? */
411 if (bitlen <= 8 || bitlen == 16 || bitlen == 32) {
412 bcopy(addr, &readval, bytelen);
413 AML_DEBUGPRINT("\n\t[bufferfield:0x%x@%p:%d,%d]",
414 readval, addr, bitoffset % 8, bitlen);
415 switch (io) {
416 case AML_BUFFER_INPUT:
417 value = aml_adjust_readvalue(AML_FIELDFLAGS_ACCESS_BYTEACC,
418 bitoffset % 8, bitlen, readval);
419 *valuep = value;
420 AML_DEBUGPRINT("\n[read(bufferfield, %p)&mask:0x%x]\n",
421 addr, value);
422 break;
423 case AML_BUFFER_OUTPUT:
424 value = aml_adjust_updatevalue(AML_FIELDFLAGS_ACCESS_BYTEACC,
425 bitoffset % 8, bitlen, readval, value);
426 bcopy(&value, addr, bytelen);
427 AML_DEBUGPRINT("->[bufferfield:0x%x@%p:%d,%d]",
428 value, addr, bitoffset % 8, bitlen);
429 break;
431 goto out;
434 offsetlow = bitoffset % 8;
435 if (bytelen > 1) {
436 offsethigh = (bitlen - (8 - offsetlow)) % 8;
437 } else {
438 offsethigh = 0;
441 if (offsetlow) {
442 masklow = (~((1 << bitlen) - 1) << offsetlow) | ~(0xff << offsetlow);
443 AML_DEBUGPRINT("\t[offsetlow = 0x%x, masklow = 0x%x, ~masklow = 0x%x]\n",
444 offsetlow, masklow, ~masklow & 0xff);
446 if (offsethigh) {
447 maskhigh = 0xff << offsethigh;
448 AML_DEBUGPRINT("\t[offsethigh = 0x%x, maskhigh = 0x%x, ~maskhigh = 0x%x]\n",
449 offsethigh, maskhigh, ~maskhigh & 0xff);
451 for (i = bytelen; i > 0; i--, addr++) {
452 val = *addr;
454 AML_DEBUGPRINT("\t[bufferfield:0x%02x@%p]", val, addr);
456 switch (io) {
457 case AML_BUFFER_INPUT:
458 tmp = val;
459 /* the lowest byte? */
460 if (i == bytelen) {
461 if (offsetlow) {
462 readval = tmp & ~masklow;
463 } else {
464 readval = tmp;
466 } else {
467 if (i == 1 && offsethigh) {
468 tmp = tmp & ~maskhigh;
470 readval = (tmp << (8 * (bytelen - i))) | readval;
473 AML_DEBUGPRINT("\n");
474 /* goto to next byte... */
475 if (i > 1) {
476 continue;
478 /* final adjustment before finishing region access */
479 if (offsetlow) {
480 readval = readval >> offsetlow;
482 AML_DEBUGPRINT("[read(bufferfield, %p)&mask:0x%x]\n",
483 addr, readval);
484 *valuep = readval;
486 break;
488 case AML_BUFFER_OUTPUT:
489 tmp = value & 0xff;
490 /* the lowest byte? */
491 if (i == bytelen) {
492 if (offsetlow) {
493 tmp = (val & masklow) | tmp << offsetlow;
495 value = value >> (8 - offsetlow);
496 } else {
497 if (i == 1 && offsethigh) {
498 tmp = (val & maskhigh) | tmp;
500 value = value >> 8;
503 AML_DEBUGPRINT("->[bufferfield:0x%02x@%p]\n",
504 tmp, addr);
505 *addr = tmp;
508 out:
509 return (0);
512 u_int32_t
513 aml_bufferfield_read(u_int8_t *origin, u_int32_t bitoffset,
514 u_int32_t bitlen)
516 int value;
518 value = 0;
519 aml_bufferfield_io(AML_BUFFER_INPUT, (u_int32_t *)&value, origin,
520 bitoffset, bitlen);
521 return (value);
525 aml_bufferfield_write(u_int32_t value, u_int8_t *origin,
526 u_int32_t bitoffset, u_int32_t bitlen)
528 int status;
530 status = aml_bufferfield_io(AML_BUFFER_OUTPUT, &value,
531 origin, bitoffset, bitlen);
532 return (status);
536 aml_region_handle_alloc(struct aml_environ *env, int regtype, u_int32_t flags,
537 u_int32_t baseaddr, u_int32_t bitoffset, u_int32_t bitlen,
538 struct aml_region_handle *h)
540 int state;
541 struct aml_name *pci_info;
543 state = 0;
544 pci_info = NULL;
545 bzero(h, sizeof(struct aml_region_handle));
547 h->env = env;
548 h->regtype = regtype;
549 h->flags = flags;
550 h->baseaddr = baseaddr;
551 h->bitoffset = bitoffset;
552 h->bitlen = bitlen;
554 switch (AML_FIELDFLAGS_ACCESSTYPE(flags)) {
555 case AML_FIELDFLAGS_ACCESS_ANYACC:
556 if (bitlen <= 8) {
557 h->unit = 1;
558 break;
560 if (bitlen <= 16) {
561 h->unit = 2;
562 break;
564 h->unit = 4;
565 break;
566 case AML_FIELDFLAGS_ACCESS_BYTEACC:
567 h->unit = 1;
568 break;
569 case AML_FIELDFLAGS_ACCESS_WORDACC:
570 h->unit = 2;
571 break;
572 case AML_FIELDFLAGS_ACCESS_DWORDACC:
573 h->unit = 4;
574 break;
575 default:
576 h->unit = 1;
577 break;
580 h->addr = baseaddr + h->unit * ((bitoffset / 8) / h->unit);
581 h->bytelen = baseaddr + ((bitoffset + bitlen) / 8) - h->addr +
582 ((bitlen % 8) ? 1 : 0);
584 #ifdef _KERNEL
585 switch (h->regtype) {
586 case AML_REGION_SYSMEM:
587 OsdMapMemory((void *)h->addr, h->bytelen, (void **)&h->vaddr);
588 break;
590 case AML_REGION_PCICFG:
591 /* Obtain PCI bus number */
592 pci_info = aml_search_name(env, "_BBN");
593 if (pci_info == NULL || pci_info->property->type != aml_t_num) {
594 AML_DEBUGPRINT("Cannot locate _BBN. Using default 0\n");
595 h->pci_bus = 0;
596 } else {
597 AML_DEBUGPRINT("found _BBN: %d\n",
598 pci_info->property->num.number);
599 h->pci_bus = pci_info->property->num.number & 0xff;
602 /* Obtain device & function number */
603 pci_info = aml_search_name(env, "_ADR");
604 if (pci_info == NULL || pci_info->property->type != aml_t_num) {
605 printf("Cannot locate: _ADR\n");
606 state = -1;
607 goto out;
609 h->pci_devfunc = pci_info->property->num.number;
611 AML_DEBUGPRINT("[pci%d.%d]", h->pci_bus, h->pci_devfunc);
612 break;
614 default:
615 break;
618 out:
619 #endif /* _KERNEL */
620 return (state);
623 void
624 aml_region_handle_free(struct aml_region_handle *h)
626 #ifdef _KERNEL
627 switch (h->regtype) {
628 case AML_REGION_SYSMEM:
629 OsdUnMapMemory((void *)h->vaddr, h->bytelen);
630 break;
632 default:
633 break;
635 #endif /* _KERNEL */
638 static int
639 aml_region_io_simple(struct aml_environ *env, int io, int regtype,
640 u_int32_t flags, u_int32_t *valuep, u_int32_t baseaddr,
641 u_int32_t bitoffset, u_int32_t bitlen)
643 int state;
644 u_int32_t readval, value, offset, bytelen, i;
645 struct aml_region_handle handle;
647 state = aml_region_handle_alloc(env, regtype, flags,
648 baseaddr, bitoffset, bitlen, &handle);
649 if (state == -1) {
650 goto out;
653 readval = 0;
654 offset = bitoffset % (handle.unit * 8);
655 /* limitation of 32 bits alignment */
656 bytelen = (handle.bytelen > 4) ? 4 : handle.bytelen;
658 if (io == AML_REGION_INPUT ||
659 AML_FIELDFLAGS_UPDATERULE(flags) == AML_FIELDFLAGS_UPDATE_PRESERVE) {
660 for (i = 0; i < bytelen; i += handle.unit) {
661 state = aml_region_read_simple(&handle, i, &value);
662 if (state == -1) {
663 goto out;
665 readval |= (value << (i * 8));
667 AML_DEBUGPRINT("\t[%d:0x%x@0x%lx:%d,%d]",
668 regtype, readval, handle.addr, offset, bitlen);
671 switch (io) {
672 case AML_REGION_INPUT:
673 AML_DEBUGPRINT("\n");
674 readval = aml_adjust_readvalue(flags, offset, bitlen, readval);
675 value = readval;
676 value = aml_region_prompt_read(&handle, value);
677 state = aml_region_prompt_update_value(readval, value, &handle);
678 if (state == -1) {
679 goto out;
682 *valuep = value;
683 break;
684 case AML_REGION_OUTPUT:
685 value = *valuep;
686 value = aml_adjust_updatevalue(flags, offset,
687 bitlen, readval, value);
688 value = aml_region_prompt_write(&handle, value);
689 AML_DEBUGPRINT("\t->[%d:0x%x@0x%lx:%d,%d]\n", regtype, value,
690 handle.addr, offset, bitlen);
691 for (i = 0; i < bytelen; i += handle.unit) {
692 state = aml_region_write_simple(&handle, i, value);
693 if (state == -1) {
694 goto out;
696 value = value >> (handle.unit * 8);
698 break;
701 aml_region_handle_free(&handle);
702 out:
703 return (state);
707 aml_region_io(struct aml_environ *env, int io, int regtype,
708 u_int32_t flags, u_int32_t *valuep, u_int32_t baseaddr,
709 u_int32_t bitoffset, u_int32_t bitlen)
711 u_int32_t unit, offset;
712 u_int32_t offadj, bitadj;
713 u_int32_t value, readval, i;
714 int state;
716 readval = 0;
717 state = 0;
718 unit = 4; /* limitation of 32 bits alignment */
719 offset = bitoffset % (unit * 8);
720 offadj = 0;
721 bitadj = 0;
722 if (offset + bitlen > unit * 8) {
723 bitadj = bitlen - (unit * 8 - offset);
725 for (i = 0; i < offset + bitlen; i += unit * 8) {
726 value = (*valuep) >> offadj;
727 state = aml_region_io_simple(env, io, regtype, flags,
728 &value, baseaddr, bitoffset + offadj, bitlen - bitadj);
729 if (state == -1) {
730 goto out;
732 readval |= value << offadj;
733 bitadj = offadj = bitlen - bitadj;
735 *valuep = readval;
737 out:
738 return (state);