static int pcmcia_device_probe(struct device * dev) { struct pcmcia_device *p_dev; struct pcmcia_driver *p_drv; int ret = 0; dev = get_device(dev); if (!dev) return -ENODEV; p_dev = to_pcmcia_dev(dev); p_drv = to_pcmcia_drv(dev->driver); if (!try_module_get(p_drv->owner)) { ret = -EINVAL; goto put_dev; } if (p_drv->attach) { p_dev->instance = p_drv->attach(); if ((!p_dev->instance) || (p_dev->client.state & CLIENT_UNBOUND)) { printk(KERN_NOTICE "ds: unable to create instance " "of '%s'!\n", p_drv->drv.name); ret = -EINVAL; } } if (ret) module_put(p_drv->owner); put_dev: if ((ret) || !(p_drv->attach)) put_device(dev); return (ret); }
static int pcmcia_device_remove(struct device * dev) { struct pcmcia_device *p_dev; struct pcmcia_driver *p_drv; int i; /* detach the "instance" */ p_dev = to_pcmcia_dev(dev); p_drv = to_pcmcia_drv(dev->driver); if (!p_drv) return 0; if (p_drv->remove) p_drv->remove(p_dev); /* check for proper unloading */ if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED)) printk(KERN_INFO "pcmcia: driver %s did not release config properly\n", p_drv->drv.name); for (i = 0; i < MAX_WIN; i++) if (p_dev->state & CLIENT_WIN_REQ(i)) printk(KERN_INFO "pcmcia: driver %s did not release windows properly\n", p_drv->drv.name); /* references from pcmcia_probe_device */ p_dev->state = CLIENT_UNBOUND; pcmcia_put_dev(p_dev); module_put(p_drv->owner); return 0; }
static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) { struct pcmcia_device * p_dev = to_pcmcia_dev(dev); struct pcmcia_driver * p_drv = to_pcmcia_drv(drv); /* matching by cardmgr */ if (p_dev->cardmgr == p_drv) return 1; return 0; }
static int pcmcia_dev_resume(struct device * dev) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); struct pcmcia_driver *p_drv = NULL; if (dev->driver) p_drv = to_pcmcia_drv(dev->driver); if (p_drv && p_drv->resume) return p_drv->resume(p_dev); return 0; }
static int pcmcia_dev_suspend(struct device * dev, pm_message_t state) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); struct pcmcia_driver *p_drv = NULL; if (dev->driver) p_drv = to_pcmcia_drv(dev->driver); if (p_drv && p_drv->suspend) return p_drv->suspend(p_dev); return 0; }
static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) { struct pcmcia_device * p_dev = to_pcmcia_dev(dev); struct pcmcia_driver * p_drv = to_pcmcia_drv(drv); struct pcmcia_device_id *did = p_drv->id_table; /* matching by cardmgr */ if (p_dev->cardmgr == p_drv) return 1; while (did && did->match_flags) { if (pcmcia_devmatch(p_dev, did)) return 1; did++; } return 0; }
static int pcmcia_device_remove(struct device * dev) { struct pcmcia_device *p_dev; struct pcmcia_driver *p_drv; /* detach the "instance" */ p_dev = to_pcmcia_dev(dev); p_drv = to_pcmcia_drv(dev->driver); if (p_drv) { if ((p_drv->detach) && (p_dev->instance)) { p_drv->detach(p_dev->instance); /* from pcmcia_probe_device */ put_device(&p_dev->dev); } module_put(p_drv->owner); } return 0; }
static int pcmcia_device_probe(struct device * dev) { struct pcmcia_device *p_dev; struct pcmcia_driver *p_drv; struct pcmcia_device_id *did; struct pcmcia_socket *s; int ret = 0; dev = get_device(dev); if (!dev) return -ENODEV; p_dev = to_pcmcia_dev(dev); p_drv = to_pcmcia_drv(dev->driver); s = p_dev->socket; if ((!p_drv->probe) || (!try_module_get(p_drv->owner))) { ret = -EINVAL; goto put_dev; } p_dev->state &= ~CLIENT_UNBOUND; /* set up the device configuration, if it hasn't been done before */ if (!s->functions) { cistpl_longlink_mfc_t mfc; if (pccard_read_tuple(s, p_dev->func, CISTPL_LONGLINK_MFC, &mfc) == CS_SUCCESS) s->functions = mfc.nfn; else s->functions = 1; s->config = kzalloc(sizeof(config_t) * s->functions, GFP_KERNEL); if (!s->config) { ret = -ENOMEM; goto put_module; } } ret = p_drv->probe(p_dev); if (ret) goto put_module; /* handle pseudo multifunction devices: * there are at most two pseudo multifunction devices. * if we're matching against the first, schedule a * call which will then check whether there are two * pseudo devices, and if not, add the second one. */ did = (struct pcmcia_device_id *) p_dev->dev.driver_data; if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) && (p_dev->socket->device_count == 1) && (p_dev->device_no == 0)) pcmcia_add_pseudo_device(p_dev->socket); put_module: if (ret) module_put(p_drv->owner); put_dev: if (ret) put_device(dev); return (ret); }