From patchwork Fri Sep 18 22:06:45 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 519596 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 9463114090B for ; Sat, 19 Sep 2015 08:07:26 +1000 (AEST) Received: from localhost ([::1]:42168 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zd3oS-0003VN-71 for incoming@patchwork.ozlabs.org; Fri, 18 Sep 2015 18:07:24 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40816) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zd3o4-000307-OL for qemu-devel@nongnu.org; Fri, 18 Sep 2015 18:07:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Zd3ny-0006oC-Gm for qemu-devel@nongnu.org; Fri, 18 Sep 2015 18:07:00 -0400 Received: from mx1.redhat.com ([209.132.183.28]:44136) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zd3ny-0006ly-73; Fri, 18 Sep 2015 18:06:54 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id E00A1A1454; Fri, 18 Sep 2015 22:06:52 +0000 (UTC) Received: from xeon.redhat.com (vpn1-6-47.ams2.redhat.com [10.36.6.47]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t8IM6nwJ014904; Fri, 18 Sep 2015 18:06:50 -0400 From: Laurent Vivier To: qemu-ppc@nongnu.org Date: Sat, 19 Sep 2015 00:06:45 +0200 Message-Id: <1442614005-22707-1-git-send-email-lvivier@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: qemu-devel@nongnu.org, Laurent Vivier , Alexander Graf , David Gibson Subject: [Qemu-devel] [PATCH] spapr: generate DT node names X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org When DT node names for PCI devices are generated by SLOF, they are generated according to the type of the device (for instance, ethernet for virtio-net-pci device). Node name for hotplugged devices is generated by QEMU. This patch adds the mechanic to QEMU to create the node name according to the device type too. The data structure has been roughly copied from OpenBIOS/OpenHackware, node names from SLOF. Example: Hotplugging some PCI cards with QEMU monitor: device_add virtio-tablet-pci device_add virtio-serial-pci device_add virtio-mouse-pci device_add virtio-scsi-pci device_add virtio-gpu-pci device_add ne2k_pci device_add nec-usb-xhci device_add intel-hda What we can see in linux device tree: echo $dir cat $dir/name echo done WITHOUT this patch: /proc/device-tree/pci@800000020000000/pci@0/ pci /proc/device-tree/pci@800000020000000/pci@1/ pci /proc/device-tree/pci@800000020000000/pci@2/ pci /proc/device-tree/pci@800000020000000/pci@3/ pci /proc/device-tree/pci@800000020000000/pci@4/ pci /proc/device-tree/pci@800000020000000/pci@5/ pci /proc/device-tree/pci@800000020000000/pci@6/ pci /proc/device-tree/pci@800000020000000/pci@7/ WITH this patch: /proc/device-tree/pci@800000020000000/ethernet@5/ ethernet /proc/device-tree/pci@800000020000000/misc-communication-controller@1/ misc-communication-controller /proc/device-tree/pci@800000020000000/misc-display-controller@4/ misc-display-controller /proc/device-tree/pci@800000020000000/misc-input-device@0/ misc-input-device /proc/device-tree/pci@800000020000000/mouse@2/ mouse /proc/device-tree/pci@800000020000000/multimedia-device@7/ multimedia-device /proc/device-tree/pci@800000020000000/scsi@3/ scsi /proc/device-tree/pci@800000020000000/usb-xhci@6/ usb-xhci Signed-off-by: Laurent Vivier --- hw/ppc/spapr_pci.c | 502 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 488 insertions(+), 14 deletions(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index a2feb4c..ca3a0ba 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -944,6 +944,487 @@ static void populate_resource_props(PCIDevice *d, ResourceProps *rp) rp->assigned_len = assigned_idx * sizeof(ResourceFields); } +/* Device classes and subclasses */ + +#define PCI_BASE_CLASS_STORAGE 0x01 +#define PCI_SUBCLASS_STORAGE_SCSI 0x00 +#define PCI_SUBCLASS_STORAGE_IDE 0x01 +#define PCI_SUBCLASS_STORAGE_FLOPPY 0x02 +#define PCI_SUBCLASS_STORAGE_IPI 0x03 +#define PCI_SUBCLASS_STORAGE_RAID 0x04 +#define PCI_SUBCLASS_STORAGE_ATA 0x05 +#define PCI_SUBCLASS_STORAGE_SATA 0x06 +#define PCI_SUBCLASS_STORAGE_SAS 0x07 +#define PCI_SUBCLASS_STORAGE_OTHER 0x80 + +#define PCI_BASE_CLASS_NETWORK 0x02 +#define PCI_SUBCLASS_NETWORK_ETHERNET 0x00 +#define PCI_SUBCLASS_NETWORK_TOKEN_RING 0x01 +#define PCI_SUBCLASS_NETWORK_FDDI 0x02 +#define PCI_SUBCLASS_NETWORK_ATM 0x03 +#define PCI_SUBCLASS_NETWORK_ISDN 0x04 +#define PCI_SUBCLASS_NETWORK_WORDFIP 0x05 +#define PCI_SUBCLASS_NETWORK_PICMG214 0x06 +#define PCI_SUBCLASS_NETWORK_OTHER 0x80 + +#define PCI_BASE_CLASS_DISPLAY 0x03 +#define PCI_SUBCLASS_DISPLAY_VGA 0x00 +#define PCI_SUBCLASS_DISPLAY_XGA 0x01 +#define PCI_SUBCLASS_DISPLAY_3D 0x02 +#define PCI_SUBCLASS_DISPLAY_OTHER 0x80 + +#define PCI_BASE_CLASS_MULTIMEDIA 0x04 +#define PCI_SUBCLASS_MULTIMEDIA_VIDEO 0x00 +#define PCI_SUBCLASS_MULTIMEDIA_AUDIO 0x01 +#define PCI_SUBCLASS_MULTIMEDIA_PHONE 0x02 +#define PCI_SUBCLASS_MULTIMEDIA_OTHER 0x80 + +#define PCI_BASE_CLASS_MEMORY 0x05 +#define PCI_SUBCLASS_MEMORY_RAM 0x00 +#define PCI_SUBCLASS_MEMORY_FLASH 0x01 + +#define PCI_BASE_CLASS_BRIDGE 0x06 +#define PCI_SUBCLASS_BRIDGE_HOST 0x00 +#define PCI_SUBCLASS_BRIDGE_ISA 0x01 +#define PCI_SUBCLASS_BRIDGE_EISA 0x02 +#define PCI_SUBCLASS_BRIDGE_MC 0x03 +#define PCI_SUBCLASS_BRIDGE_PCI 0x04 +#define PCI_SUBCLASS_BRIDGE_PCMCIA 0x05 +#define PCI_SUBCLASS_BRIDGE_NUBUS 0x06 +#define PCI_SUBCLASS_BRIDGE_CARDBUS 0x07 +#define PCI_SUBCLASS_BRIDGE_RACEWAY 0x08 +#define PCI_SUBCLASS_BRIDGE_PCI_SEMITP 0x09 +#define PCI_SUBCLASS_BRIDGE_IB_PCI 0x0a +#define PCI_SUBCLASS_BRIDGE_OTHER 0x80 + +#define PCI_BASE_CLASS_COMMUNICATION 0x07 +#define PCI_SUBCLASS_COMMUNICATION_SERIAL 0x00 +#define PCI_SUBCLASS_COMMUNICATION_PARALLEL 0x01 +#define PCI_SUBCLASS_COMMUNICATION_MULTISERIAL 0x02 +#define PCI_SUBCLASS_COMMUNICATION_MODEM 0x03 +#define PCI_SUBCLASS_COMMUNICATION_GPIB 0x04 +#define PCI_SUBCLASS_COMMUNICATION_SC 0x05 +#define PCI_SUBCLASS_COMMUNICATION_OTHER 0x80 + +#define PCI_BASE_CLASS_SYSTEM 0x08 +#define PCI_SUBCLASS_SYSTEM_PIC 0x00 +#define PCI_SUBCLASS_SYSTEM_DMA 0x01 +#define PCI_SUBCLASS_SYSTEM_TIMER 0x02 +#define PCI_SUBCLASS_SYSTEM_RTC 0x03 +#define PCI_SUBCLASS_SYSTEM_HOTPLUG 0x04 +#define PCI_SUBCLASS_SYSTEM_SD 0x05 +#define PCI_SUBCLASS_SYSTEM_OTHER 0x80 + +#define PCI_BASE_CLASS_INPUT 0x09 +#define PCI_SUBCLASS_INPUT_KEYBOARD 0x00 +#define PCI_SUBCLASS_INPUT_PEN 0x01 +#define PCI_SUBCLASS_INPUT_MOUSE 0x02 +#define PCI_SUBCLASS_INPUT_SCANNER 0x03 +#define PCI_SUBCLASS_INPUT_GAMEPORT 0x04 +#define PCI_SUBCLASS_INPUT_OTHER 0x80 + +#define PCI_BASE_CLASS_DOCKING 0x0a +#define PCI_SUBCLASS_DOCKING_GENERIC 0x00 +#define PCI_SUBCLASS_DOCKING_OTHER 0x80 + +#define PCI_BASE_CLASS_PROCESSOR 0x0b +#define PCI_SUBCLASS_PROCESSOR_386 0x00 +#define PCI_SUBCLASS_PROCESSOR_486 0x01 +#define PCI_SUBCLASS_PROCESSOR_PENTIUM 0x02 +#define PCI_SUBCLASS_PROCESSOR_ALPHA 0x10 +#define PCI_SUBCLASS_PROCESSOR_POWERPC 0x20 +#define PCI_SUBCLASS_PROCESSOR_MIPS 0x30 +#define PCI_SUBCLASS_PROCESSOR_CO 0x40 + +#define PCI_BASE_CLASS_SERIAL 0x0c +#define PCI_SUBCLASS_SERIAL_FIREWIRE 0x00 +#define PCI_SUBCLASS_SERIAL_ACCESS 0x01 +#define PCI_SUBCLASS_SERIAL_SSA 0x02 +#define PCI_SUBCLASS_SERIAL_USB 0x03 +#define PCI_SUBCLASS_SERIAL_FIBER 0x04 +#define PCI_SUBCLASS_SERIAL_SMBUS 0x05 +#define PCI_SUBCLASS_SERIAL_IB 0x06 +#define PCI_SUBCLASS_SERIAL_IPMI 0x07 +#define PCI_SUBCLASS_SERIAL_SERCOS 0x08 +#define PCI_SUBCLASS_SERIAL_CANBUS 0x09 + +#define PCI_BASE_CLASS_WIRELESS 0x0d +#define PCI_SUBCLASS_WIRELESS_IRDA 0x00 +#define PCI_SUBCLASS_WIRELESS_CIR 0x01 +#define PCI_SUBCLASS_WIRELESS_RF_CONTROLLER 0x10 +#define PCI_SUBCLASS_WIRELESS_BLUETOOTH 0x11 +#define PCI_SUBCLASS_WIRELESS_BROADBAND 0x12 +#define PCI_SUBCLASS_WIRELESS_OTHER 0x80 + +#define PCI_BASE_CLASS_SATELLITE 0x0f +#define PCI_SUBCLASS_SATELLITE_TV 0x00 +#define PCI_SUBCLASS_SATELLITE_AUDIO 0x01 +#define PCI_SUBCLASS_SATELLITE_VOICE 0x03 +#define PCI_SUBCLASS_SATELLITE_DATA 0x04 + +#define PCI_BASE_CLASS_CRYPT 0x10 +#define PCI_SUBCLASS_CRYPT_NETWORK 0x00 +#define PCI_SUBCLASS_CRYPT_ENTERTAINMENT 0x01 +#define PCI_SUBCLASS_CRYPT_OTHER 0x80 + +#define PCI_BASE_CLASS_SIGNAL_PROCESSING 0x11 +#define PCI_SUBCLASS_SP_DPIO 0x00 +#define PCI_SUBCLASS_SP_PERF 0x01 +#define PCI_SUBCLASS_SP_SYNCH 0x10 +#define PCI_SUBCLASS_SP_MANAGEMENT 0x20 +#define PCI_SUBCLASS_SP_OTHER 0x80 + +#define PCI_CLASS_OTHERS 0xff + +typedef struct pci_class_t pci_class_t; +typedef struct pci_subclass_t pci_subclass_t; +typedef struct pci_iface_t pci_iface_t; + +struct pci_iface_t { + uint8_t iface; + const char *name; +}; + +struct pci_subclass_t { + uint8_t subclass; + const char *name; + const pci_iface_t *iface; +}; + +struct pci_class_t { + const char *name; + const pci_subclass_t *subc; +}; + +static const pci_subclass_t undef_subclass[] = { + { 0x01, "display", NULL }, + { 0xFF, NULL, NULL, NULL }, +}; + +static const pci_subclass_t mass_subclass[] = { + { PCI_SUBCLASS_STORAGE_SCSI, "scsi", NULL }, + { PCI_SUBCLASS_STORAGE_IDE, "ide", NULL }, + { PCI_SUBCLASS_STORAGE_FLOPPY, "fdc", NULL }, + { PCI_SUBCLASS_STORAGE_IPI, "ipi", NULL }, + { PCI_SUBCLASS_STORAGE_RAID, "raid", NULL }, + { PCI_SUBCLASS_STORAGE_ATA, "ata", NULL }, + { PCI_SUBCLASS_STORAGE_SATA, "sata", NULL }, + { PCI_SUBCLASS_STORAGE_SAS, "sas", NULL }, + { PCI_SUBCLASS_STORAGE_OTHER, "mass-storage", NULL }, + { 0xFF, NULL, NULL }, +}; + +static const pci_subclass_t net_subclass[] = { + { PCI_SUBCLASS_NETWORK_ETHERNET, "ethernet", NULL }, + { PCI_SUBCLASS_NETWORK_TOKEN_RING, "token-ring", NULL }, + { PCI_SUBCLASS_NETWORK_FDDI, "fddi", NULL }, + { PCI_SUBCLASS_NETWORK_ATM, "atm", NULL }, + { PCI_SUBCLASS_NETWORK_ISDN, "isdn", NULL }, + { PCI_SUBCLASS_NETWORK_WORDFIP, "worldfip", NULL }, + { PCI_SUBCLASS_NETWORK_PICMG214, "picmg", NULL }, + { PCI_SUBCLASS_NETWORK_OTHER, "network", NULL }, + { 0xFF, NULL, NULL }, +}; + +static const struct pci_iface_t vga_iface[] = { + { 0x00, "VGA", }, + { 0x01, "8514-compatible", }, + { 0xFF, NULL, }, +}; + +static const pci_subclass_t displ_subclass[] = { + { PCI_SUBCLASS_DISPLAY_VGA, "vga", vga_iface }, + { PCI_SUBCLASS_DISPLAY_XGA, "xga", NULL }, + { PCI_SUBCLASS_DISPLAY_3D, "3d-controller", NULL }, + { PCI_SUBCLASS_DISPLAY_OTHER, "misc-display-controller", NULL }, + { 0xFF, NULL, NULL }, +}; + +static const pci_subclass_t media_subclass[] = { + { PCI_SUBCLASS_MULTIMEDIA_VIDEO, "video", NULL }, + { PCI_SUBCLASS_MULTIMEDIA_AUDIO, "sound", NULL }, + { PCI_SUBCLASS_MULTIMEDIA_PHONE, "telephony", NULL }, + { PCI_SUBCLASS_MULTIMEDIA_OTHER, "misc-multimedia-device", NULL }, + { 0xFF, NULL, NULL }, +}; + +static const pci_subclass_t mem_subclass[] = { + { PCI_SUBCLASS_MEMORY_RAM, "memory", NULL }, + { PCI_SUBCLASS_MEMORY_FLASH, "flash", NULL }, + { 0xFF, NULL, NULL }, +}; + + +static const pci_subclass_t bridg_subclass[] = { + { PCI_SUBCLASS_BRIDGE_HOST, "host", NULL }, + { PCI_SUBCLASS_BRIDGE_ISA, "isa", NULL }, + { PCI_SUBCLASS_BRIDGE_EISA, "eisa", NULL }, + { PCI_SUBCLASS_BRIDGE_MC, "mca", NULL }, + { PCI_SUBCLASS_BRIDGE_PCI, "pci", NULL }, + { PCI_SUBCLASS_BRIDGE_PCMCIA, "pcmcia", NULL }, + { PCI_SUBCLASS_BRIDGE_NUBUS, "nubus", NULL }, + { PCI_SUBCLASS_BRIDGE_CARDBUS, "cardbus", NULL }, + { PCI_SUBCLASS_BRIDGE_RACEWAY, "raceway", NULL }, + { PCI_SUBCLASS_BRIDGE_PCI_SEMITP, "semi-transparent-pci", NULL }, + { PCI_SUBCLASS_BRIDGE_IB_PCI, "infiniband", NULL }, + { PCI_SUBCLASS_BRIDGE_OTHER, "misc-brige", NULL }, + { 0xFF, NULL, NULL }, +}; + +static const pci_iface_t serial_iface[] = { + { 0x00, "serial" }, + { 0x01, "16450-serial" }, + { 0x02, "16550-serial" }, + { 0x03, "16650-serial" }, + { 0x04, "16750-serial" }, + { 0x05, "16850-serial" }, + { 0x06, "16950-serial" }, + { 0xFF, NULL }, +}; + +static const pci_iface_t par_iface[] = { + { 0x00, "parallel" }, + { 0x01, "bi-directional-parallel" }, + { 0x02, "ecp-1.x-parallel" }, + { 0x03, "ieee1284-controller" }, + { 0xFE, "ieee1284-device" }, + { 0xFF, NULL }, +}; + +static const pci_iface_t modem_iface[] = { + { 0x00, "modem" }, + { 0x01, "16450-modem" }, + { 0x02, "16550-modem" }, + { 0x03, "16650-modem" }, + { 0x04, "16750-modem" }, + { 0xFF, NULL }, +}; + +static const pci_subclass_t comm_subclass[] = { + { PCI_SUBCLASS_COMMUNICATION_SERIAL, "serial", serial_iface }, + { PCI_SUBCLASS_COMMUNICATION_PARALLEL, "parallel", par_iface }, + { PCI_SUBCLASS_COMMUNICATION_MULTISERIAL, "multiport-serial", NULL }, + { PCI_SUBCLASS_COMMUNICATION_MODEM, "modem", modem_iface }, + { PCI_SUBCLASS_COMMUNICATION_GPIB, "gpib", NULL }, + { PCI_SUBCLASS_COMMUNICATION_SC, "smart-card", NULL }, + { PCI_SUBCLASS_COMMUNICATION_OTHER, "misc-communication-controller", + NULL }, + { 0xFF, NULL, NULL, NULL }, +}; + +static const pci_iface_t pic_iface[] = { + { 0x00, "8259-pic" }, + { 0x01, "isa-pic" }, + { 0x02, "eisa-pic" }, + { 0x10, "io-apic" }, + { 0x20, "io-apic" }, + { 0xFF, NULL }, +}; + +static const pci_iface_t dma_iface[] = { + { 0x00, "dma-controller" }, + { 0x01, "isa-dma" }, + { 0x02, "eisa-dma" }, + { 0xFF, NULL }, +}; + +static const pci_iface_t tmr_iface[] = { + { 0x00, "8254-system-timer" }, + { 0x01, "isa-system-timer", }, + { 0x02, "eisa-system-timer" }, + { 0xFF, NULL }, +}; + +static const pci_iface_t rtc_iface[] = { + { 0x00, "rtc" }, + { 0x01, "isa-rtc" }, + { 0xFF, NULL }, +}; + +static const pci_subclass_t sys_subclass[] = { + { PCI_SUBCLASS_SYSTEM_PIC, "interrupt-controller", pic_iface }, + { PCI_SUBCLASS_SYSTEM_DMA, "dma-controller", dma_iface }, + { PCI_SUBCLASS_SYSTEM_TIMER, "timer", tmr_iface }, + { PCI_SUBCLASS_SYSTEM_RTC, "rtc", rtc_iface }, + { PCI_SUBCLASS_SYSTEM_HOTPLUG, "hot-plug-controller", NULL }, + { PCI_SUBCLASS_SYSTEM_SD, "sd-host-controller", NULL }, + { PCI_SUBCLASS_SYSTEM_OTHER, "misc-system-peripheral", NULL }, + { 0xFF, NULL, NULL }, +}; + +static const pci_subclass_t inp_subclass[] = { + { PCI_SUBCLASS_INPUT_KEYBOARD, "keyboard", NULL }, + { PCI_SUBCLASS_INPUT_PEN, "pen", NULL }, + { PCI_SUBCLASS_INPUT_MOUSE, "mouse", NULL }, + { PCI_SUBCLASS_INPUT_SCANNER, "scanner", NULL }, + { PCI_SUBCLASS_INPUT_GAMEPORT, "gameport", NULL }, + { PCI_SUBCLASS_INPUT_OTHER, "misc-input-device", NULL }, + { 0xFF, NULL, NULL }, +}; + +static const pci_subclass_t dock_subclass[] = { + { PCI_SUBCLASS_DOCKING_GENERIC, "dock", NULL }, + { PCI_SUBCLASS_DOCKING_OTHER, "docking-station", NULL }, + { 0xFF, NULL, NULL }, +}; + +static const pci_subclass_t cpu_subclass[] = { + { PCI_SUBCLASS_PROCESSOR_386, "386", NULL }, + { PCI_SUBCLASS_PROCESSOR_486, "486", NULL }, + { PCI_SUBCLASS_PROCESSOR_PENTIUM, "pentium", NULL }, + { PCI_SUBCLASS_PROCESSOR_ALPHA, "alpha", NULL }, + { PCI_SUBCLASS_PROCESSOR_POWERPC, "powerpc", NULL }, + { PCI_SUBCLASS_PROCESSOR_MIPS, "mips", NULL }, + { PCI_SUBCLASS_PROCESSOR_CO, "co-processor", NULL }, + { 0xFF, NULL, NULL }, +}; + +static const pci_iface_t usb_iface[] = { + { 0x00, "usb-uhci" }, + { 0x10, "usb-ohci", }, + { 0x20, "usb-ehci" }, + { 0x30, "usb-xhci" }, + { 0x80, "misc-usb-controller" }, + { 0xFE, "usb-device" }, + { 0xFF, NULL }, +}; + +static const pci_iface_t ipmi_iface[] = { + { 0x00, "ipmi-smic" }, + { 0x01, "ipmi-kbrd" }, + { 0x02, "IPMI-bltr" }, + { 0xFF, NULL }, +}; + +static const pci_subclass_t ser_subclass[] = { + { PCI_SUBCLASS_SERIAL_FIREWIRE, "firewire", NULL }, + { PCI_SUBCLASS_SERIAL_ACCESS, "access-bus", NULL }, + { PCI_SUBCLASS_SERIAL_SSA, "ssa", NULL }, + { PCI_SUBCLASS_SERIAL_USB, "usb", usb_iface }, + { PCI_SUBCLASS_SERIAL_FIBER, "fibre-channel", NULL }, + { PCI_SUBCLASS_SERIAL_SMBUS, "smb", NULL }, + { PCI_SUBCLASS_SERIAL_IB, "infiniband", NULL }, + { PCI_SUBCLASS_SERIAL_IPMI, "ipmi", ipmi_iface }, + { PCI_SUBCLASS_SERIAL_SERCOS, "sercos", NULL }, + { PCI_SUBCLASS_SERIAL_CANBUS, "canbus", NULL }, + { 0xFF, NULL, NULL }, +}; + +static const pci_subclass_t wrl_subclass[] = { + { PCI_SUBCLASS_WIRELESS_IRDA, "irda", NULL }, + { PCI_SUBCLASS_WIRELESS_CIR, "consumer-ir", NULL }, + { PCI_SUBCLASS_WIRELESS_RF_CONTROLLER, "rf-controller", NULL }, + { PCI_SUBCLASS_WIRELESS_BLUETOOTH, "bluetooth", NULL }, + { PCI_SUBCLASS_WIRELESS_BROADBAND, "broadband", NULL }, + { PCI_SUBCLASS_WIRELESS_OTHER, "misc-wireless-controller", NULL }, + { 0xFF, NULL, NULL }, +}; + +static const pci_subclass_t sat_subclass[] = { + { PCI_SUBCLASS_SATELLITE_TV, "satellite-tv", NULL }, + { PCI_SUBCLASS_SATELLITE_AUDIO, "satellite-audio", NULL }, + { PCI_SUBCLASS_SATELLITE_VOICE, "satellite-voice", NULL }, + { PCI_SUBCLASS_SATELLITE_DATA, "satellite-data", NULL }, + { 0xFF, NULL, NULL }, +}; + +static const pci_subclass_t crypt_subclass[] = { + { PCI_SUBCLASS_CRYPT_NETWORK, "network-encryption", NULL }, + { PCI_SUBCLASS_CRYPT_ENTERTAINMENT, "entertainment-encryption", NULL }, + { PCI_SUBCLASS_CRYPT_OTHER, "misc-encryption", NULL }, + { 0xFF, NULL, NULL }, +}; + +static const pci_subclass_t spc_subclass[] = { + { PCI_SUBCLASS_SP_DPIO, "dpio", NULL }, + { PCI_SUBCLASS_SP_PERF, "counter", NULL }, + { PCI_SUBCLASS_SP_SYNCH, "measurement", NULL }, + { PCI_SUBCLASS_SP_MANAGEMENT, "management-card", NULL }, + { PCI_SUBCLASS_SP_OTHER, "misc-signal-processing-controller", NULL }, + { 0xFF, NULL, NULL }, +}; + +static const pci_class_t pci_classes[] = { + { "unknown-legacy-device", undef_subclass }, + { "mass-storage", mass_subclass }, + { "network", net_subclass }, + { "display", displ_subclass, }, + { "multimedia-device", media_subclass }, + { "memory-controller", mem_subclass }, + { "unknown-bridge", bridg_subclass }, + { "communication-controller", comm_subclass}, + { "system-peripheral", sys_subclass }, + { "input-controller", inp_subclass }, + { "docking-station", dock_subclass }, + { "cpu", cpu_subclass }, + { "serial-bus", ser_subclass }, + { "wireless-controller", wrl_subclass }, + { "intelligent-io", NULL }, + { "satellite-device", sat_subclass }, + { "encryption", crypt_subclass }, + { "data-processing-controller", spc_subclass }, +}; + +static const char *pci_find_device_name(uint8_t class, uint8_t subclass, + uint8_t iface) +{ + const pci_class_t *pclass; + const pci_subclass_t *psubclass; + const pci_iface_t *piface; + const char *name; + + if (class > (sizeof(pci_classes) / sizeof(pci_class_t))) { + return "pci"; + } + + pclass = pci_classes + class; + name = pclass->name; + + if (pclass->subc == NULL) { + return name; + } + + psubclass = pclass->subc; + while (psubclass->subclass != 0xff) { + if (psubclass->subclass == subclass) { + name = psubclass->name; + break; + } + psubclass++; + } + + piface = psubclass->iface; + if (piface == NULL) { + return name; + } + while (piface->iface != 0xff) { + if (piface->iface == iface) { + name = piface->name; + break; + } + piface++; + } + + return name; +} + +static void pci_get_node_name(char *nodename, int len, PCIDevice *dev) +{ + int slot = PCI_SLOT(dev->devfn); + int func = PCI_FUNC(dev->devfn); + uint32_t ccode = pci_default_read_config(dev, PCI_CLASS_PROG, 3); + const char *name; + + name = pci_find_device_name((ccode >> 16) & 0xff, (ccode >> 8) & 0xff, + ccode & 0xff); + + if (func != 0) { + snprintf(nodename, len, "%s@%x,%x", name, slot, func); + } else { + snprintf(nodename, len, "%s@%x", name, slot); + } +} + static uint32_t spapr_phb_get_pci_drc_index(sPAPRPHBState *phb, PCIDevice *pdev); @@ -955,6 +1436,7 @@ static int spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset, int pci_status, err; char *buf = NULL; uint32_t drc_index = spapr_phb_get_pci_drc_index(sphb, dev); + uint32_t ccode = pci_default_read_config(dev, PCI_CLASS_PROG, 3); if (pci_default_read_config(dev, PCI_HEADER_TYPE, 1) == PCI_HEADER_TYPE_BRIDGE) { @@ -968,8 +1450,7 @@ static int spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset, pci_default_read_config(dev, PCI_DEVICE_ID, 2))); _FDT(fdt_setprop_cell(fdt, offset, "revision-id", pci_default_read_config(dev, PCI_REVISION_ID, 1))); - _FDT(fdt_setprop_cell(fdt, offset, "class-code", - pci_default_read_config(dev, PCI_CLASS_PROG, 3))); + _FDT(fdt_setprop_cell(fdt, offset, "class-code", ccode)); if (pci_default_read_config(dev, PCI_INTERRUPT_PIN, 1)) { _FDT(fdt_setprop_cell(fdt, offset, "interrupts", pci_default_read_config(dev, PCI_INTERRUPT_PIN, 1))); @@ -1010,11 +1491,10 @@ static int spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset, _FDT(fdt_setprop(fdt, offset, "udf-supported", NULL, 0)); } - /* NOTE: this is normally generated by firmware via path/unit name, - * but in our case we must set it manually since it does not get - * processed by OF beforehand - */ - _FDT(fdt_setprop_string(fdt, offset, "name", "pci")); + _FDT(fdt_setprop_string(fdt, offset, "name", + pci_find_device_name((ccode >> 16) & 0xff, + (ccode >> 8) & 0xff, + ccode & 0xff))); buf = spapr_phb_get_loc_code(sphb, dev); if (!buf) { error_report("Failed setting the ibm,loc-code"); @@ -1051,15 +1531,9 @@ static int spapr_create_pci_child_dt(sPAPRPHBState *phb, PCIDevice *dev, void *fdt, int node_offset) { int offset, ret; - int slot = PCI_SLOT(dev->devfn); - int func = PCI_FUNC(dev->devfn); char nodename[FDT_NAME_MAX]; - if (func != 0) { - snprintf(nodename, FDT_NAME_MAX, "pci@%x,%x", slot, func); - } else { - snprintf(nodename, FDT_NAME_MAX, "pci@%x", slot); - } + pci_get_node_name(nodename, FDT_NAME_MAX, dev); offset = fdt_add_subnode(fdt, node_offset, nodename); ret = spapr_populate_pci_child_dt(dev, fdt, offset, phb);