Version:  2.0.40 2.2.26 2.4.37 2.6.39 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15

Linux/drivers/misc/mei/pci-me.c

  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.
  9  *
 10  * This program is distributed in the hope it will be useful, but WITHOUT
 11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 13  * more details.
 14  *
 15  */
 16 #include <linux/module.h>
 17 #include <linux/moduleparam.h>
 18 #include <linux/kernel.h>
 19 #include <linux/device.h>
 20 #include <linux/fs.h>
 21 #include <linux/errno.h>
 22 #include <linux/types.h>
 23 #include <linux/fcntl.h>
 24 #include <linux/aio.h>
 25 #include <linux/pci.h>
 26 #include <linux/poll.h>
 27 #include <linux/ioctl.h>
 28 #include <linux/cdev.h>
 29 #include <linux/sched.h>
 30 #include <linux/uuid.h>
 31 #include <linux/compat.h>
 32 #include <linux/jiffies.h>
 33 #include <linux/interrupt.h>
 34 #include <linux/miscdevice.h>
 35 
 36 #include <linux/mei.h>
 37 
 38 #include "mei_dev.h"
 39 #include "client.h"
 40 #include "hw-me-regs.h"
 41 #include "hw-me.h"
 42 
 43 /* mei_pci_tbl - PCI Device ID Table */
 44 static const struct pci_device_id mei_me_pci_tbl[] = {
 45         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82946GZ)},
 46         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G35)},
 47         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82Q965)},
 48         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G965)},
 49         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GM965)},
 50         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GME965)},
 51         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82Q35)},
 52         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82G33)},
 53         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82Q33)},
 54         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82X38)},
 55         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_3200)},
 56         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_6)},
 57         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_7)},
 58         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_8)},
 59         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_9)},
 60         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_10)},
 61         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_1)},
 62         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_2)},
 63         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_3)},
 64         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_4)},
 65         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_1)},
 66         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_2)},
 67         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_3)},
 68         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_4)},
 69         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_IBXPK_1)},
 70         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_IBXPK_2)},
 71         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_CPT_1)},
 72         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PBG_1)},
 73         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_1)},
 74         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_2)},
 75         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_3)},
 76         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_H)},
 77         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_W)},
 78         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_LP)},
 79         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_HR)},
 80         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_WPT_LP)},
 81 
 82         /* required last entry */
 83         {0, }
 84 };
 85 
 86 MODULE_DEVICE_TABLE(pci, mei_me_pci_tbl);
 87 
 88 /**
 89  * mei_quirk_probe - probe for devices that doesn't valid ME interface
 90  *
 91  * @pdev: PCI device structure
 92  * @ent: entry into pci_device_table
 93  *
 94  * returns true if ME Interface is valid, false otherwise
 95  */
 96 static bool mei_me_quirk_probe(struct pci_dev *pdev,
 97                                 const struct pci_device_id *ent)
 98 {
 99         u32 reg;
100         /* Cougar Point || Patsburg */
101         if (ent->device == MEI_DEV_ID_CPT_1 ||
102             ent->device == MEI_DEV_ID_PBG_1) {
103                 pci_read_config_dword(pdev, PCI_CFG_HFS_2, &reg);
104                 /* make sure that bit 9 (NM) is up and bit 10 (DM) is down */
105                 if ((reg & 0x600) == 0x200)
106                         goto no_mei;
107         }
108 
109         /* Lynx Point */
110         if (ent->device == MEI_DEV_ID_LPT_H  ||
111             ent->device == MEI_DEV_ID_LPT_W  ||
112             ent->device == MEI_DEV_ID_LPT_HR) {
113                 /* Read ME FW Status check for SPS Firmware */
114                 pci_read_config_dword(pdev, PCI_CFG_HFS_1, &reg);
115                 /* if bits [19:16] = 15, running SPS Firmware */
116                 if ((reg & 0xf0000) == 0xf0000)
117                         goto no_mei;
118         }
119 
120         return true;
121 
122 no_mei:
123         dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n");
124         return false;
125 }
126 /**
127  * mei_probe - Device Initialization Routine
128  *
129  * @pdev: PCI device structure
130  * @ent: entry in kcs_pci_tbl
131  *
132  * returns 0 on success, <0 on failure.
133  */
134 static int mei_me_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
135 {
136         struct mei_device *dev;
137         struct mei_me_hw *hw;
138         int err;
139 
140 
141         if (!mei_me_quirk_probe(pdev, ent)) {
142                 err = -ENODEV;
143                 goto end;
144         }
145 
146         /* enable pci dev */
147         err = pci_enable_device(pdev);
148         if (err) {
149                 dev_err(&pdev->dev, "failed to enable pci device.\n");
150                 goto end;
151         }
152         /* set PCI host mastering  */
153         pci_set_master(pdev);
154         /* pci request regions for mei driver */
155         err = pci_request_regions(pdev, KBUILD_MODNAME);
156         if (err) {
157                 dev_err(&pdev->dev, "failed to get pci regions.\n");
158                 goto disable_device;
159         }
160 
161         if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) ||
162             dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) {
163 
164                 err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
165                 if (err)
166                         err = dma_set_coherent_mask(&pdev->dev,
167                                                     DMA_BIT_MASK(32));
168         }
169         if (err) {
170                 dev_err(&pdev->dev, "No usable DMA configuration, aborting\n");
171                 goto release_regions;
172         }
173 
174 
175         /* allocates and initializes the mei dev structure */
176         dev = mei_me_dev_init(pdev);
177         if (!dev) {
178                 err = -ENOMEM;
179                 goto release_regions;
180         }
181         hw = to_me_hw(dev);
182         /* mapping  IO device memory */
183         hw->mem_addr = pci_iomap(pdev, 0, 0);
184         if (!hw->mem_addr) {
185                 dev_err(&pdev->dev, "mapping I/O device memory failure.\n");
186                 err = -ENOMEM;
187                 goto free_device;
188         }
189         pci_enable_msi(pdev);
190 
191          /* request and enable interrupt */
192         if (pci_dev_msi_enabled(pdev))
193                 err = request_threaded_irq(pdev->irq,
194                         NULL,
195                         mei_me_irq_thread_handler,
196                         IRQF_ONESHOT, KBUILD_MODNAME, dev);
197         else
198                 err = request_threaded_irq(pdev->irq,
199                         mei_me_irq_quick_handler,
200                         mei_me_irq_thread_handler,
201                         IRQF_SHARED, KBUILD_MODNAME, dev);
202 
203         if (err) {
204                 dev_err(&pdev->dev, "request_threaded_irq failure. irq = %d\n",
205                        pdev->irq);
206                 goto disable_msi;
207         }
208 
209         if (mei_start(dev)) {
210                 dev_err(&pdev->dev, "init hw failure.\n");
211                 err = -ENODEV;
212                 goto release_irq;
213         }
214 
215         err = mei_register(dev);
216         if (err)
217                 goto release_irq;
218 
219         pci_set_drvdata(pdev, dev);
220 
221         schedule_delayed_work(&dev->timer_work, HZ);
222 
223         dev_dbg(&pdev->dev, "initialization successful.\n");
224 
225         return 0;
226 
227 release_irq:
228         mei_cancel_work(dev);
229         mei_disable_interrupts(dev);
230         free_irq(pdev->irq, dev);
231 disable_msi:
232         pci_disable_msi(pdev);
233         pci_iounmap(pdev, hw->mem_addr);
234 free_device:
235         kfree(dev);
236 release_regions:
237         pci_release_regions(pdev);
238 disable_device:
239         pci_disable_device(pdev);
240 end:
241         dev_err(&pdev->dev, "initialization failed.\n");
242         return err;
243 }
244 
245 /**
246  * mei_remove - Device Removal Routine
247  *
248  * @pdev: PCI device structure
249  *
250  * mei_remove is called by the PCI subsystem to alert the driver
251  * that it should release a PCI device.
252  */
253 static void mei_me_remove(struct pci_dev *pdev)
254 {
255         struct mei_device *dev;
256         struct mei_me_hw *hw;
257 
258         dev = pci_get_drvdata(pdev);
259         if (!dev)
260                 return;
261 
262         hw = to_me_hw(dev);
263 
264 
265         dev_dbg(&pdev->dev, "stop\n");
266         mei_stop(dev);
267 
268         /* disable interrupts */
269         mei_disable_interrupts(dev);
270 
271         free_irq(pdev->irq, dev);
272         pci_disable_msi(pdev);
273 
274         if (hw->mem_addr)
275                 pci_iounmap(pdev, hw->mem_addr);
276 
277         mei_deregister(dev);
278 
279         kfree(dev);
280 
281         pci_release_regions(pdev);
282         pci_disable_device(pdev);
283 
284 
285 }
286 #ifdef CONFIG_PM_SLEEP
287 static int mei_me_pci_suspend(struct device *device)
288 {
289         struct pci_dev *pdev = to_pci_dev(device);
290         struct mei_device *dev = pci_get_drvdata(pdev);
291 
292         if (!dev)
293                 return -ENODEV;
294 
295         dev_dbg(&pdev->dev, "suspend\n");
296 
297         mei_stop(dev);
298 
299         mei_disable_interrupts(dev);
300 
301         free_irq(pdev->irq, dev);
302         pci_disable_msi(pdev);
303 
304         return 0;
305 }
306 
307 static int mei_me_pci_resume(struct device *device)
308 {
309         struct pci_dev *pdev = to_pci_dev(device);
310         struct mei_device *dev;
311         int err;
312 
313         dev = pci_get_drvdata(pdev);
314         if (!dev)
315                 return -ENODEV;
316 
317         pci_enable_msi(pdev);
318 
319         /* request and enable interrupt */
320         if (pci_dev_msi_enabled(pdev))
321                 err = request_threaded_irq(pdev->irq,
322                         NULL,
323                         mei_me_irq_thread_handler,
324                         IRQF_ONESHOT, KBUILD_MODNAME, dev);
325         else
326                 err = request_threaded_irq(pdev->irq,
327                         mei_me_irq_quick_handler,
328                         mei_me_irq_thread_handler,
329                         IRQF_SHARED, KBUILD_MODNAME, dev);
330 
331         if (err) {
332                 dev_err(&pdev->dev, "request_threaded_irq failed: irq = %d.\n",
333                                 pdev->irq);
334                 return err;
335         }
336 
337         err = mei_restart(dev);
338         if (err)
339                 return err;
340 
341         /* Start timer if stopped in suspend */
342         schedule_delayed_work(&dev->timer_work, HZ);
343 
344         return 0;
345 }
346 
347 static SIMPLE_DEV_PM_OPS(mei_me_pm_ops, mei_me_pci_suspend, mei_me_pci_resume);
348 #define MEI_ME_PM_OPS   (&mei_me_pm_ops)
349 #else
350 #define MEI_ME_PM_OPS   NULL
351 #endif /* CONFIG_PM_SLEEP */
352 /*
353  *  PCI driver structure
354  */
355 static struct pci_driver mei_me_driver = {
356         .name = KBUILD_MODNAME,
357         .id_table = mei_me_pci_tbl,
358         .probe = mei_me_probe,
359         .remove = mei_me_remove,
360         .shutdown = mei_me_remove,
361         .driver.pm = MEI_ME_PM_OPS,
362 };
363 
364 module_pci_driver(mei_me_driver);
365 
366 MODULE_AUTHOR("Intel Corporation");
367 MODULE_DESCRIPTION("Intel(R) Management Engine Interface");
368 MODULE_LICENSE("GPL v2");
369 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us