in cistpl.c [1473:1539]
static ssize_t pccard_extract_cis(struct pcmcia_socket *s, char *buf,
loff_t off, size_t count)
{
tuple_t tuple;
int status, i;
loff_t pointer = 0;
ssize_t ret = 0;
u_char *tuplebuffer;
u_char *tempbuffer;
tuplebuffer = kmalloc_array(256, sizeof(u_char), GFP_KERNEL);
if (!tuplebuffer)
return -ENOMEM;
tempbuffer = kmalloc_array(258, sizeof(u_char), GFP_KERNEL);
if (!tempbuffer) {
ret = -ENOMEM;
goto free_tuple;
}
memset(&tuple, 0, sizeof(tuple_t));
tuple.Attributes = TUPLE_RETURN_LINK | TUPLE_RETURN_COMMON;
tuple.DesiredTuple = RETURN_FIRST_TUPLE;
tuple.TupleOffset = 0;
status = pccard_get_first_tuple(s, BIND_FN_ALL, &tuple);
while (!status) {
tuple.TupleData = tuplebuffer;
tuple.TupleDataMax = 255;
memset(tuplebuffer, 0, sizeof(u_char) * 255);
status = pccard_get_tuple_data(s, &tuple);
if (status)
break;
if (off < (pointer + 2 + tuple.TupleDataLen)) {
tempbuffer[0] = tuple.TupleCode & 0xff;
tempbuffer[1] = tuple.TupleLink & 0xff;
for (i = 0; i < tuple.TupleDataLen; i++)
tempbuffer[i + 2] = tuplebuffer[i] & 0xff;
for (i = 0; i < (2 + tuple.TupleDataLen); i++) {
if (((i + pointer) >= off) &&
(i + pointer) < (off + count)) {
buf[ret] = tempbuffer[i];
ret++;
}
}
}
pointer += 2 + tuple.TupleDataLen;
if (pointer >= (off + count))
break;
if (tuple.TupleCode == CISTPL_END)
break;
status = pccard_get_next_tuple(s, BIND_FN_ALL, &tuple);
}
kfree(tempbuffer);
free_tuple:
kfree(tuplebuffer);
return ret;
}