1 /* 2 * dock.c - ACPI dock station driver 3 * 4 * Copyright (C) 2006 Kristen Carlson Accardi <kristen.c.accardi@intel.com> 5 * 6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or (at 11 * your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License along 19 * with this program; if not, write to the Free Software Foundation, Inc., 20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 21 * 22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 23 */ 24 25 #include <linux/kernel.h> 26 #include <linux/module.h> 27 #include <linux/init.h> 28 #include <linux/types.h> 29 #include <linux/notifier.h> 30 #include <linux/platform_device.h> 31 #include <linux/jiffies.h> 32 #include <linux/stddef.h> 33 #include <acpi/acpi_bus.h> 34 #include <acpi/acpi_drivers.h> 35 36 #define PREFIX "ACPI: " 37 38 #define ACPI_DOCK_DRIVER_DESCRIPTION "ACPI Dock Station Driver" 39 40 ACPI_MODULE_NAME("dock"); 41 MODULE_AUTHOR("Kristen Carlson Accardi"); 42 MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_DESCRIPTION); 43 MODULE_LICENSE("GPL"); 44 45 static int immediate_undock = 1; 46 module_param(immediate_undock, bool, 0644); 47 MODULE_PARM_DESC(immediate_undock, "1 (default) will cause the driver to " 48 "undock immediately when the undock button is pressed, 0 will cause" 49 " the driver to wait for userspace to write the undock sysfs file " 50 " before undocking"); 51 52 static struct atomic_notifier_head dock_notifier_list; 53 54 static const struct acpi_device_id dock_device_ids[] = { 55 {"LNXDOCK", 0}, 56 {"", 0}, 57 }; 58 MODULE_DEVICE_TABLE(acpi, dock_device_ids); 59 60 struct dock_station { 61 acpi_handle handle; 62 unsigned long last_dock_time; 63 u32 flags; 64 spinlock_t dd_lock; 65 struct mutex hp_lock; 66 struct list_head dependent_devices; 67 struct list_head hotplug_devices; 68 69 struct list_head sibling; 70 struct platform_device *dock_device; 71 }; 72 static LIST_HEAD(dock_stations); 73 static int dock_station_count; 74 75 struct dock_dependent_device { 76 struct list_head list; 77 struct list_head hotplug_list; 78 acpi_handle handle; 79 struct acpi_dock_ops *ops; 80 void *context; 81 }; 82 83 #define DOCK_DOCKING 0x00000001 84 #define DOCK_UNDOCKING 0x00000002 85 #define DOCK_IS_DOCK 0x00000010 86 #define DOCK_IS_ATA 0x00000020 87 #define DOCK_IS_BAT 0x00000040 88 #define DOCK_EVENT 3 89 #define UNDOCK_EVENT 2 90 91 /***************************************************************************** 92 * Dock Dependent device functions * 93 *****************************************************************************/ 94 /** 95 * add_dock_dependent_device - associate a device with the dock station 96 * @ds: The dock station 97 * @handle: handle of the dependent device 98 * 99 * Add the dependent device to the dock's dependent device list. 100 */ 101 static int 102 add_dock_dependent_device(struct dock_station *ds, acpi_handle handle) 103 { 104 struct dock_dependent_device *dd; 105 106 dd = kzalloc(sizeof(*dd), GFP_KERNEL); 107 if (!dd) 108 return -ENOMEM; 109 110 dd->handle = handle; 111 INIT_LIST_HEAD(&dd->list); 112 INIT_LIST_HEAD(&dd->hotplug_list); 113 114 spin_lock(&ds->dd_lock); 115 list_add_tail(&dd->list, &ds->dependent_devices); 116 spin_unlock(&ds->dd_lock); 117 118 return 0; 119 } 120 121 /** 122 * dock_add_hotplug_device - associate a hotplug handler with the dock station 123 * @ds: The dock station 124 * @dd: The dependent device struct 125 * 126 * Add the dependent device to the dock's hotplug device list 127 */ 128 static void 129 dock_add_hotplug_device(struct dock_station *ds, 130 struct dock_dependent_device *dd) 131 { 132 mutex_lock(&ds->hp_lock); 133 list_add_tail(&dd->hotplug_list, &ds->hotplug_devices); 134 mutex_unlock(&ds->hp_lock); 135 } 136 137 /** 138 * dock_del_hotplug_device - remove a hotplug handler from the dock station 139 * @ds: The dock station 140 * @dd: the dependent device struct 141 * 142 * Delete the dependent device from the dock's hotplug device list 143 */ 144 static void 145 dock_del_hotplug_device(struct dock_station *ds, 146 struct dock_dependent_device *dd) 147 { 148 mutex_lock(&ds->hp_lock); 149 list_del(&dd->hotplug_list); 150 mutex_unlock(&ds->hp_lock); 151 } 152 153 /** 154 * find_dock_dependent_device - get a device dependent on this dock 155 * @ds: the dock station 156 * @handle: the acpi_handle of the device we want 157 * 158 * iterate over the dependent device list for this dock. If the 159 * dependent device matches the handle, return. 160 */ 161 static struct dock_dependent_device * 162 find_dock_dependent_device(struct dock_station *ds, acpi_handle handle) 163 { 164 struct dock_dependent_device *dd; 165 166 spin_lock(&ds->dd_lock); 167 list_for_each_entry(dd, &ds->dependent_devices, list) { 168 if (handle == dd->handle) { 169 spin_unlock(&ds->dd_lock); 170 return dd; 171 } 172 } 173 spin_unlock(&ds->dd_lock); 174 return NULL; 175 } 176 177 /***************************************************************************** 178 * Dock functions * 179 *****************************************************************************/ 180 /** 181 * is_dock - see if a device is a dock station 182 * @handle: acpi handle of the device 183 * 184 * If an acpi object has a _DCK method, then it is by definition a dock 185 * station, so return true. 186 */ 187 static int is_dock(acpi_handle handle) 188 { 189 acpi_status status; 190 acpi_handle tmp; 191 192 status = acpi_get_handle(handle, "_DCK", &tmp); 193 if (ACPI_FAILURE(status)) 194 return 0; 195 return 1; 196 } 197 198 static int is_ejectable(acpi_handle handle) 199 { 200 acpi_status status; 201 acpi_handle tmp; 202 203 status = acpi_get_handle(handle, "_EJ0", &tmp); 204 if (ACPI_FAILURE(status)) 205 return 0; 206 return 1; 207 } 208 209 static int is_ata(acpi_handle handle) 210 { 211 acpi_handle tmp; 212 213 if ((ACPI_SUCCESS(acpi_get_handle(handle, "_GTF", &tmp))) || 214 (ACPI_SUCCESS(acpi_get_handle(handle, "_GTM", &tmp))) || 215 (ACPI_SUCCESS(acpi_get_handle(handle, "_STM", &tmp))) || 216 (ACPI_SUCCESS(acpi_get_handle(handle, "_SDD", &tmp)))) 217 return 1; 218 219 return 0; 220 } 221 222 static int is_battery(acpi_handle handle) 223 { 224 struct acpi_device_info *info; 225 int ret = 1; 226 227 if (!ACPI_SUCCESS(acpi_get_object_info(handle, &info))) 228 return 0; 229 if (!(info->valid & ACPI_VALID_HID)) 230 ret = 0; 231 else 232 ret = !strcmp("PNP0C0A", info->hardware_id.string); 233 234 kfree(info); 235 return ret; 236 } 237 238 static int is_ejectable_bay(acpi_handle handle) 239 { 240 acpi_handle phandle; 241 242 if (!is_ejectable(handle)) 243 return 0; 244 if (is_battery(handle) || is_ata(handle)) 245 return 1; 246 if (!acpi_get_parent(handle, &phandle) && is_ata(phandle)) 247 return 1; 248 return 0; 249 } 250 251 /** 252 * is_dock_device - see if a device is on a dock station 253 * @handle: acpi handle of the device 254 * 255 * If this device is either the dock station itself, 256 * or is a device dependent on the dock station, then it 257 * is a dock device 258 */ 259 int is_dock_device(acpi_handle handle) 260 { 261 struct dock_station *dock_station; 262 263 if (!dock_station_count) 264 return 0; 265 266 if (is_dock(handle)) 267 return 1; 268 269 list_for_each_entry(dock_station, &dock_stations, sibling) 270 if (find_dock_dependent_device(dock_station, handle)) 271 return 1; 272 273 return 0; 274 } 275 EXPORT_SYMBOL_GPL(is_dock_device); 276 277 /** 278 * dock_present - see if the dock station is present. 279 * @ds: the dock station 280 * 281 * execute the _STA method. note that present does not 282 * imply that we are docked. 283 */ 284 static int dock_present(struct dock_station *ds) 285 { 286 unsigned long long sta; 287 acpi_status status; 288 289 if (ds) { 290 status = acpi_evaluate_integer(ds->handle, "_STA", NULL, &sta); 291 if (ACPI_SUCCESS(status) && sta) 292 return 1; 293 } 294 return 0; 295 } 296 297 /** 298 * dock_create_acpi_device - add new devices to acpi 299 * @handle - handle of the device to add 300 * 301 * This function will create a new acpi_device for the given 302 * handle if one does not exist already. This should cause 303 * acpi to scan for drivers for the given devices, and call 304 * matching driver's add routine. 305 * 306 * Returns a pointer to the acpi_device corresponding to the handle. 307 */ 308 static struct acpi_device * dock_create_acpi_device(acpi_handle handle) 309 { 310 struct acpi_device *device; 311 struct acpi_device *parent_device; 312 acpi_handle parent; 313 int ret; 314 315 if (acpi_bus_get_device(handle, &device)) { 316 /* 317 * no device created for this object, 318 * so we should create one. 319 */ 320 acpi_get_parent(handle, &parent); 321 if (acpi_bus_get_device(parent, &parent_device)) 322 parent_device = NULL; 323 324 ret = acpi_bus_add(&device, parent_device, handle, 325 ACPI_BUS_TYPE_DEVICE); 326 if (ret) { 327 pr_debug("error adding bus, %x\n", -ret); 328 return NULL; 329 } 330 } 331 return device; 332 } 333 334 /** 335 * dock_remove_acpi_device - remove the acpi_device struct from acpi 336 * @handle - the handle of the device to remove 337 * 338 * Tell acpi to remove the acpi_device. This should cause any loaded 339 * driver to have it's remove routine called. 340 */ 341 static void dock_remove_acpi_device(acpi_handle handle) 342 { 343 struct acpi_device *device; 344 int ret; 345 346 if (!acpi_bus_get_device(handle, &device)) { 347 ret = acpi_bus_trim(device, 1); 348 if (ret) 349 pr_debug("error removing bus, %x\n", -ret); 350 } 351 } 352 353 /** 354 * hotplug_dock_devices - insert or remove devices on the dock station 355 * @ds: the dock station 356 * @event: either bus check or eject request 357 * 358 * Some devices on the dock station need to have drivers called 359 * to perform hotplug operations after a dock event has occurred. 360 * Traverse the list of dock devices that have registered a 361 * hotplug handler, and call the handler. 362 */ 363 static void hotplug_dock_devices(struct dock_station *ds, u32 event) 364 { 365 struct dock_dependent_device *dd; 366 367 mutex_lock(&ds->hp_lock); 368 369 /* 370 * First call driver specific hotplug functions 371 */ 372 list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) 373 if (dd->ops && dd->ops->handler) 374 dd->ops->handler(dd->handle, event, dd->context); 375 376 /* 377 * Now make sure that an acpi_device is created for each 378 * dependent device, or removed if this is an eject request. 379 * This will cause acpi_drivers to be stopped/started if they 380 * exist 381 */ 382 list_for_each_entry(dd, &ds->dependent_devices, list) { 383 if (event == ACPI_NOTIFY_EJECT_REQUEST) 384 dock_remove_acpi_device(dd->handle); 385 else 386 dock_create_acpi_device(dd->handle); 387 } 388 mutex_unlock(&ds->hp_lock); 389 } 390 391 static void dock_event(struct dock_station *ds, u32 event, int num) 392 { 393 struct device *dev = &ds->dock_device->dev; 394 char event_string[13]; 395 char *envp[] = { event_string, NULL }; 396 struct dock_dependent_device *dd; 397 398 if (num == UNDOCK_EVENT) 399 sprintf(event_string, "EVENT=undock"); 400 else 401 sprintf(event_string, "EVENT=dock"); 402 403 /* 404 * Indicate that the status of the dock station has 405 * changed. 406 */ 407 if (num == DOCK_EVENT) 408 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); 409 410 list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) 411 if (dd->ops && dd->ops->uevent) 412 dd->ops->uevent(dd->handle, event, dd->context); 413 414 if (num != DOCK_EVENT) 415 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); 416 } 417 418 /** 419 * eject_dock - respond to a dock eject request 420 * @ds: the dock station 421 * 422 * This is called after _DCK is called, to execute the dock station's 423 * _EJ0 method. 424 */ 425 static void eject_dock(struct dock_station *ds) 426 { 427 struct acpi_object_list arg_list; 428 union acpi_object arg; 429 acpi_status status; 430 acpi_handle tmp; 431 432 /* all dock devices should have _EJ0, but check anyway */ 433 status = acpi_get_handle(ds->handle, "_EJ0", &tmp); 434 if (ACPI_FAILURE(status)) { 435 pr_debug("No _EJ0 support for dock device\n"); 436 return; 437 } 438 439 arg_list.count = 1; 440 arg_list.pointer = &arg; 441 arg.type = ACPI_TYPE_INTEGER; 442 arg.integer.value = 1; 443 444 status = acpi_evaluate_object(ds->handle, "_EJ0", &arg_list, NULL); 445 if (ACPI_FAILURE(status)) 446 pr_debug("Failed to evaluate _EJ0!\n"); 447 } 448 449 /** 450 * handle_dock - handle a dock event 451 * @ds: the dock station 452 * @dock: to dock, or undock - that is the question 453 * 454 * Execute the _DCK method in response to an acpi event 455 */ 456 static void handle_dock(struct dock_station *ds, int dock) 457 { 458 acpi_status status; 459 struct acpi_object_list arg_list; 460 union acpi_object arg; 461 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 462 struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 463 464 acpi_get_name(ds->handle, ACPI_FULL_PATHNAME, &name_buffer); 465 466 printk(KERN_INFO PREFIX "%s - %s\n", 467 (char *)name_buffer.pointer, dock ? "docking" : "undocking"); 468 469 /* _DCK method has one argument */ 470 arg_list.count = 1; 471 arg_list.pointer = &arg; 472 arg.type = ACPI_TYPE_INTEGER; 473 arg.integer.value = dock; 474 status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer); 475 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) 476 ACPI_EXCEPTION((AE_INFO, status, "%s - failed to execute" 477 " _DCK\n", (char *)name_buffer.pointer)); 478 479 kfree(buffer.pointer); 480 kfree(name_buffer.pointer); 481 } 482 483 static inline void dock(struct dock_station *ds) 484 { 485 handle_dock(ds, 1); 486 } 487 488 static inline void undock(struct dock_station *ds) 489 { 490 handle_dock(ds, 0); 491 } 492 493 static inline void begin_dock(struct dock_station *ds) 494 { 495 ds->flags |= DOCK_DOCKING; 496 } 497 498 static inline void complete_dock(struct dock_station *ds) 499 { 500 ds->flags &= ~(DOCK_DOCKING); 501 ds->last_dock_time = jiffies; 502 } 503 504 static inline void begin_undock(struct dock_station *ds) 505 { 506 ds->flags |= DOCK_UNDOCKING; 507 } 508 509 static inline void complete_undock(struct dock_station *ds) 510 { 511 ds->flags &= ~(DOCK_UNDOCKING); 512 } 513 514 static void dock_lock(struct dock_station *ds, int lock) 515 { 516 struct acpi_object_list arg_list; 517 union acpi_object arg; 518 acpi_status status; 519 520 arg_list.count = 1; 521 arg_list.pointer = &arg; 522 arg.type = ACPI_TYPE_INTEGER; 523 arg.integer.value = !!lock; 524 status = acpi_evaluate_object(ds->handle, "_LCK", &arg_list, NULL); 525 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { 526 if (lock) 527 printk(KERN_WARNING PREFIX "Locking device failed\n"); 528 else 529 printk(KERN_WARNING PREFIX "Unlocking device failed\n"); 530 } 531 } 532 533 /** 534 * dock_in_progress - see if we are in the middle of handling a dock event 535 * @ds: the dock station 536 * 537 * Sometimes while docking, false dock events can be sent to the driver 538 * because good connections aren't made or some other reason. Ignore these 539 * if we are in the middle of doing something. 540 */ 541 static int dock_in_progress(struct dock_station *ds) 542 { 543 if ((ds->flags & DOCK_DOCKING) || 544 time_before(jiffies, (ds->last_dock_time + HZ))) 545 return 1; 546 return 0; 547 } 548 549 /** 550 * register_dock_notifier - add yourself to the dock notifier list 551 * @nb: the callers notifier block 552 * 553 * If a driver wishes to be notified about dock events, they can 554 * use this function to put a notifier block on the dock notifier list. 555 * this notifier call chain will be called after a dock event, but 556 * before hotplugging any new devices. 557 */ 558 int register_dock_notifier(struct notifier_block *nb) 559 { 560 if (!dock_station_count) 561 return -ENODEV; 562 563 return atomic_notifier_chain_register(&dock_notifier_list, nb); 564 } 565 EXPORT_SYMBOL_GPL(register_dock_notifier); 566 567 /** 568 * unregister_dock_notifier - remove yourself from the dock notifier list 569 * @nb: the callers notifier block 570 */ 571 void unregister_dock_notifier(struct notifier_block *nb) 572 { 573 if (!dock_station_count) 574 return; 575 576 atomic_notifier_chain_unregister(&dock_notifier_list, nb); 577 } 578 EXPORT_SYMBOL_GPL(unregister_dock_notifier); 579 580 /** 581 * register_hotplug_dock_device - register a hotplug function 582 * @handle: the handle of the device 583 * @ops: handlers to call after docking 584 * @context: device specific data 585 * 586 * If a driver would like to perform a hotplug operation after a dock 587 * event, they can register an acpi_notifiy_handler to be called by 588 * the dock driver after _DCK is executed. 589 */ 590 int 591 register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops, 592 void *context) 593 { 594 struct dock_dependent_device *dd; 595 struct dock_station *dock_station; 596 int ret = -EINVAL; 597 598 if (!dock_station_count) 599 return -ENODEV; 600 601 /* 602 * make sure this handle is for a device dependent on the dock, 603 * this would include the dock station itself 604 */ 605 list_for_each_entry(dock_station, &dock_stations, sibling) { 606 /* 607 * An ATA bay can be in a dock and itself can be ejected 608 * seperately, so there are two 'dock stations' which need the 609 * ops 610 */ 611 dd = find_dock_dependent_device(dock_station, handle); 612 if (dd) { 613 dd->ops = ops; 614 dd->context = context; 615 dock_add_hotplug_device(dock_station, dd); 616 ret = 0; 617 } 618 } 619 620 return ret; 621 } 622 EXPORT_SYMBOL_GPL(register_hotplug_dock_device); 623 624 /** 625 * unregister_hotplug_dock_device - remove yourself from the hotplug list 626 * @handle: the acpi handle of the device 627 */ 628 void unregister_hotplug_dock_device(acpi_handle handle) 629 { 630 struct dock_dependent_device *dd; 631 struct dock_station *dock_station; 632 633 if (!dock_station_count) 634 return; 635 636 list_for_each_entry(dock_station, &dock_stations, sibling) { 637 dd = find_dock_dependent_device(dock_station, handle); 638 if (dd) 639 dock_del_hotplug_device(dock_station, dd); 640 } 641 } 642 EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device); 643 644 /** 645 * handle_eject_request - handle an undock request checking for error conditions 646 * 647 * Check to make sure the dock device is still present, then undock and 648 * hotremove all the devices that may need removing. 649 */ 650 static int handle_eject_request(struct dock_station *ds, u32 event) 651 { 652 if (dock_in_progress(ds)) 653 return -EBUSY; 654 655 /* 656 * here we need to generate the undock 657 * event prior to actually doing the undock 658 * so that the device struct still exists. 659 * Also, even send the dock event if the 660 * device is not present anymore 661 */ 662 dock_event(ds, event, UNDOCK_EVENT); 663 664 hotplug_dock_devices(ds, ACPI_NOTIFY_EJECT_REQUEST); 665 undock(ds); 666 dock_lock(ds, 0); 667 eject_dock(ds); 668 if (dock_present(ds)) { 669 printk(KERN_ERR PREFIX "Unable to undock!\n"); 670 return -EBUSY; 671 } 672 complete_undock(ds); 673 return 0; 674 } 675 676 /** 677 * dock_notify - act upon an acpi dock notification 678 * @handle: the dock station handle 679 * @event: the acpi event 680 * @data: our driver data struct 681 * 682 * If we are notified to dock, then check to see if the dock is 683 * present and then dock. Notify all drivers of the dock event, 684 * and then hotplug and devices that may need hotplugging. 685 */ 686 static void dock_notify(acpi_handle handle, u32 event, void *data) 687 { 688 struct dock_station *ds = data; 689 struct acpi_device *tmp; 690 int surprise_removal = 0; 691 692 /* 693 * According to acpi spec 3.0a, if a DEVICE_CHECK notification 694 * is sent and _DCK is present, it is assumed to mean an undock 695 * request. 696 */ 697 if ((ds->flags & DOCK_IS_DOCK) && event == ACPI_NOTIFY_DEVICE_CHECK) 698 event = ACPI_NOTIFY_EJECT_REQUEST; 699 700 /* 701 * dock station: BUS_CHECK - docked or surprise removal 702 * DEVICE_CHECK - undocked 703 * other device: BUS_CHECK/DEVICE_CHECK - added or surprise removal 704 * 705 * To simplify event handling, dock dependent device handler always 706 * get ACPI_NOTIFY_BUS_CHECK/ACPI_NOTIFY_DEVICE_CHECK for add and 707 * ACPI_NOTIFY_EJECT_REQUEST for removal 708 */ 709 switch (event) { 710 case ACPI_NOTIFY_BUS_CHECK: 711 case ACPI_NOTIFY_DEVICE_CHECK: 712 if (!dock_in_progress(ds) && acpi_bus_get_device(ds->handle, 713 &tmp)) { 714 begin_dock(ds); 715 dock(ds); 716 if (!dock_present(ds)) { 717 printk(KERN_ERR PREFIX "Unable to dock!\n"); 718 complete_dock(ds); 719 break; 720 } 721 atomic_notifier_call_chain(&dock_notifier_list, 722 event, NULL); 723 hotplug_dock_devices(ds, event); 724 complete_dock(ds); 725 dock_event(ds, event, DOCK_EVENT); 726 dock_lock(ds, 1); 727 break; 728 } 729 if (dock_present(ds) || dock_in_progress(ds)) 730 break; 731 /* This is a surprise removal */ 732 surprise_removal = 1; 733 event = ACPI_NOTIFY_EJECT_REQUEST; 734 /* Fall back */ 735 case ACPI_NOTIFY_EJECT_REQUEST: 736 begin_undock(ds); 737 if ((immediate_undock && !(ds->flags & DOCK_IS_ATA)) 738 || surprise_removal) 739 handle_eject_request(ds, event); 740 else 741 dock_event(ds, event, UNDOCK_EVENT); 742 break; 743 default: 744 printk(KERN_ERR PREFIX "Unknown dock event %d\n", event); 745 } 746 } 747 748 struct dock_data { 749 acpi_handle handle; 750 unsigned long event; 751 struct dock_station *ds; 752 }; 753 754 static void acpi_dock_deferred_cb(void *context) 755 { 756 struct dock_data *data = context; 757 758 dock_notify(data->handle, data->event, data->ds); 759 kfree(data); 760 } 761 762 static int acpi_dock_notifier_call(struct notifier_block *this, 763 unsigned long event, void *data) 764 { 765 struct dock_station *dock_station; 766 acpi_handle handle = data; 767 768 if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK 769 && event != ACPI_NOTIFY_EJECT_REQUEST) 770 return 0; 771 list_for_each_entry(dock_station, &dock_stations, sibling) { 772 if (dock_station->handle == handle) { 773 struct dock_data *dd; 774 775 dd = kmalloc(sizeof(*dd), GFP_KERNEL); 776 if (!dd) 777 return 0; 778 dd->handle = handle; 779 dd->event = event; 780 dd->ds = dock_station; 781 acpi_os_hotplug_execute(acpi_dock_deferred_cb, dd); 782 return 0 ; 783 } 784 } 785 return 0; 786 } 787 788 static struct notifier_block dock_acpi_notifier = { 789 .notifier_call = acpi_dock_notifier_call, 790 }; 791 792 /** 793 * find_dock_devices - find devices on the dock station 794 * @handle: the handle of the device we are examining 795 * @lvl: unused 796 * @context: the dock station private data 797 * @rv: unused 798 * 799 * This function is called by acpi_walk_namespace. It will 800 * check to see if an object has an _EJD method. If it does, then it 801 * will see if it is dependent on the dock station. 802 */ 803 static acpi_status 804 find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv) 805 { 806 acpi_status status; 807 acpi_handle tmp, parent; 808 struct dock_station *ds = context; 809 810 status = acpi_bus_get_ejd(handle, &tmp); 811 if (ACPI_FAILURE(status)) { 812 /* try the parent device as well */ 813 status = acpi_get_parent(handle, &parent); 814 if (ACPI_FAILURE(status)) 815 goto fdd_out; 816 /* see if parent is dependent on dock */ 817 status = acpi_bus_get_ejd(parent, &tmp); 818 if (ACPI_FAILURE(status)) 819 goto fdd_out; 820 } 821 822 if (tmp == ds->handle) 823 add_dock_dependent_device(ds, handle); 824 825 fdd_out: 826 return AE_OK; 827 } 828 829 /* 830 * show_docked - read method for "docked" file in sysfs 831 */ 832 static ssize_t show_docked(struct device *dev, 833 struct device_attribute *attr, char *buf) 834 { 835 struct acpi_device *tmp; 836 837 struct dock_station *dock_station = dev->platform_data; 838 839 if (ACPI_SUCCESS(acpi_bus_get_device(dock_station->handle, &tmp))) 840 return snprintf(buf, PAGE_SIZE, "1\n"); 841 return snprintf(buf, PAGE_SIZE, "0\n"); 842 } 843 static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); 844 845 /* 846 * show_flags - read method for flags file in sysfs 847 */ 848 static ssize_t show_flags(struct device *dev, 849 struct device_attribute *attr, char *buf) 850 { 851 struct dock_station *dock_station = dev->platform_data; 852 return snprintf(buf, PAGE_SIZE, "%d\n", dock_station->flags); 853 854 } 855 static DEVICE_ATTR(flags, S_IRUGO, show_flags, NULL); 856 857 /* 858 * write_undock - write method for "undock" file in sysfs 859 */ 860 static ssize_t write_undock(struct device *dev, struct device_attribute *attr, 861 const char *buf, size_t count) 862 { 863 int ret; 864 struct dock_station *dock_station = dev->platform_data; 865 866 if (!count) 867 return -EINVAL; 868 869 begin_undock(dock_station); 870 ret = handle_eject_request(dock_station, ACPI_NOTIFY_EJECT_REQUEST); 871 return ret ? ret: count; 872 } 873 static DEVICE_ATTR(undock, S_IWUSR, NULL, write_undock); 874 875 /* 876 * show_dock_uid - read method for "uid" file in sysfs 877 */ 878 static ssize_t show_dock_uid(struct device *dev, 879 struct device_attribute *attr, char *buf) 880 { 881 unsigned long long lbuf; 882 struct dock_station *dock_station = dev->platform_data; 883 acpi_status status = acpi_evaluate_integer(dock_station->handle, 884 "_UID", NULL, &lbuf); 885 if (ACPI_FAILURE(status)) 886 return 0; 887 888 return snprintf(buf, PAGE_SIZE, "%llx\n", lbuf); 889 } 890 static DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL); 891 892 static ssize_t show_dock_type(struct device *dev, 893 struct device_attribute *attr, char *buf) 894 { 895 struct dock_station *dock_station = dev->platform_data; 896 char *type; 897 898 if (dock_station->flags & DOCK_IS_DOCK) 899 type = "dock_station"; 900 else if (dock_station->flags & DOCK_IS_ATA) 901 type = "ata_bay"; 902 else if (dock_station->flags & DOCK_IS_BAT) 903 type = "battery_bay"; 904 else 905 type = "unknown"; 906 907 return snprintf(buf, PAGE_SIZE, "%s\n", type); 908 } 909 static DEVICE_ATTR(type, S_IRUGO, show_dock_type, NULL); 910 911 static struct attribute *dock_attributes[] = { 912 &dev_attr_docked.attr, 913 &dev_attr_flags.attr, 914 &dev_attr_undock.attr, 915 &dev_attr_uid.attr, 916 &dev_attr_type.attr, 917 NULL 918 }; 919 920 static struct attribute_group dock_attribute_group = { 921 .attrs = dock_attributes 922 }; 923 924 /** 925 * dock_add - add a new dock station 926 * @handle: the dock station handle 927 * 928 * allocated and initialize a new dock station device. Find all devices 929 * that are on the dock station, and register for dock event notifications. 930 */ 931 static int dock_add(acpi_handle handle) 932 { 933 int ret, id; 934 struct dock_station ds, *dock_station; 935 struct platform_device *dd; 936 937 id = dock_station_count; 938 memset(&ds, 0, sizeof(ds)); 939 dd = platform_device_register_data(NULL, "dock", id, &ds, sizeof(ds)); 940 if (IS_ERR(dd)) 941 return PTR_ERR(dd); 942 943 dock_station = dd->dev.platform_data; 944 945 dock_station->handle = handle; 946 dock_station->dock_device = dd; 947 dock_station->last_dock_time = jiffies - HZ; 948 949 mutex_init(&dock_station->hp_lock); 950 spin_lock_init(&dock_station->dd_lock); 951 INIT_LIST_HEAD(&dock_station->sibling); 952 INIT_LIST_HEAD(&dock_station->hotplug_devices); 953 ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); 954 INIT_LIST_HEAD(&dock_station->dependent_devices); 955 956 /* we want the dock device to send uevents */ 957 dev_set_uevent_suppress(&dd->dev, 0); 958 959 if (is_dock(handle)) 960 dock_station->flags |= DOCK_IS_DOCK; 961 if (is_ata(handle)) 962 dock_station->flags |= DOCK_IS_ATA; 963 if (is_battery(handle)) 964 dock_station->flags |= DOCK_IS_BAT; 965 966 ret = sysfs_create_group(&dd->dev.kobj, &dock_attribute_group); 967 if (ret) 968 goto err_unregister; 969 970 /* Find dependent devices */ 971 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 972 ACPI_UINT32_MAX, find_dock_devices, NULL, 973 dock_station, NULL); 974 975 /* add the dock station as a device dependent on itself */ 976 ret = add_dock_dependent_device(dock_station, handle); 977 if (ret) 978 goto err_rmgroup; 979 980 dock_station_count++; 981 list_add(&dock_station->sibling, &dock_stations); 982 return 0; 983 984 err_rmgroup: 985 sysfs_remove_group(&dd->dev.kobj, &dock_attribute_group); 986 err_unregister: 987 platform_device_unregister(dd); 988 printk(KERN_ERR "%s encountered error %d\n", __func__, ret); 989 return ret; 990 } 991 992 /** 993 * dock_remove - free up resources related to the dock station 994 */ 995 static int dock_remove(struct dock_station *ds) 996 { 997 struct dock_dependent_device *dd, *tmp; 998 struct platform_device *dock_device = ds->dock_device; 999 1000 if (!dock_station_count) 1001 return 0; 1002 1003 /* remove dependent devices */ 1004 list_for_each_entry_safe(dd, tmp, &ds->dependent_devices, list) 1005 kfree(dd); 1006 1007 list_del(&ds->sibling); 1008 1009 /* cleanup sysfs */ 1010 sysfs_remove_group(&dock_device->dev.kobj, &dock_attribute_group); 1011 platform_device_unregister(dock_device); 1012 1013 return 0; 1014 } 1015 1016 /** 1017 * find_dock - look for a dock station 1018 * @handle: acpi handle of a device 1019 * @lvl: unused 1020 * @context: counter of dock stations found 1021 * @rv: unused 1022 * 1023 * This is called by acpi_walk_namespace to look for dock stations. 1024 */ 1025 static acpi_status 1026 find_dock(acpi_handle handle, u32 lvl, void *context, void **rv) 1027 { 1028 acpi_status status = AE_OK; 1029 1030 if (is_dock(handle)) 1031 if (dock_add(handle) >= 0) 1032 status = AE_CTRL_TERMINATE; 1033 1034 return status; 1035 } 1036 1037 static acpi_status 1038 find_bay(acpi_handle handle, u32 lvl, void *context, void **rv) 1039 { 1040 /* If bay is a dock, it's already handled */ 1041 if (is_ejectable_bay(handle) && !is_dock(handle)) 1042 dock_add(handle); 1043 return AE_OK; 1044 } 1045 1046 static int __init dock_init(void) 1047 { 1048 if (acpi_disabled) 1049 return 0; 1050 1051 /* look for a dock station */ 1052 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 1053 ACPI_UINT32_MAX, find_dock, NULL, NULL, NULL); 1054 1055 /* look for bay */ 1056 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 1057 ACPI_UINT32_MAX, find_bay, NULL, NULL, NULL); 1058 if (!dock_station_count) { 1059 printk(KERN_INFO PREFIX "No dock devices found.\n"); 1060 return 0; 1061 } 1062 1063 register_acpi_bus_notifier(&dock_acpi_notifier); 1064 printk(KERN_INFO PREFIX "%s: %d docks/bays found\n", 1065 ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count); 1066 return 0; 1067 } 1068 1069 static void __exit dock_exit(void) 1070 { 1071 struct dock_station *tmp, *dock_station; 1072 1073 unregister_acpi_bus_notifier(&dock_acpi_notifier); 1074 list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibling) 1075 dock_remove(dock_station); 1076 } 1077 1078 /* 1079 * Must be called before drivers of devices in dock, otherwise we can't know 1080 * which devices are in a dock 1081 */ 1082 subsys_initcall(dock_init); 1083 module_exit(dock_exit); 1084