1 /* 2 * ipmi_si_pci.c 3 * 4 * Handling for IPMI devices on the PCI bus. 5 */ 6 #include <linux/module.h> 7 #include <linux/pci.h> 8 #include "ipmi_si.h" 9 10 #define PFX "ipmi_pci: " 11 12 static bool pci_registered; 13 14 static bool si_trypci = true; 15 16 module_param_named(trypci, si_trypci, bool, 0); 17 MODULE_PARM_DESC(trypci, "Setting this to zero will disable the" 18 " default scan of the interfaces identified via pci"); 19 20 #define PCI_ERMC_CLASSCODE 0x0C0700 21 #define PCI_ERMC_CLASSCODE_MASK 0xffffff00 22 #define PCI_ERMC_CLASSCODE_TYPE_MASK 0xff 23 #define PCI_ERMC_CLASSCODE_TYPE_SMIC 0x00 24 #define PCI_ERMC_CLASSCODE_TYPE_KCS 0x01 25 #define PCI_ERMC_CLASSCODE_TYPE_BT 0x02 26 27 #define PCI_HP_VENDOR_ID 0x103C 28 #define PCI_MMC_DEVICE_ID 0x121A 29 #define PCI_MMC_ADDR_CW 0x10 30 31 static void ipmi_pci_cleanup(struct si_sm_io *io) 32 { 33 struct pci_dev *pdev = io->addr_source_data; 34 35 pci_disable_device(pdev); 36 } 37 38 static int ipmi_pci_probe_regspacing(struct si_sm_io *io) 39 { 40 if (io->si_type == SI_KCS) { 41 unsigned char status; 42 int regspacing; 43 44 io->regsize = DEFAULT_REGSIZE; 45 io->regshift = 0; 46 47 /* detect 1, 4, 16byte spacing */ 48 for (regspacing = DEFAULT_REGSPACING; regspacing <= 16;) { 49 io->regspacing = regspacing; 50 if (io->io_setup(io)) { 51 dev_err(io->dev, 52 "Could not setup I/O space\n"); 53 return DEFAULT_REGSPACING; 54 } 55 /* write invalid cmd */ 56 io->outputb(io, 1, 0x10); 57 /* read status back */ 58 status = io->inputb(io, 1); 59 io->io_cleanup(io); 60 if (status) 61 return regspacing; 62 regspacing *= 4; 63 } 64 } 65 return DEFAULT_REGSPACING; 66 } 67 68 static int ipmi_pci_probe(struct pci_dev *pdev, 69 const struct pci_device_id *ent) 70 { 71 int rv; 72 int class_type = pdev->class & PCI_ERMC_CLASSCODE_TYPE_MASK; 73 struct si_sm_io io; 74 75 memset(&io, 0, sizeof(io)); 76 io.addr_source = SI_PCI; 77 dev_info(&pdev->dev, "probing via PCI"); 78 79 switch (class_type) { 80 case PCI_ERMC_CLASSCODE_TYPE_SMIC: 81 io.si_type = SI_SMIC; 82 break; 83 84 case PCI_ERMC_CLASSCODE_TYPE_KCS: 85 io.si_type = SI_KCS; 86 break; 87 88 case PCI_ERMC_CLASSCODE_TYPE_BT: 89 io.si_type = SI_BT; 90 break; 91 92 default: 93 dev_info(&pdev->dev, "Unknown IPMI type: %d\n", class_type); 94 return -ENOMEM; 95 } 96 97 rv = pci_enable_device(pdev); 98 if (rv) { 99 dev_err(&pdev->dev, "couldn't enable PCI device\n"); 100 return rv; 101 } 102 103 io.addr_source_cleanup = ipmi_pci_cleanup; 104 io.addr_source_data = pdev; 105 106 if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) { 107 io.addr_type = IPMI_IO_ADDR_SPACE; 108 io.io_setup = ipmi_si_port_setup; 109 } else { 110 io.addr_type = IPMI_MEM_ADDR_SPACE; 111 io.io_setup = ipmi_si_mem_setup; 112 } 113 io.addr_data = pci_resource_start(pdev, 0); 114 115 io.regspacing = ipmi_pci_probe_regspacing(&io); 116 io.regsize = DEFAULT_REGSIZE; 117 io.regshift = 0; 118 119 io.irq = pdev->irq; 120 if (io.irq) 121 io.irq_setup = ipmi_std_irq_setup; 122 123 io.dev = &pdev->dev; 124 125 dev_info(&pdev->dev, "%pR regsize %d spacing %d irq %d\n", 126 &pdev->resource[0], io.regsize, io.regspacing, io.irq); 127 128 rv = ipmi_si_add_smi(&io); 129 if (rv) 130 pci_disable_device(pdev); 131 132 return rv; 133 } 134 135 static void ipmi_pci_remove(struct pci_dev *pdev) 136 { 137 ipmi_si_remove_by_dev(&pdev->dev); 138 } 139 140 static const struct pci_device_id ipmi_pci_devices[] = { 141 { PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) }, 142 { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) }, 143 { 0, } 144 }; 145 MODULE_DEVICE_TABLE(pci, ipmi_pci_devices); 146 147 static struct pci_driver ipmi_pci_driver = { 148 .name = DEVICE_NAME, 149 .id_table = ipmi_pci_devices, 150 .probe = ipmi_pci_probe, 151 .remove = ipmi_pci_remove, 152 }; 153 154 void ipmi_si_pci_init(void) 155 { 156 if (si_trypci) { 157 int rv = pci_register_driver(&ipmi_pci_driver); 158 if (rv) 159 pr_err(PFX "Unable to register PCI driver: %d\n", rv); 160 else 161 pci_registered = true; 162 } 163 } 164 165 void ipmi_si_pci_shutdown(void) 166 { 167 if (pci_registered) 168 pci_unregister_driver(&ipmi_pci_driver); 169 } 170