card.c (10261B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * card.c - contains functions for managing groups of PnP devices 4 * 5 * Copyright 2002 Adam Belay <ambx1@neo.rr.com> 6 */ 7 8#include <linux/module.h> 9#include <linux/mutex.h> 10#include <linux/ctype.h> 11#include <linux/slab.h> 12#include <linux/pnp.h> 13#include <linux/dma-mapping.h> 14#include "base.h" 15 16LIST_HEAD(pnp_cards); 17static LIST_HEAD(pnp_card_drivers); 18 19static const struct pnp_card_device_id *match_card(struct pnp_card_driver *drv, 20 struct pnp_card *card) 21{ 22 const struct pnp_card_device_id *drv_id = drv->id_table; 23 24 while (*drv_id->id) { 25 if (compare_pnp_id(card->id, drv_id->id)) { 26 int i = 0; 27 28 for (;;) { 29 int found; 30 struct pnp_dev *dev; 31 32 if (i == PNP_MAX_DEVICES || 33 !*drv_id->devs[i].id) 34 return drv_id; 35 found = 0; 36 card_for_each_dev(card, dev) { 37 if (compare_pnp_id(dev->id, 38 drv_id->devs[i].id)) { 39 found = 1; 40 break; 41 } 42 } 43 if (!found) 44 break; 45 i++; 46 } 47 } 48 drv_id++; 49 } 50 return NULL; 51} 52 53static void card_remove(struct pnp_dev *dev) 54{ 55 dev->card_link = NULL; 56} 57 58static void card_remove_first(struct pnp_dev *dev) 59{ 60 struct pnp_card_driver *drv = to_pnp_card_driver(dev->driver); 61 62 if (!dev->card || !drv) 63 return; 64 if (drv->remove) 65 drv->remove(dev->card_link); 66 drv->link.remove = &card_remove; 67 kfree(dev->card_link); 68 card_remove(dev); 69} 70 71static int card_probe(struct pnp_card *card, struct pnp_card_driver *drv) 72{ 73 const struct pnp_card_device_id *id; 74 struct pnp_card_link *clink; 75 struct pnp_dev *dev; 76 77 if (!drv->probe) 78 return 0; 79 id = match_card(drv, card); 80 if (!id) 81 return 0; 82 83 clink = kzalloc(sizeof(*clink), GFP_KERNEL); 84 if (!clink) 85 return 0; 86 clink->card = card; 87 clink->driver = drv; 88 clink->pm_state = PMSG_ON; 89 90 if (drv->probe(clink, id) >= 0) 91 return 1; 92 93 /* Recovery */ 94 card_for_each_dev(card, dev) { 95 if (dev->card_link == clink) 96 pnp_release_card_device(dev); 97 } 98 kfree(clink); 99 return 0; 100} 101 102/** 103 * pnp_add_card_id - adds an EISA id to the specified card 104 * @id: pointer to a pnp_id structure 105 * @card: pointer to the desired card 106 */ 107static struct pnp_id *pnp_add_card_id(struct pnp_card *card, char *id) 108{ 109 struct pnp_id *dev_id, *ptr; 110 111 dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL); 112 if (!dev_id) 113 return NULL; 114 115 dev_id->id[0] = id[0]; 116 dev_id->id[1] = id[1]; 117 dev_id->id[2] = id[2]; 118 dev_id->id[3] = tolower(id[3]); 119 dev_id->id[4] = tolower(id[4]); 120 dev_id->id[5] = tolower(id[5]); 121 dev_id->id[6] = tolower(id[6]); 122 dev_id->id[7] = '\0'; 123 124 dev_id->next = NULL; 125 ptr = card->id; 126 while (ptr && ptr->next) 127 ptr = ptr->next; 128 if (ptr) 129 ptr->next = dev_id; 130 else 131 card->id = dev_id; 132 133 return dev_id; 134} 135 136static void pnp_free_card_ids(struct pnp_card *card) 137{ 138 struct pnp_id *id; 139 struct pnp_id *next; 140 141 id = card->id; 142 while (id) { 143 next = id->next; 144 kfree(id); 145 id = next; 146 } 147} 148 149static void pnp_release_card(struct device *dmdev) 150{ 151 struct pnp_card *card = to_pnp_card(dmdev); 152 153 pnp_free_card_ids(card); 154 kfree(card); 155} 156 157struct pnp_card *pnp_alloc_card(struct pnp_protocol *protocol, int id, char *pnpid) 158{ 159 struct pnp_card *card; 160 struct pnp_id *dev_id; 161 162 card = kzalloc(sizeof(struct pnp_card), GFP_KERNEL); 163 if (!card) 164 return NULL; 165 166 card->protocol = protocol; 167 card->number = id; 168 169 card->dev.parent = &card->protocol->dev; 170 dev_set_name(&card->dev, "%02x:%02x", card->protocol->number, card->number); 171 172 card->dev.coherent_dma_mask = DMA_BIT_MASK(24); 173 card->dev.dma_mask = &card->dev.coherent_dma_mask; 174 175 dev_id = pnp_add_card_id(card, pnpid); 176 if (!dev_id) { 177 kfree(card); 178 return NULL; 179 } 180 181 return card; 182} 183 184static ssize_t name_show(struct device *dmdev, 185 struct device_attribute *attr, char *buf) 186{ 187 char *str = buf; 188 struct pnp_card *card = to_pnp_card(dmdev); 189 190 str += sprintf(str, "%s\n", card->name); 191 return (str - buf); 192} 193 194static DEVICE_ATTR_RO(name); 195 196static ssize_t card_id_show(struct device *dmdev, 197 struct device_attribute *attr, char *buf) 198{ 199 char *str = buf; 200 struct pnp_card *card = to_pnp_card(dmdev); 201 struct pnp_id *pos = card->id; 202 203 while (pos) { 204 str += sprintf(str, "%s\n", pos->id); 205 pos = pos->next; 206 } 207 return (str - buf); 208} 209 210static DEVICE_ATTR_RO(card_id); 211 212static int pnp_interface_attach_card(struct pnp_card *card) 213{ 214 int rc = device_create_file(&card->dev, &dev_attr_name); 215 216 if (rc) 217 return rc; 218 219 rc = device_create_file(&card->dev, &dev_attr_card_id); 220 if (rc) 221 goto err_name; 222 223 return 0; 224 225err_name: 226 device_remove_file(&card->dev, &dev_attr_name); 227 return rc; 228} 229 230/** 231 * pnp_add_card - adds a PnP card to the PnP Layer 232 * @card: pointer to the card to add 233 */ 234int pnp_add_card(struct pnp_card *card) 235{ 236 int error; 237 struct list_head *pos, *temp; 238 239 card->dev.bus = NULL; 240 card->dev.release = &pnp_release_card; 241 error = device_register(&card->dev); 242 if (error) { 243 dev_err(&card->dev, "could not register (err=%d)\n", error); 244 put_device(&card->dev); 245 return error; 246 } 247 248 pnp_interface_attach_card(card); 249 mutex_lock(&pnp_lock); 250 list_add_tail(&card->global_list, &pnp_cards); 251 list_add_tail(&card->protocol_list, &card->protocol->cards); 252 mutex_unlock(&pnp_lock); 253 254 /* we wait until now to add devices in order to ensure the drivers 255 * will be able to use all of the related devices on the card 256 * without waiting an unreasonable length of time */ 257 list_for_each(pos, &card->devices) { 258 struct pnp_dev *dev = card_to_pnp_dev(pos); 259 __pnp_add_device(dev); 260 } 261 262 /* match with card drivers */ 263 list_for_each_safe(pos, temp, &pnp_card_drivers) { 264 struct pnp_card_driver *drv = 265 list_entry(pos, struct pnp_card_driver, 266 global_list); 267 card_probe(card, drv); 268 } 269 return 0; 270} 271 272/** 273 * pnp_remove_card - removes a PnP card from the PnP Layer 274 * @card: pointer to the card to remove 275 */ 276void pnp_remove_card(struct pnp_card *card) 277{ 278 struct list_head *pos, *temp; 279 280 device_unregister(&card->dev); 281 mutex_lock(&pnp_lock); 282 list_del(&card->global_list); 283 list_del(&card->protocol_list); 284 mutex_unlock(&pnp_lock); 285 list_for_each_safe(pos, temp, &card->devices) { 286 struct pnp_dev *dev = card_to_pnp_dev(pos); 287 pnp_remove_card_device(dev); 288 } 289} 290 291/** 292 * pnp_add_card_device - adds a device to the specified card 293 * @card: pointer to the card to add to 294 * @dev: pointer to the device to add 295 */ 296int pnp_add_card_device(struct pnp_card *card, struct pnp_dev *dev) 297{ 298 dev->dev.parent = &card->dev; 299 dev->card_link = NULL; 300 dev_set_name(&dev->dev, "%02x:%02x.%02x", 301 dev->protocol->number, card->number, dev->number); 302 mutex_lock(&pnp_lock); 303 dev->card = card; 304 list_add_tail(&dev->card_list, &card->devices); 305 mutex_unlock(&pnp_lock); 306 return 0; 307} 308 309/** 310 * pnp_remove_card_device- removes a device from the specified card 311 * @dev: pointer to the device to remove 312 */ 313void pnp_remove_card_device(struct pnp_dev *dev) 314{ 315 mutex_lock(&pnp_lock); 316 dev->card = NULL; 317 list_del(&dev->card_list); 318 mutex_unlock(&pnp_lock); 319 __pnp_remove_device(dev); 320} 321 322/** 323 * pnp_request_card_device - Searches for a PnP device under the specified card 324 * @clink: pointer to the card link, cannot be NULL 325 * @id: pointer to a PnP ID structure that explains the rules for finding the device 326 * @from: Starting place to search from. If NULL it will start from the beginning. 327 */ 328struct pnp_dev *pnp_request_card_device(struct pnp_card_link *clink, 329 const char *id, struct pnp_dev *from) 330{ 331 struct list_head *pos; 332 struct pnp_dev *dev; 333 struct pnp_card_driver *drv; 334 struct pnp_card *card; 335 336 if (!clink || !id) 337 return NULL; 338 339 card = clink->card; 340 drv = clink->driver; 341 if (!from) { 342 pos = card->devices.next; 343 } else { 344 if (from->card != card) 345 return NULL; 346 pos = from->card_list.next; 347 } 348 while (pos != &card->devices) { 349 dev = card_to_pnp_dev(pos); 350 if ((!dev->card_link) && compare_pnp_id(dev->id, id)) 351 goto found; 352 pos = pos->next; 353 } 354 355 return NULL; 356 357found: 358 dev->card_link = clink; 359 dev->dev.driver = &drv->link.driver; 360 if (pnp_bus_type.probe(&dev->dev)) 361 goto err_out; 362 if (device_bind_driver(&dev->dev)) 363 goto err_out; 364 365 return dev; 366 367err_out: 368 dev->dev.driver = NULL; 369 dev->card_link = NULL; 370 return NULL; 371} 372EXPORT_SYMBOL(pnp_request_card_device); 373 374/** 375 * pnp_release_card_device - call this when the driver no longer needs the device 376 * @dev: pointer to the PnP device structure 377 */ 378void pnp_release_card_device(struct pnp_dev *dev) 379{ 380 struct pnp_card_driver *drv = dev->card_link->driver; 381 382 drv->link.remove = &card_remove; 383 device_release_driver(&dev->dev); 384 drv->link.remove = &card_remove_first; 385} 386EXPORT_SYMBOL(pnp_release_card_device); 387 388/* 389 * suspend/resume callbacks 390 */ 391static int card_suspend(struct pnp_dev *dev, pm_message_t state) 392{ 393 struct pnp_card_link *link = dev->card_link; 394 395 if (link->pm_state.event == state.event) 396 return 0; 397 link->pm_state = state; 398 return link->driver->suspend(link, state); 399} 400 401static int card_resume(struct pnp_dev *dev) 402{ 403 struct pnp_card_link *link = dev->card_link; 404 405 if (link->pm_state.event == PM_EVENT_ON) 406 return 0; 407 link->pm_state = PMSG_ON; 408 link->driver->resume(link); 409 return 0; 410} 411 412/** 413 * pnp_register_card_driver - registers a PnP card driver with the PnP Layer 414 * @drv: pointer to the driver to register 415 */ 416int pnp_register_card_driver(struct pnp_card_driver *drv) 417{ 418 int error; 419 struct list_head *pos, *temp; 420 421 drv->link.name = drv->name; 422 drv->link.id_table = NULL; /* this will disable auto matching */ 423 drv->link.flags = drv->flags; 424 drv->link.probe = NULL; 425 drv->link.remove = &card_remove_first; 426 drv->link.suspend = drv->suspend ? card_suspend : NULL; 427 drv->link.resume = drv->resume ? card_resume : NULL; 428 429 error = pnp_register_driver(&drv->link); 430 if (error < 0) 431 return error; 432 433 mutex_lock(&pnp_lock); 434 list_add_tail(&drv->global_list, &pnp_card_drivers); 435 mutex_unlock(&pnp_lock); 436 437 list_for_each_safe(pos, temp, &pnp_cards) { 438 struct pnp_card *card = 439 list_entry(pos, struct pnp_card, global_list); 440 card_probe(card, drv); 441 } 442 return 0; 443} 444EXPORT_SYMBOL(pnp_register_card_driver); 445 446/** 447 * pnp_unregister_card_driver - unregisters a PnP card driver from the PnP Layer 448 * @drv: pointer to the driver to unregister 449 */ 450void pnp_unregister_card_driver(struct pnp_card_driver *drv) 451{ 452 mutex_lock(&pnp_lock); 453 list_del(&drv->global_list); 454 mutex_unlock(&pnp_lock); 455 pnp_unregister_driver(&drv->link); 456} 457EXPORT_SYMBOL(pnp_unregister_card_driver);