static ssize_t pccard_show_cis(struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { unsigned int size = 0x200; if (off >= size) count = 0; else { struct pcmcia_socket *s; unsigned int chains; if (off + count > size) count = size - off; s = to_socket(container_of(kobj, struct device, kobj)); if (!(s->state & SOCKET_PRESENT)) return -ENODEV; if (pccard_validate_cis(s, &chains)) return -EIO; if (!chains) return -ENODATA; count = pccard_extract_cis(s, buf, off, count); } return (count); }
static int pcmcia_card_add(struct pcmcia_socket *s) { cisinfo_t cisinfo; cistpl_longlink_mfc_t mfc; unsigned int no_funcs, i; int ret = 0; if (!(s->resource_setup_done)) return -EAGAIN; /* try again, but later... */ if (pcmcia_validate_mem(s)) return -EAGAIN; /* try again, but later... */ ret = pccard_validate_cis(s, BIND_FN_ALL, &cisinfo); if (ret || !cisinfo.Chains) { ds_dbg(0, "invalid CIS or invalid resources\n"); return -ENODEV; } if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC, &mfc)) no_funcs = mfc.nfn; else no_funcs = 1; for (i=0; i < no_funcs; i++) pcmcia_device_add(s, i); return (ret); }
int pcmcia_validate_cis(client_handle_t handle, cisinfo_t *info) { struct pcmcia_socket *s; if (CHECK_HANDLE(handle)) return CS_BAD_HANDLE; s = SOCKET(handle); return pccard_validate_cis(s, handle->Function, info); }
/* Validation function for cards with a valid CIS */ static int readable(struct pcmcia_socket *s, struct resource *res, cisinfo_t *info) { int ret = -1; s->cis_mem.res = res; s->cis_virt = ioremap(res->start, s->map_size); if (s->cis_virt) { ret = pccard_validate_cis(s, BIND_FN_ALL, info); /* invalidate mapping and CIS cache */ iounmap(s->cis_virt); s->cis_virt = NULL; destroy_cis_cache(s); } s->cis_mem.res = NULL; if ((ret != 0) || (info->Chains == 0)) return 0; return 1; }