Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * card.c - contains functions for managing groups of PnP devices
0004  *
0005  * Copyright 2002 Adam Belay <ambx1@neo.rr.com>
0006  */
0007 
0008 #include <linux/module.h>
0009 #include <linux/mutex.h>
0010 #include <linux/ctype.h>
0011 #include <linux/slab.h>
0012 #include <linux/pnp.h>
0013 #include <linux/dma-mapping.h>
0014 #include "base.h"
0015 
0016 LIST_HEAD(pnp_cards);
0017 static LIST_HEAD(pnp_card_drivers);
0018 
0019 static const struct pnp_card_device_id *match_card(struct pnp_card_driver *drv,
0020                            struct pnp_card *card)
0021 {
0022     const struct pnp_card_device_id *drv_id = drv->id_table;
0023 
0024     while (*drv_id->id) {
0025         if (compare_pnp_id(card->id, drv_id->id)) {
0026             int i = 0;
0027 
0028             for (;;) {
0029                 int found;
0030                 struct pnp_dev *dev;
0031 
0032                 if (i == PNP_MAX_DEVICES ||
0033                     !*drv_id->devs[i].id)
0034                     return drv_id;
0035                 found = 0;
0036                 card_for_each_dev(card, dev) {
0037                     if (compare_pnp_id(dev->id,
0038                            drv_id->devs[i].id)) {
0039                         found = 1;
0040                         break;
0041                     }
0042                 }
0043                 if (!found)
0044                     break;
0045                 i++;
0046             }
0047         }
0048         drv_id++;
0049     }
0050     return NULL;
0051 }
0052 
0053 static void card_remove(struct pnp_dev *dev)
0054 {
0055     dev->card_link = NULL;
0056 }
0057 
0058 static void card_remove_first(struct pnp_dev *dev)
0059 {
0060     struct pnp_card_driver *drv = to_pnp_card_driver(dev->driver);
0061 
0062     if (!dev->card || !drv)
0063         return;
0064     if (drv->remove)
0065         drv->remove(dev->card_link);
0066     drv->link.remove = &card_remove;
0067     kfree(dev->card_link);
0068     card_remove(dev);
0069 }
0070 
0071 static int card_probe(struct pnp_card *card, struct pnp_card_driver *drv)
0072 {
0073     const struct pnp_card_device_id *id;
0074     struct pnp_card_link *clink;
0075     struct pnp_dev *dev;
0076 
0077     if (!drv->probe)
0078         return 0;
0079     id = match_card(drv, card);
0080     if (!id)
0081         return 0;
0082 
0083     clink = kzalloc(sizeof(*clink), GFP_KERNEL);
0084     if (!clink)
0085         return 0;
0086     clink->card = card;
0087     clink->driver = drv;
0088     clink->pm_state = PMSG_ON;
0089 
0090     if (drv->probe(clink, id) >= 0)
0091         return 1;
0092 
0093     /* Recovery */
0094     card_for_each_dev(card, dev) {
0095         if (dev->card_link == clink)
0096             pnp_release_card_device(dev);
0097     }
0098     kfree(clink);
0099     return 0;
0100 }
0101 
0102 /**
0103  * pnp_add_card_id - adds an EISA id to the specified card
0104  * @id: pointer to a pnp_id structure
0105  * @card: pointer to the desired card
0106  */
0107 static struct pnp_id *pnp_add_card_id(struct pnp_card *card, char *id)
0108 {
0109     struct pnp_id *dev_id, *ptr;
0110 
0111     dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
0112     if (!dev_id)
0113         return NULL;
0114 
0115     dev_id->id[0] = id[0];
0116     dev_id->id[1] = id[1];
0117     dev_id->id[2] = id[2];
0118     dev_id->id[3] = tolower(id[3]);
0119     dev_id->id[4] = tolower(id[4]);
0120     dev_id->id[5] = tolower(id[5]);
0121     dev_id->id[6] = tolower(id[6]);
0122     dev_id->id[7] = '\0';
0123 
0124     dev_id->next = NULL;
0125     ptr = card->id;
0126     while (ptr && ptr->next)
0127         ptr = ptr->next;
0128     if (ptr)
0129         ptr->next = dev_id;
0130     else
0131         card->id = dev_id;
0132 
0133     return dev_id;
0134 }
0135 
0136 static void pnp_free_card_ids(struct pnp_card *card)
0137 {
0138     struct pnp_id *id;
0139     struct pnp_id *next;
0140 
0141     id = card->id;
0142     while (id) {
0143         next = id->next;
0144         kfree(id);
0145         id = next;
0146     }
0147 }
0148 
0149 static void pnp_release_card(struct device *dmdev)
0150 {
0151     struct pnp_card *card = to_pnp_card(dmdev);
0152 
0153     pnp_free_card_ids(card);
0154     kfree(card);
0155 }
0156 
0157 struct pnp_card *pnp_alloc_card(struct pnp_protocol *protocol, int id, char *pnpid)
0158 {
0159     struct pnp_card *card;
0160     struct pnp_id *dev_id;
0161 
0162     card = kzalloc(sizeof(struct pnp_card), GFP_KERNEL);
0163     if (!card)
0164         return NULL;
0165 
0166     card->protocol = protocol;
0167     card->number = id;
0168 
0169     card->dev.parent = &card->protocol->dev;
0170     dev_set_name(&card->dev, "%02x:%02x", card->protocol->number, card->number);
0171 
0172     card->dev.coherent_dma_mask = DMA_BIT_MASK(24);
0173     card->dev.dma_mask = &card->dev.coherent_dma_mask;
0174 
0175     dev_id = pnp_add_card_id(card, pnpid);
0176     if (!dev_id) {
0177         kfree(card);
0178         return NULL;
0179     }
0180 
0181     return card;
0182 }
0183 
0184 static ssize_t name_show(struct device *dmdev,
0185              struct device_attribute *attr, char *buf)
0186 {
0187     char *str = buf;
0188     struct pnp_card *card = to_pnp_card(dmdev);
0189 
0190     str += sprintf(str, "%s\n", card->name);
0191     return (str - buf);
0192 }
0193 
0194 static DEVICE_ATTR_RO(name);
0195 
0196 static ssize_t card_id_show(struct device *dmdev,
0197                 struct device_attribute *attr, char *buf)
0198 {
0199     char *str = buf;
0200     struct pnp_card *card = to_pnp_card(dmdev);
0201     struct pnp_id *pos = card->id;
0202 
0203     while (pos) {
0204         str += sprintf(str, "%s\n", pos->id);
0205         pos = pos->next;
0206     }
0207     return (str - buf);
0208 }
0209 
0210 static DEVICE_ATTR_RO(card_id);
0211 
0212 static int pnp_interface_attach_card(struct pnp_card *card)
0213 {
0214     int rc = device_create_file(&card->dev, &dev_attr_name);
0215 
0216     if (rc)
0217         return rc;
0218 
0219     rc = device_create_file(&card->dev, &dev_attr_card_id);
0220     if (rc)
0221         goto err_name;
0222 
0223     return 0;
0224 
0225 err_name:
0226     device_remove_file(&card->dev, &dev_attr_name);
0227     return rc;
0228 }
0229 
0230 /**
0231  * pnp_add_card - adds a PnP card to the PnP Layer
0232  * @card: pointer to the card to add
0233  */
0234 int pnp_add_card(struct pnp_card *card)
0235 {
0236     int error;
0237     struct list_head *pos, *temp;
0238 
0239     card->dev.bus = NULL;
0240     card->dev.release = &pnp_release_card;
0241     error = device_register(&card->dev);
0242     if (error) {
0243         dev_err(&card->dev, "could not register (err=%d)\n", error);
0244         put_device(&card->dev);
0245         return error;
0246     }
0247 
0248     pnp_interface_attach_card(card);
0249     mutex_lock(&pnp_lock);
0250     list_add_tail(&card->global_list, &pnp_cards);
0251     list_add_tail(&card->protocol_list, &card->protocol->cards);
0252     mutex_unlock(&pnp_lock);
0253 
0254     /* we wait until now to add devices in order to ensure the drivers
0255      * will be able to use all of the related devices on the card
0256      * without waiting an unreasonable length of time */
0257     list_for_each(pos, &card->devices) {
0258         struct pnp_dev *dev = card_to_pnp_dev(pos);
0259         __pnp_add_device(dev);
0260     }
0261 
0262     /* match with card drivers */
0263     list_for_each_safe(pos, temp, &pnp_card_drivers) {
0264         struct pnp_card_driver *drv =
0265             list_entry(pos, struct pnp_card_driver,
0266                    global_list);
0267         card_probe(card, drv);
0268     }
0269     return 0;
0270 }
0271 
0272 /**
0273  * pnp_remove_card - removes a PnP card from the PnP Layer
0274  * @card: pointer to the card to remove
0275  */
0276 void pnp_remove_card(struct pnp_card *card)
0277 {
0278     struct list_head *pos, *temp;
0279 
0280     device_unregister(&card->dev);
0281     mutex_lock(&pnp_lock);
0282     list_del(&card->global_list);
0283     list_del(&card->protocol_list);
0284     mutex_unlock(&pnp_lock);
0285     list_for_each_safe(pos, temp, &card->devices) {
0286         struct pnp_dev *dev = card_to_pnp_dev(pos);
0287         pnp_remove_card_device(dev);
0288     }
0289 }
0290 
0291 /**
0292  * pnp_add_card_device - adds a device to the specified card
0293  * @card: pointer to the card to add to
0294  * @dev: pointer to the device to add
0295  */
0296 int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev)
0297 {
0298     dev->dev.parent = &card->dev;
0299     dev->card_link = NULL;
0300     dev_set_name(&dev->dev, "%02x:%02x.%02x",
0301              dev->protocol->number, card->number, dev->number);
0302     mutex_lock(&pnp_lock);
0303     dev->card = card;
0304     list_add_tail(&dev->card_list, &card->devices);
0305     mutex_unlock(&pnp_lock);
0306     return 0;
0307 }
0308 
0309 /**
0310  * pnp_remove_card_device- removes a device from the specified card
0311  * @dev: pointer to the device to remove
0312  */
0313 void pnp_remove_card_device(struct pnp_dev *dev)
0314 {
0315     mutex_lock(&pnp_lock);
0316     dev->card = NULL;
0317     list_del(&dev->card_list);
0318     mutex_unlock(&pnp_lock);
0319     __pnp_remove_device(dev);
0320 }
0321 
0322 /**
0323  * pnp_request_card_device - Searches for a PnP device under the specified card
0324  * @clink: pointer to the card link, cannot be NULL
0325  * @id: pointer to a PnP ID structure that explains the rules for finding the device
0326  * @from: Starting place to search from. If NULL it will start from the beginning.
0327  */
0328 struct pnp_dev *pnp_request_card_device(struct pnp_card_link *clink,
0329                     const char *id, struct pnp_dev *from)
0330 {
0331     struct list_head *pos;
0332     struct pnp_dev *dev;
0333     struct pnp_card_driver *drv;
0334     struct pnp_card *card;
0335 
0336     if (!clink || !id)
0337         return NULL;
0338 
0339     card = clink->card;
0340     drv = clink->driver;
0341     if (!from) {
0342         pos = card->devices.next;
0343     } else {
0344         if (from->card != card)
0345             return NULL;
0346         pos = from->card_list.next;
0347     }
0348     while (pos != &card->devices) {
0349         dev = card_to_pnp_dev(pos);
0350         if ((!dev->card_link) && compare_pnp_id(dev->id, id))
0351             goto found;
0352         pos = pos->next;
0353     }
0354 
0355     return NULL;
0356 
0357 found:
0358     dev->card_link = clink;
0359     dev->dev.driver = &drv->link.driver;
0360     if (pnp_bus_type.probe(&dev->dev))
0361         goto err_out;
0362     if (device_bind_driver(&dev->dev))
0363         goto err_out;
0364 
0365     return dev;
0366 
0367 err_out:
0368     dev->dev.driver = NULL;
0369     dev->card_link = NULL;
0370     return NULL;
0371 }
0372 EXPORT_SYMBOL(pnp_request_card_device);
0373 
0374 /**
0375  * pnp_release_card_device - call this when the driver no longer needs the device
0376  * @dev: pointer to the PnP device structure
0377  */
0378 void pnp_release_card_device(struct pnp_dev *dev)
0379 {
0380     struct pnp_card_driver *drv = dev->card_link->driver;
0381 
0382     drv->link.remove = &card_remove;
0383     device_release_driver(&dev->dev);
0384     drv->link.remove = &card_remove_first;
0385 }
0386 EXPORT_SYMBOL(pnp_release_card_device);
0387 
0388 /*
0389  * suspend/resume callbacks
0390  */
0391 static int card_suspend(struct pnp_dev *dev, pm_message_t state)
0392 {
0393     struct pnp_card_link *link = dev->card_link;
0394 
0395     if (link->pm_state.event == state.event)
0396         return 0;
0397     link->pm_state = state;
0398     return link->driver->suspend(link, state);
0399 }
0400 
0401 static int card_resume(struct pnp_dev *dev)
0402 {
0403     struct pnp_card_link *link = dev->card_link;
0404 
0405     if (link->pm_state.event == PM_EVENT_ON)
0406         return 0;
0407     link->pm_state = PMSG_ON;
0408     link->driver->resume(link);
0409     return 0;
0410 }
0411 
0412 /**
0413  * pnp_register_card_driver - registers a PnP card driver with the PnP Layer
0414  * @drv: pointer to the driver to register
0415  */
0416 int pnp_register_card_driver(struct pnp_card_driver *drv)
0417 {
0418     int error;
0419     struct list_head *pos, *temp;
0420 
0421     drv->link.name = drv->name;
0422     drv->link.id_table = NULL;  /* this will disable auto matching */
0423     drv->link.flags = drv->flags;
0424     drv->link.probe = NULL;
0425     drv->link.remove = &card_remove_first;
0426     drv->link.suspend = drv->suspend ? card_suspend : NULL;
0427     drv->link.resume = drv->resume ? card_resume : NULL;
0428 
0429     error = pnp_register_driver(&drv->link);
0430     if (error < 0)
0431         return error;
0432 
0433     mutex_lock(&pnp_lock);
0434     list_add_tail(&drv->global_list, &pnp_card_drivers);
0435     mutex_unlock(&pnp_lock);
0436 
0437     list_for_each_safe(pos, temp, &pnp_cards) {
0438         struct pnp_card *card =
0439             list_entry(pos, struct pnp_card, global_list);
0440         card_probe(card, drv);
0441     }
0442     return 0;
0443 }
0444 EXPORT_SYMBOL(pnp_register_card_driver);
0445 
0446 /**
0447  * pnp_unregister_card_driver - unregisters a PnP card driver from the PnP Layer
0448  * @drv: pointer to the driver to unregister
0449  */
0450 void pnp_unregister_card_driver(struct pnp_card_driver *drv)
0451 {
0452     mutex_lock(&pnp_lock);
0453     list_del(&drv->global_list);
0454     mutex_unlock(&pnp_lock);
0455     pnp_unregister_driver(&drv->link);
0456 }
0457 EXPORT_SYMBOL(pnp_unregister_card_driver);