ide-bus.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * ide bus support for qdev.
  3. *
  4. * Copyright (c) 2009 Gerd Hoffmann <kraxel@redhat.com>
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "qemu/osdep.h"
  20. #include "qapi/error.h"
  21. #include "qemu/error-report.h"
  22. #include "qemu/module.h"
  23. #include "system/block-backend.h"
  24. #include "system/blockdev.h"
  25. #include "system/runstate.h"
  26. #include "ide-internal.h"
  27. static char *idebus_get_fw_dev_path(DeviceState *dev);
  28. static void idebus_unrealize(BusState *qdev);
  29. static void ide_bus_class_init(ObjectClass *klass, void *data)
  30. {
  31. BusClass *k = BUS_CLASS(klass);
  32. k->get_fw_dev_path = idebus_get_fw_dev_path;
  33. k->unrealize = idebus_unrealize;
  34. }
  35. static void idebus_unrealize(BusState *bus)
  36. {
  37. IDEBus *ibus = IDE_BUS(bus);
  38. if (ibus->vmstate) {
  39. qemu_del_vm_change_state_handler(ibus->vmstate);
  40. }
  41. }
  42. static const TypeInfo ide_bus_info = {
  43. .name = TYPE_IDE_BUS,
  44. .parent = TYPE_BUS,
  45. .instance_size = sizeof(IDEBus),
  46. .class_init = ide_bus_class_init,
  47. };
  48. void ide_bus_init(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
  49. int bus_id, int max_units)
  50. {
  51. qbus_init(idebus, idebus_size, TYPE_IDE_BUS, dev, NULL);
  52. idebus->bus_id = bus_id;
  53. idebus->max_units = max_units;
  54. }
  55. static char *idebus_get_fw_dev_path(DeviceState *dev)
  56. {
  57. char path[30];
  58. snprintf(path, sizeof(path), "%s@%x", qdev_fw_name(dev),
  59. ((IDEBus *)dev->parent_bus)->bus_id);
  60. return g_strdup(path);
  61. }
  62. IDEDevice *ide_bus_create_drive(IDEBus *bus, int unit, DriveInfo *drive)
  63. {
  64. DeviceState *dev;
  65. dev = qdev_new(drive->media_cd ? "ide-cd" : "ide-hd");
  66. qdev_prop_set_uint32(dev, "unit", unit);
  67. qdev_prop_set_drive_err(dev, "drive", blk_by_legacy_dinfo(drive),
  68. &error_fatal);
  69. qdev_realize_and_unref(dev, &bus->qbus, &error_fatal);
  70. return DO_UPCAST(IDEDevice, qdev, dev);
  71. }
  72. int ide_get_geometry(BusState *bus, int unit,
  73. int16_t *cyls, int8_t *heads, int8_t *secs)
  74. {
  75. IDEState *s = &DO_UPCAST(IDEBus, qbus, bus)->ifs[unit];
  76. if (s->drive_kind != IDE_HD || !s->blk) {
  77. return -1;
  78. }
  79. *cyls = s->cylinders;
  80. *heads = s->heads;
  81. *secs = s->sectors;
  82. return 0;
  83. }
  84. int ide_get_bios_chs_trans(BusState *bus, int unit)
  85. {
  86. return DO_UPCAST(IDEBus, qbus, bus)->ifs[unit].chs_trans;
  87. }
  88. static void ide_bus_register_type(void)
  89. {
  90. type_register_static(&ide_bus_info);
  91. }
  92. type_init(ide_bus_register_type)