pci-me.c (393b148f9d0e70cfcb0096985bb0f0742802929e) | pci-me.c (30e53bb8ffb1f3270ad89196d9799057008d9537) |
---|---|
1/* 2 * 3 * Intel Management Engine Interface (Intel MEI) Linux driver 4 * Copyright (c) 2003-2012, Intel Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. --- 33 unchanged lines hidden (view full) --- 42#include "mei_dev.h" 43#include "hw-me.h" 44#include "client.h" 45 46/* AMT device is a singleton on the platform */ 47static struct pci_dev *mei_pdev; 48 49/* mei_pci_tbl - PCI Device ID Table */ | 1/* 2 * 3 * Intel Management Engine Interface (Intel MEI) Linux driver 4 * Copyright (c) 2003-2012, Intel Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. --- 33 unchanged lines hidden (view full) --- 42#include "mei_dev.h" 43#include "hw-me.h" 44#include "client.h" 45 46/* AMT device is a singleton on the platform */ 47static struct pci_dev *mei_pdev; 48 49/* mei_pci_tbl - PCI Device ID Table */ |
50static DEFINE_PCI_DEVICE_TABLE(mei_pci_tbl) = { | 50static DEFINE_PCI_DEVICE_TABLE(mei_me_pci_tbl) = { |
51 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82946GZ)}, 52 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G35)}, 53 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82Q965)}, 54 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G965)}, 55 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GM965)}, 56 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GME965)}, 57 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82Q35)}, 58 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82G33)}, --- 22 unchanged lines hidden (view full) --- 81 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_3)}, 82 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT)}, 83 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_LP)}, 84 85 /* required last entry */ 86 {0, } 87}; 88 | 51 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82946GZ)}, 52 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G35)}, 53 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82Q965)}, 54 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G965)}, 55 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GM965)}, 56 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GME965)}, 57 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82Q35)}, 58 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82G33)}, --- 22 unchanged lines hidden (view full) --- 81 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_3)}, 82 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT)}, 83 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_LP)}, 84 85 /* required last entry */ 86 {0, } 87}; 88 |
89MODULE_DEVICE_TABLE(pci, mei_pci_tbl); | 89MODULE_DEVICE_TABLE(pci, mei_me_pci_tbl); |
90 91static DEFINE_MUTEX(mei_mutex); 92 93/** 94 * mei_quirk_probe - probe for devices that doesn't valid ME interface | 90 91static DEFINE_MUTEX(mei_mutex); 92 93/** 94 * mei_quirk_probe - probe for devices that doesn't valid ME interface |
95 * | |
96 * @pdev: PCI device structure 97 * @ent: entry into pci_device_table 98 * 99 * returns true if ME Interface is valid, false otherwise 100 */ | 95 * @pdev: PCI device structure 96 * @ent: entry into pci_device_table 97 * 98 * returns true if ME Interface is valid, false otherwise 99 */ |
101static bool mei_quirk_probe(struct pci_dev *pdev, | 100static bool mei_me_quirk_probe(struct pci_dev *pdev, |
102 const struct pci_device_id *ent) 103{ 104 u32 reg; 105 if (ent->device == MEI_DEV_ID_PBG_1) { 106 pci_read_config_dword(pdev, 0x48, ®); 107 /* make sure that bit 9 is up and bit 10 is down */ 108 if ((reg & 0x600) == 0x200) { 109 dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n"); --- 5 unchanged lines hidden (view full) --- 115/** 116 * mei_probe - Device Initialization Routine 117 * 118 * @pdev: PCI device structure 119 * @ent: entry in kcs_pci_tbl 120 * 121 * returns 0 on success, <0 on failure. 122 */ | 101 const struct pci_device_id *ent) 102{ 103 u32 reg; 104 if (ent->device == MEI_DEV_ID_PBG_1) { 105 pci_read_config_dword(pdev, 0x48, ®); 106 /* make sure that bit 9 is up and bit 10 is down */ 107 if ((reg & 0x600) == 0x200) { 108 dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n"); --- 5 unchanged lines hidden (view full) --- 114/** 115 * mei_probe - Device Initialization Routine 116 * 117 * @pdev: PCI device structure 118 * @ent: entry in kcs_pci_tbl 119 * 120 * returns 0 on success, <0 on failure. 121 */ |
123static int mei_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 122static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
124{ 125 struct mei_device *dev; 126 struct mei_me_hw *hw; 127 int err; 128 129 mutex_lock(&mei_mutex); 130 | 123{ 124 struct mei_device *dev; 125 struct mei_me_hw *hw; 126 int err; 127 128 mutex_lock(&mei_mutex); 129 |
131 if (!mei_quirk_probe(pdev, ent)) { | 130 if (!mei_me_quirk_probe(pdev, ent)) { |
132 err = -ENODEV; 133 goto end; 134 } 135 136 if (mei_pdev) { 137 err = -EEXIST; 138 goto end; 139 } --- 40 unchanged lines hidden (view full) --- 180 IRQF_SHARED, KBUILD_MODNAME, dev); 181 182 if (err) { 183 dev_err(&pdev->dev, "request_threaded_irq failure. irq = %d\n", 184 pdev->irq); 185 goto disable_msi; 186 } 187 | 131 err = -ENODEV; 132 goto end; 133 } 134 135 if (mei_pdev) { 136 err = -EEXIST; 137 goto end; 138 } --- 40 unchanged lines hidden (view full) --- 179 IRQF_SHARED, KBUILD_MODNAME, dev); 180 181 if (err) { 182 dev_err(&pdev->dev, "request_threaded_irq failure. irq = %d\n", 183 pdev->irq); 184 goto disable_msi; 185 } 186 |
188 if (mei_hw_init(dev)) { | 187 if (mei_start(dev)) { |
189 dev_err(&pdev->dev, "init hw failure.\n"); 190 err = -ENODEV; 191 goto release_irq; 192 } 193 | 188 dev_err(&pdev->dev, "init hw failure.\n"); 189 err = -ENODEV; 190 goto release_irq; 191 } 192 |
194 err = mei_register(&pdev->dev); | 193 err = mei_register(dev); |
195 if (err) 196 goto release_irq; 197 198 mei_pdev = pdev; 199 pci_set_drvdata(pdev, dev); 200 | 194 if (err) 195 goto release_irq; 196 197 mei_pdev = pdev; 198 pci_set_drvdata(pdev, dev); 199 |
201 | |
202 schedule_delayed_work(&dev->timer_work, HZ); 203 204 mutex_unlock(&mei_mutex); 205 206 pr_debug("initialization successful.\n"); 207 208 return 0; 209 --- 19 unchanged lines hidden (view full) --- 229/** 230 * mei_remove - Device Removal Routine 231 * 232 * @pdev: PCI device structure 233 * 234 * mei_remove is called by the PCI subsystem to alert the driver 235 * that it should release a PCI device. 236 */ | 200 schedule_delayed_work(&dev->timer_work, HZ); 201 202 mutex_unlock(&mei_mutex); 203 204 pr_debug("initialization successful.\n"); 205 206 return 0; 207 --- 19 unchanged lines hidden (view full) --- 227/** 228 * mei_remove - Device Removal Routine 229 * 230 * @pdev: PCI device structure 231 * 232 * mei_remove is called by the PCI subsystem to alert the driver 233 * that it should release a PCI device. 234 */ |
237static void mei_remove(struct pci_dev *pdev) | 235static void mei_me_remove(struct pci_dev *pdev) |
238{ 239 struct mei_device *dev; 240 struct mei_me_hw *hw; 241 242 if (mei_pdev != pdev) 243 return; 244 245 dev = pci_get_drvdata(pdev); 246 if (!dev) 247 return; 248 249 hw = to_me_hw(dev); 250 | 236{ 237 struct mei_device *dev; 238 struct mei_me_hw *hw; 239 240 if (mei_pdev != pdev) 241 return; 242 243 dev = pci_get_drvdata(pdev); 244 if (!dev) 245 return; 246 247 hw = to_me_hw(dev); 248 |
251 mutex_lock(&dev->device_lock); | |
252 | 249 |
253 cancel_delayed_work(&dev->timer_work); | 250 dev_err(&pdev->dev, "stop\n"); 251 mei_stop(dev); |
254 | 252 |
255 mei_wd_stop(dev); 256 | |
257 mei_pdev = NULL; 258 | 253 mei_pdev = NULL; 254 |
259 if (dev->iamthif_cl.state == MEI_FILE_CONNECTED) { 260 dev->iamthif_cl.state = MEI_FILE_DISCONNECTING; 261 mei_cl_disconnect(&dev->iamthif_cl); 262 } 263 if (dev->wd_cl.state == MEI_FILE_CONNECTED) { 264 dev->wd_cl.state = MEI_FILE_DISCONNECTING; 265 mei_cl_disconnect(&dev->wd_cl); 266 } 267 268 /* Unregistering watchdog device */ 269 mei_watchdog_unregister(dev); 270 271 /* remove entry if already in list */ 272 dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n"); 273 274 if (dev->open_handle_count > 0) 275 dev->open_handle_count--; 276 mei_cl_unlink(&dev->wd_cl); 277 278 if (dev->open_handle_count > 0) 279 dev->open_handle_count--; 280 mei_cl_unlink(&dev->iamthif_cl); 281 282 dev->iamthif_current_cb = NULL; 283 dev->me_clients_num = 0; 284 285 mutex_unlock(&dev->device_lock); 286 287 flush_scheduled_work(); 288 | |
289 /* disable interrupts */ 290 mei_disable_interrupts(dev); 291 292 free_irq(pdev->irq, dev); 293 pci_disable_msi(pdev); 294 pci_set_drvdata(pdev, NULL); 295 296 if (hw->mem_addr) 297 pci_iounmap(pdev, hw->mem_addr); 298 | 255 /* disable interrupts */ 256 mei_disable_interrupts(dev); 257 258 free_irq(pdev->irq, dev); 259 pci_disable_msi(pdev); 260 pci_set_drvdata(pdev, NULL); 261 262 if (hw->mem_addr) 263 pci_iounmap(pdev, hw->mem_addr); 264 |
265 mei_deregister(dev); 266 |
|
299 kfree(dev); 300 301 pci_release_regions(pdev); 302 pci_disable_device(pdev); 303 | 267 kfree(dev); 268 269 pci_release_regions(pdev); 270 pci_disable_device(pdev); 271 |
304 mei_deregister(); | |
305 306} 307#ifdef CONFIG_PM | 272 273} 274#ifdef CONFIG_PM |
308static int mei_pci_suspend(struct device *device) | 275static int mei_me_pci_suspend(struct device *device) |
309{ 310 struct pci_dev *pdev = to_pci_dev(device); 311 struct mei_device *dev = pci_get_drvdata(pdev); | 276{ 277 struct pci_dev *pdev = to_pci_dev(device); 278 struct mei_device *dev = pci_get_drvdata(pdev); |
312 int err; | |
313 314 if (!dev) 315 return -ENODEV; | 279 280 if (!dev) 281 return -ENODEV; |
316 mutex_lock(&dev->device_lock); | |
317 | 282 |
318 cancel_delayed_work(&dev->timer_work); | 283 dev_err(&pdev->dev, "suspend\n"); |
319 | 284 |
320 /* Stop watchdog if exists */ 321 err = mei_wd_stop(dev); 322 /* Set new mei state */ 323 if (dev->dev_state == MEI_DEV_ENABLED || 324 dev->dev_state == MEI_DEV_RECOVERING_FROM_RESET) { 325 dev->dev_state = MEI_DEV_POWER_DOWN; 326 mei_reset(dev, 0); 327 } 328 mutex_unlock(&dev->device_lock); | 285 mei_stop(dev); |
329 | 286 |
287 mei_disable_interrupts(dev); 288 |
|
330 free_irq(pdev->irq, dev); 331 pci_disable_msi(pdev); 332 | 289 free_irq(pdev->irq, dev); 290 pci_disable_msi(pdev); 291 |
333 return err; | 292 return 0; |
334} 335 | 293} 294 |
336static int mei_pci_resume(struct device *device) | 295static int mei_me_pci_resume(struct device *device) |
337{ 338 struct pci_dev *pdev = to_pci_dev(device); 339 struct mei_device *dev; 340 int err; 341 342 dev = pci_get_drvdata(pdev); 343 if (!dev) 344 return -ENODEV; --- 23 unchanged lines hidden (view full) --- 368 mei_reset(dev, 1); 369 mutex_unlock(&dev->device_lock); 370 371 /* Start timer if stopped in suspend */ 372 schedule_delayed_work(&dev->timer_work, HZ); 373 374 return err; 375} | 296{ 297 struct pci_dev *pdev = to_pci_dev(device); 298 struct mei_device *dev; 299 int err; 300 301 dev = pci_get_drvdata(pdev); 302 if (!dev) 303 return -ENODEV; --- 23 unchanged lines hidden (view full) --- 327 mei_reset(dev, 1); 328 mutex_unlock(&dev->device_lock); 329 330 /* Start timer if stopped in suspend */ 331 schedule_delayed_work(&dev->timer_work, HZ); 332 333 return err; 334} |
376static SIMPLE_DEV_PM_OPS(mei_pm_ops, mei_pci_suspend, mei_pci_resume); 377#define MEI_PM_OPS (&mei_pm_ops) | 335static SIMPLE_DEV_PM_OPS(mei_me_pm_ops, mei_me_pci_suspend, mei_me_pci_resume); 336#define MEI_ME_PM_OPS (&mei_me_pm_ops) |
378#else | 337#else |
379#define MEI_PM_OPS NULL | 338#define MEI_ME_PM_OPS NULL |
380#endif /* CONFIG_PM */ 381/* 382 * PCI driver structure 383 */ | 339#endif /* CONFIG_PM */ 340/* 341 * PCI driver structure 342 */ |
384static struct pci_driver mei_driver = { | 343static struct pci_driver mei_me_driver = { |
385 .name = KBUILD_MODNAME, | 344 .name = KBUILD_MODNAME, |
386 .id_table = mei_pci_tbl, 387 .probe = mei_probe, 388 .remove = mei_remove, 389 .shutdown = mei_remove, 390 .driver.pm = MEI_PM_OPS, | 345 .id_table = mei_me_pci_tbl, 346 .probe = mei_me_probe, 347 .remove = mei_me_remove, 348 .shutdown = mei_me_remove, 349 .driver.pm = MEI_ME_PM_OPS, |
391}; 392 | 350}; 351 |
393module_pci_driver(mei_driver); | 352module_pci_driver(mei_me_driver); |
394 395MODULE_AUTHOR("Intel Corporation"); 396MODULE_DESCRIPTION("Intel(R) Management Engine Interface"); 397MODULE_LICENSE("GPL v2"); | 353 354MODULE_AUTHOR("Intel Corporation"); 355MODULE_DESCRIPTION("Intel(R) Management Engine Interface"); 356MODULE_LICENSE("GPL v2"); |