2 * Part of Intel(R) Manageability Engine Interface Linux driver
4 * Copyright (c) 2003 - 2008 Intel Corp.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer,
12 * without modification.
13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
14 * substantially similar to the "NO WARRANTY" disclaimer below
15 * ("Disclaimer") and any redistribution must be conditioned upon
16 * including a substantially similar Disclaimer requirement for further
17 * binary redistribution.
18 * 3. Neither the names of the above-listed copyright holders nor the names
19 * of any contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
22 * Alternatively, this software may be distributed under the terms of the
23 * GNU General Public License ("GPL") version 2 as published by the Free
24 * Software Foundation.
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
30 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
35 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
36 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGES.
42 #include <linux/module.h>
43 #include <linux/moduleparam.h>
44 #include <linux/kernel.h>
45 #include <linux/slab.h>
47 #include <linux/errno.h>
48 #include <linux/types.h>
49 #include <linux/fcntl.h>
50 #include <linux/aio.h>
51 #include <linux/pci.h>
52 #include <linux/reboot.h>
53 #include <linux/poll.h>
54 #include <linux/init.h>
55 #include <linux/kdev_t.h>
56 #include <linux/ioctl.h>
57 #include <linux/cdev.h>
58 #include <linux/device.h>
59 #include <linux/unistd.h>
60 #include <linux/kthread.h>
63 #include "heci_interface.h"
64 #include "heci_version.h"
67 #define HECI_READ_TIMEOUT 45
69 #define HECI_DRIVER_NAME "heci"
74 char heci_driver_name
[] = HECI_DRIVER_NAME
;
75 char heci_driver_string
[] = "Intel(R) Management Engine Interface";
76 char heci_driver_version
[] = HECI_DRIVER_VERSION
;
77 char heci_copyright
[] = "Copyright (c) 2003 - 2008 Intel Corporation.";
85 MODULE_PARM_DESC(heci_debug
, "Debug enabled or not");
86 module_param(heci_debug
, int, 0644);
89 #define HECI_DEV_NAME "heci"
91 /* heci char device for registration */
92 static struct cdev heci_cdev
;
94 /* major number for device */
95 static int heci_major
;
96 /* The device pointer */
97 static struct pci_dev
*heci_device
;
99 struct class *heci_class
;
102 /* heci_pci_tbl - PCI Device ID Table */
103 static struct pci_device_id heci_pci_tbl
[] = {
104 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_82946GZ
)},
105 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_82G35
)},
106 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_82Q965
)},
107 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_82G965
)},
108 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_82GM965
)},
109 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_82GME965
)},
110 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9_82Q35
)},
111 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9_82G33
)},
112 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9_82Q33
)},
113 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9_82X38
)},
114 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9_3200
)},
115 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9_6
)},
116 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9_7
)},
117 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9_8
)},
118 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9_9
)},
119 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9_10
)},
120 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9M_1
)},
121 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9M_2
)},
122 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9M_3
)},
123 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9M_4
)},
124 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH10_1
)},
125 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH10_2
)},
126 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH10_3
)},
127 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH10_4
)},
128 /* required last entry */
132 MODULE_DEVICE_TABLE(pci
, heci_pci_tbl
);
135 * Local Function Prototypes
137 static int __init
heci_init_module(void);
138 static void __exit
heci_exit_module(void);
139 static int __devinit
heci_probe(struct pci_dev
*pdev
,
140 const struct pci_device_id
*ent
);
141 static void __devexit
heci_remove(struct pci_dev
*pdev
);
142 static int heci_open(struct inode
*inode
, struct file
*file
);
143 static int heci_release(struct inode
*inode
, struct file
*file
);
144 static ssize_t
heci_read(struct file
*file
, char __user
*ubuf
,
145 size_t length
, loff_t
*offset
);
146 static int heci_ioctl(struct inode
*inode
, struct file
*file
,
147 unsigned int cmd
, unsigned long data
);
148 static ssize_t
heci_write(struct file
*file
, const char __user
*ubuf
,
149 size_t length
, loff_t
*offset
);
150 static unsigned int heci_poll(struct file
*file
, poll_table
*wait
);
151 static struct heci_cb_private
*find_read_list_entry(
152 struct iamt_heci_device
*dev
,
153 struct heci_file_private
*file_ext
);
155 static int heci_suspend(struct pci_dev
*pdev
, pm_message_t state
);
156 static int heci_resume(struct pci_dev
*pdev
);
157 static __u16 g_sus_wd_timeout
;
159 #define heci_suspend NULL
160 #define heci_resume NULL
163 * PCI driver structure
165 static struct pci_driver heci_driver
= {
166 .name
= heci_driver_name
,
167 .id_table
= heci_pci_tbl
,
169 .remove
= __devexit_p(heci_remove
),
170 .shutdown
= __devexit_p(heci_remove
),
171 .suspend
= heci_suspend
,
172 .resume
= heci_resume
176 * file operations structure will be use heci char device.
178 static const struct file_operations heci_fops
= {
179 .owner
= THIS_MODULE
,
183 .release
= heci_release
,
189 * heci_registration_cdev - set up the cdev structure for heci device.
191 * @dev: char device struct
192 * @hminor: minor number for registration char device
193 * @fops: file operations structure
195 * returns 0 on success, <0 on failure.
197 static int heci_registration_cdev(struct cdev
*dev
, int hminor
,
198 const struct file_operations
*fops
)
200 int ret
, devno
= MKDEV(heci_major
, hminor
);
202 cdev_init(dev
, fops
);
203 dev
->owner
= THIS_MODULE
;
204 ret
= cdev_add(dev
, devno
, 1);
205 /* Fail gracefully if need be */
207 printk(KERN_ERR
"heci: Error %d registering heci device %d\n",
213 /* Display the version of heci driver. */
214 static ssize_t
version_show(struct class *dev
, char *buf
)
216 return sprintf(buf
, "%s %s.\n",
217 heci_driver_string
, heci_driver_version
);
220 static CLASS_ATTR(version
, S_IRUGO
, version_show
, NULL
);
223 * heci_register_cdev - registers heci char device
225 * returns 0 on success, <0 on failure.
227 static int heci_register_cdev(void)
232 /* registration of char devices */
233 ret
= alloc_chrdev_region(&dev
, HECI_MINORS_BASE
, HECI_MINORS_COUNT
,
236 printk(KERN_ERR
"heci: Error allocating char device region.\n");
240 heci_major
= MAJOR(dev
);
242 ret
= heci_registration_cdev(&heci_cdev
, HECI_MINOR_NUMBER
,
245 unregister_chrdev_region(MKDEV(heci_major
, HECI_MINORS_BASE
),
252 * heci_unregister_cdev - unregisters heci char device
254 static void heci_unregister_cdev(void)
256 cdev_del(&heci_cdev
);
257 unregister_chrdev_region(MKDEV(heci_major
, HECI_MINORS_BASE
),
261 #ifndef HECI_DEVICE_CREATE
262 #define HECI_DEVICE_CREATE device_create
265 * heci_sysfs_device_create - adds device entry to sysfs
267 * returns 0 on success, <0 on failure.
269 static int heci_sysfs_device_create(void)
275 class = class_create(THIS_MODULE
, HECI_DRIVER_NAME
);
277 err
= PTR_ERR(class);
278 printk(KERN_ERR
"heci: Error creating heci class.\n");
282 err
= class_create_file(class, &class_attr_version
);
284 class_destroy(class);
285 printk(KERN_ERR
"heci: Error creating heci class file.\n");
289 tmphdev
= HECI_DEVICE_CREATE(class, NULL
, heci_cdev
.dev
, NULL
,
291 if (IS_ERR(tmphdev
)) {
292 err
= PTR_ERR(tmphdev
);
293 class_remove_file(class, &class_attr_version
);
294 class_destroy(class);
304 * heci_sysfs_device_remove - unregisters the device entry on sysfs
306 static void heci_sysfs_device_remove(void)
308 if ((heci_class
== NULL
) || (IS_ERR(heci_class
)))
311 device_destroy(heci_class
, heci_cdev
.dev
);
312 class_remove_file(heci_class
, &class_attr_version
);
313 class_destroy(heci_class
);
317 * heci_init_module - Driver Registration Routine
319 * heci_init_module is the first routine called when the driver is
320 * loaded. All it does is register with the PCI subsystem.
322 * returns 0 on success, <0 on failure.
324 static int __init
heci_init_module(void)
328 printk(KERN_INFO
"heci: %s - version %s\n", heci_driver_string
,
329 heci_driver_version
);
330 printk(KERN_INFO
"heci: %s\n", heci_copyright
);
332 /* init pci module */
333 ret
= pci_register_driver(&heci_driver
);
335 printk(KERN_ERR
"heci: Error registering driver.\n");
339 ret
= heci_register_cdev();
343 ret
= heci_sysfs_device_create();
345 goto unregister_cdev
;
350 heci_unregister_cdev();
352 pci_unregister_driver(&heci_driver
);
357 module_init(heci_init_module
);
361 * heci_exit_module - Driver Exit Cleanup Routine
363 * heci_exit_module is called just before the driver is removed
366 static void __exit
heci_exit_module(void)
368 pci_unregister_driver(&heci_driver
);
369 heci_sysfs_device_remove();
370 heci_unregister_cdev();
373 module_exit(heci_exit_module
);
377 * heci_probe - Device Initialization Routine
379 * @pdev: PCI device information struct
380 * @ent: entry in kcs_pci_tbl
382 * returns 0 on success, <0 on failure.
384 static int __devinit
heci_probe(struct pci_dev
*pdev
,
385 const struct pci_device_id
*ent
)
387 struct iamt_heci_device
*dev
= NULL
;
395 err
= pci_enable_device(pdev
);
397 printk(KERN_ERR
"heci: Failed to enable pci device.\n");
400 /* set PCI host mastering */
401 pci_set_master(pdev
);
402 /* pci request regions for heci driver */
403 err
= pci_request_regions(pdev
, heci_driver_name
);
405 printk(KERN_ERR
"heci: Failed to get pci regions.\n");
408 /* allocates and initializes the heci dev structure */
409 dev
= init_heci_device(pdev
);
412 goto release_regions
;
414 /* mapping IO device memory */
415 for (i
= 0; i
<= 5; i
++) {
416 if (pci_resource_len(pdev
, i
) == 0)
418 if (pci_resource_flags(pdev
, i
) & IORESOURCE_IO
) {
419 printk(KERN_ERR
"heci: heci has IO ports.\n");
421 } else if (pci_resource_flags(pdev
, i
) & IORESOURCE_MEM
) {
424 "heci: Too many mem addresses.\n");
427 dev
->mem_base
= pci_resource_start(pdev
, i
);
428 dev
->mem_length
= pci_resource_len(pdev
, i
);
431 if (!dev
->mem_base
) {
432 printk(KERN_ERR
"heci: No address to use.\n");
436 dev
->mem_addr
= ioremap_nocache(dev
->mem_base
,
438 if (!dev
->mem_addr
) {
439 printk(KERN_ERR
"heci: Remap IO device memory failure.\n");
443 /* request and enable interrupt */
444 err
= request_irq(pdev
->irq
, heci_isr_interrupt
, IRQF_SHARED
,
445 heci_driver_name
, dev
);
447 printk(KERN_ERR
"heci: Request_irq failure. irq = %d \n",
452 if (heci_hw_init(dev
)) {
453 printk(KERN_ERR
"heci: Init hw failure.\n");
457 init_timer(&dev
->wd_timer
);
459 heci_initialize_clients(dev
);
460 if (dev
->heci_state
!= HECI_ENABLED
) {
465 spin_lock_bh(&dev
->device_lock
);
467 pci_set_drvdata(pdev
, dev
);
468 spin_unlock_bh(&dev
->device_lock
);
471 mod_timer(&dev
->wd_timer
, jiffies
);
474 g_sus_wd_timeout
= 0;
476 printk(KERN_INFO
"heci driver initialization successful.\n");
480 /* disable interrupts */
481 dev
->host_hw_state
= read_heci_register(dev
, H_CSR
);
482 heci_csr_disable_interrupts(dev
);
484 del_timer_sync(&dev
->wd_timer
);
486 flush_scheduled_work();
489 free_irq(pdev
->irq
, dev
);
492 iounmap(dev
->mem_addr
);
496 pci_release_regions(pdev
);
498 pci_disable_device(pdev
);
500 printk(KERN_ERR
"heci driver initialization failed.\n");
505 * heci_remove - Device Removal Routine
507 * @pdev: PCI device information struct
509 * heci_remove is called by the PCI subsystem to alert the driver
510 * that it should release a PCI device.
512 static void __devexit
heci_remove(struct pci_dev
*pdev
)
514 struct iamt_heci_device
*dev
= pci_get_drvdata(pdev
);
516 if (heci_device
!= pdev
)
522 spin_lock_bh(&dev
->device_lock
);
523 if (heci_device
!= pdev
) {
524 spin_unlock_bh(&dev
->device_lock
);
528 if (dev
->reinit_tsk
!= NULL
) {
529 kthread_stop(dev
->reinit_tsk
);
530 dev
->reinit_tsk
= NULL
;
533 del_timer_sync(&dev
->wd_timer
);
534 if (dev
->wd_file_ext
.state
== HECI_FILE_CONNECTED
535 && dev
->wd_timeout
) {
537 dev
->wd_due_counter
= 0;
538 memcpy(dev
->wd_data
, heci_stop_wd_params
, HECI_WD_PARAMS_SIZE
);
540 if (dev
->host_buffer_is_empty
&&
541 flow_ctrl_creds(dev
, &dev
->wd_file_ext
)) {
542 dev
->host_buffer_is_empty
= 0;
544 if (!heci_send_wd(dev
))
545 DBG("send stop WD failed\n");
547 flow_ctrl_reduce(dev
, &dev
->wd_file_ext
);
554 spin_unlock_bh(&dev
->device_lock
);
556 wait_event_interruptible_timeout(dev
->wait_stop_wd
,
557 (dev
->wd_stoped
), 10 * HZ
);
558 spin_lock_bh(&dev
->device_lock
);
560 DBG("stop wd failed to complete.\n");
562 DBG("stop wd complete.\n");
567 spin_unlock_bh(&dev
->device_lock
);
569 if (dev
->iamthif_file_ext
.state
== HECI_FILE_CONNECTED
) {
570 dev
->iamthif_file_ext
.state
= HECI_FILE_DISCONNECTING
;
571 heci_disconnect_host_client(dev
,
572 &dev
->iamthif_file_ext
);
574 if (dev
->wd_file_ext
.state
== HECI_FILE_CONNECTED
) {
575 dev
->wd_file_ext
.state
= HECI_FILE_DISCONNECTING
;
576 heci_disconnect_host_client(dev
,
580 spin_lock_bh(&dev
->device_lock
);
582 /* remove entry if already in list */
583 DBG("list del iamthif and wd file list.\n");
584 heci_remove_client_from_file_list(dev
, dev
->wd_file_ext
.
586 heci_remove_client_from_file_list(dev
,
587 dev
->iamthif_file_ext
.host_client_id
);
589 dev
->iamthif_current_cb
= NULL
;
590 dev
->iamthif_file_ext
.file
= NULL
;
591 dev
->num_heci_me_clients
= 0;
593 spin_unlock_bh(&dev
->device_lock
);
595 flush_scheduled_work();
597 /* disable interrupts */
598 heci_csr_disable_interrupts(dev
);
600 free_irq(pdev
->irq
, dev
);
601 pci_set_drvdata(pdev
, NULL
);
604 iounmap(dev
->mem_addr
);
608 pci_release_regions(pdev
);
609 pci_disable_device(pdev
);
613 * heci_clear_list - remove all callbacks associated with file
616 * @file: file information struct
617 * @heci_cb_list: callbacks list
619 * heci_clear_list is called to clear resources associated with file
620 * when application calls close function or Ctrl-C was pressed
622 * returns 1 if callback removed from the list, 0 otherwise
624 static int heci_clear_list(struct iamt_heci_device
*dev
,
625 struct file
*file
, struct list_head
*heci_cb_list
)
627 struct heci_cb_private
*priv_cb_pos
= NULL
;
628 struct heci_cb_private
*priv_cb_next
= NULL
;
629 struct file
*file_temp
;
632 /* list all list member */
633 list_for_each_entry_safe(priv_cb_pos
, priv_cb_next
,
634 heci_cb_list
, cb_list
) {
635 file_temp
= (struct file
*)priv_cb_pos
->file_object
;
636 /* check if list member associated with a file */
637 if (file_temp
== file
) {
638 /* remove member from the list */
639 list_del(&priv_cb_pos
->cb_list
);
640 /* check if cb equal to current iamthif cb */
641 if (dev
->iamthif_current_cb
== priv_cb_pos
) {
642 dev
->iamthif_current_cb
= NULL
;
643 /* send flow control to iamthif client */
644 heci_send_flow_control(dev
,
645 &dev
->iamthif_file_ext
);
647 /* free all allocated buffers */
648 heci_free_cb_private(priv_cb_pos
);
656 * heci_clear_lists - remove all callbacks associated with file
658 * @dev: device information struct
659 * @file: file information struct
661 * heci_clear_lists is called to clear resources associated with file
662 * when application calls close function or Ctrl-C was pressed
664 * returns 1 if callback removed from the list, 0 otherwise
666 static int heci_clear_lists(struct iamt_heci_device
*dev
, struct file
*file
)
670 /* remove callbacks associated with a file */
671 heci_clear_list(dev
, file
, &dev
->pthi_cmd_list
.heci_cb
.cb_list
);
672 if (heci_clear_list(dev
, file
,
673 &dev
->pthi_read_complete_list
.heci_cb
.cb_list
))
676 heci_clear_list(dev
, file
, &dev
->ctrl_rd_list
.heci_cb
.cb_list
);
678 if (heci_clear_list(dev
, file
, &dev
->ctrl_wr_list
.heci_cb
.cb_list
))
681 if (heci_clear_list(dev
, file
,
682 &dev
->write_waiting_list
.heci_cb
.cb_list
))
685 if (heci_clear_list(dev
, file
, &dev
->write_list
.heci_cb
.cb_list
))
688 /* check if iamthif_current_cb not NULL */
689 if (dev
->iamthif_current_cb
&& (!rets
)) {
690 /* check file and iamthif current cb association */
691 if (dev
->iamthif_current_cb
->file_object
== file
) {
693 heci_free_cb_private(dev
->iamthif_current_cb
);
694 dev
->iamthif_current_cb
= NULL
;
702 * heci_open - the open function
704 * @inode: pointer to inode structure
705 * @file: pointer to file structure
707 * returns 0 on success, <0 on error
709 static int heci_open(struct inode
*inode
, struct file
*file
)
711 struct heci_file_private
*file_ext
;
712 int if_num
= iminor(inode
);
713 struct iamt_heci_device
*dev
;
718 dev
= pci_get_drvdata(heci_device
);
719 if ((if_num
!= HECI_MINOR_NUMBER
) || (!dev
))
722 file_ext
= heci_alloc_file_private(file
);
723 if (file_ext
== NULL
)
726 spin_lock_bh(&dev
->device_lock
);
727 if (dev
->heci_state
!= HECI_ENABLED
) {
728 spin_unlock_bh(&dev
->device_lock
);
732 if (dev
->open_handle_count
>= HECI_MAX_OPEN_HANDLE_COUNT
) {
733 spin_unlock_bh(&dev
->device_lock
);
737 dev
->open_handle_count
++;
738 list_add_tail(&file_ext
->link
, &dev
->file_list
);
739 while ((dev
->heci_host_clients
[dev
->current_host_client_id
/ 8]
740 & (1 << (dev
->current_host_client_id
% 8))) != 0) {
742 dev
->current_host_client_id
++; /* allow overflow */
743 DBG("current_host_client_id = %d\n",
744 dev
->current_host_client_id
);
745 DBG("dev->open_handle_count = %lu\n",
746 dev
->open_handle_count
);
748 DBG("current_host_client_id = %d\n", dev
->current_host_client_id
);
749 file_ext
->host_client_id
= dev
->current_host_client_id
;
750 dev
->heci_host_clients
[file_ext
->host_client_id
/ 8] |=
751 (1 << (file_ext
->host_client_id
% 8));
752 spin_unlock_bh(&dev
->device_lock
);
753 spin_lock(&file_ext
->file_lock
);
754 file_ext
->state
= HECI_FILE_INITIALIZING
;
755 file_ext
->sm_state
= 0;
757 file
->private_data
= file_ext
;
758 spin_unlock(&file_ext
->file_lock
);
764 * heci_release - the release function
766 * @inode: pointer to inode structure
767 * @file: pointer to file structure
769 * returns 0 on success, <0 on error
771 static int heci_release(struct inode
*inode
, struct file
*file
)
774 int if_num
= iminor(inode
);
775 struct heci_file_private
*file_ext
= file
->private_data
;
776 struct heci_cb_private
*priv_cb
= NULL
;
777 struct iamt_heci_device
*dev
;
782 dev
= pci_get_drvdata(heci_device
);
783 if ((if_num
!= HECI_MINOR_NUMBER
) || (!dev
) || (!file_ext
))
786 if (file_ext
!= &dev
->iamthif_file_ext
) {
787 spin_lock(&file_ext
->file_lock
);
788 if (file_ext
->state
== HECI_FILE_CONNECTED
) {
789 file_ext
->state
= HECI_FILE_DISCONNECTING
;
790 spin_unlock(&file_ext
->file_lock
);
791 DBG("disconnecting client host client = %d, "
793 file_ext
->host_client_id
,
794 file_ext
->me_client_id
);
795 rets
= heci_disconnect_host_client(dev
, file_ext
);
796 spin_lock(&file_ext
->file_lock
);
798 spin_lock_bh(&dev
->device_lock
);
799 heci_flush_queues(dev
, file_ext
);
800 DBG("remove client host client = %d, ME client = %d\n",
801 file_ext
->host_client_id
,
802 file_ext
->me_client_id
);
804 if (dev
->open_handle_count
> 0) {
805 dev
->heci_host_clients
[file_ext
->host_client_id
/ 8] &=
806 ~(1 << (file_ext
->host_client_id
% 8));
807 dev
->open_handle_count
--;
809 heci_remove_client_from_file_list(dev
,
810 file_ext
->host_client_id
);
813 if (file_ext
->read_cb
!= NULL
) {
814 priv_cb
= find_read_list_entry(dev
, file_ext
);
815 /* Remove entry from read list */
817 list_del(&priv_cb
->cb_list
);
819 priv_cb
= file_ext
->read_cb
;
820 file_ext
->read_cb
= NULL
;
823 spin_unlock_bh(&dev
->device_lock
);
824 file
->private_data
= NULL
;
825 spin_unlock(&file_ext
->file_lock
);
828 heci_free_cb_private(priv_cb
);
832 spin_lock_bh(&dev
->device_lock
);
834 if (dev
->open_handle_count
> 0)
835 dev
->open_handle_count
--;
837 if (dev
->iamthif_file_object
== file
838 && dev
->iamthif_state
!= HECI_IAMTHIF_IDLE
) {
839 DBG("pthi canceled iamthif state %d\n",
841 dev
->iamthif_canceled
= 1;
842 if (dev
->iamthif_state
== HECI_IAMTHIF_READ_COMPLETE
) {
843 DBG("run next pthi iamthif cb\n");
844 run_next_iamthif_cmd(dev
);
848 if (heci_clear_lists(dev
, file
))
849 dev
->iamthif_state
= HECI_IAMTHIF_IDLE
;
851 spin_unlock_bh(&dev
->device_lock
);
856 static struct heci_cb_private
*find_read_list_entry(
857 struct iamt_heci_device
*dev
,
858 struct heci_file_private
*file_ext
)
860 struct heci_cb_private
*priv_cb_pos
= NULL
;
861 struct heci_cb_private
*priv_cb_next
= NULL
;
862 struct heci_file_private
*file_ext_list_temp
;
864 if (dev
->read_list
.status
== 0
865 && !list_empty(&dev
->read_list
.heci_cb
.cb_list
)) {
866 DBG("remove read_list CB \n");
867 list_for_each_entry_safe(priv_cb_pos
,
869 &dev
->read_list
.heci_cb
.cb_list
, cb_list
) {
871 file_ext_list_temp
= (struct heci_file_private
*)
872 priv_cb_pos
->file_private
;
874 if ((file_ext_list_temp
!= NULL
) &&
875 heci_fe_same_id(file_ext
, file_ext_list_temp
))
884 * heci_read - the read client message function.
886 * @file: pointer to file structure
887 * @ubuf: pointer to user buffer
888 * @length: buffer length
889 * @offset: data offset in buffer
891 * returns >=0 data length on success , <0 on error
893 static ssize_t
heci_read(struct file
*file
, char __user
*ubuf
,
894 size_t length
, loff_t
*offset
)
897 int rets
= 0, err
= 0;
898 int if_num
= iminor(file
->f_dentry
->d_inode
);
899 struct heci_file_private
*file_ext
= file
->private_data
;
900 struct heci_cb_private
*priv_cb_pos
= NULL
;
901 struct heci_cb_private
*priv_cb
= NULL
;
902 struct iamt_heci_device
*dev
;
907 dev
= pci_get_drvdata(heci_device
);
908 if ((if_num
!= HECI_MINOR_NUMBER
) || (!dev
) || (!file_ext
))
911 spin_lock_bh(&dev
->device_lock
);
912 if (dev
->heci_state
!= HECI_ENABLED
) {
913 spin_unlock_bh(&dev
->device_lock
);
916 spin_unlock_bh(&dev
->device_lock
);
918 spin_lock(&file_ext
->file_lock
);
919 if ((file_ext
->sm_state
& HECI_WD_STATE_INDEPENDENCE_MSG_SENT
) == 0) {
920 spin_unlock(&file_ext
->file_lock
);
921 /* Do not allow to read watchdog client */
922 for (i
= 0; i
< dev
->num_heci_me_clients
; i
++) {
923 if (memcmp(&heci_wd_guid
,
924 &dev
->me_clients
[i
].props
.protocol_name
,
925 sizeof(struct guid
)) == 0) {
926 if (file_ext
->me_client_id
==
927 dev
->me_clients
[i
].client_id
)
932 file_ext
->sm_state
&= ~HECI_WD_STATE_INDEPENDENCE_MSG_SENT
;
933 spin_unlock(&file_ext
->file_lock
);
936 if (file_ext
== &dev
->iamthif_file_ext
) {
937 rets
= pthi_read(dev
, if_num
, file
, ubuf
, length
, offset
);
941 if (file_ext
->read_cb
&& file_ext
->read_cb
->information
> *offset
) {
942 priv_cb
= file_ext
->read_cb
;
944 } else if (file_ext
->read_cb
&& file_ext
->read_cb
->information
> 0 &&
945 file_ext
->read_cb
->information
<= *offset
) {
946 priv_cb
= file_ext
->read_cb
;
949 } else if ((!file_ext
->read_cb
|| file_ext
->read_cb
->information
== 0)
951 /*Offset needs to be cleaned for contingous reads*/
957 spin_lock(&file_ext
->read_io_lock
);
958 err
= heci_start_read(dev
, if_num
, file_ext
);
959 if (err
!= 0 && err
!= -EBUSY
) {
960 DBG("heci start read failure with status = %d\n", err
);
961 spin_unlock(&file_ext
->read_io_lock
);
965 if (HECI_READ_COMPLETE
!= file_ext
->reading_state
966 && !waitqueue_active(&file_ext
->rx_wait
)) {
967 if (file
->f_flags
& O_NONBLOCK
) {
969 spin_unlock(&file_ext
->read_io_lock
);
972 spin_unlock(&file_ext
->read_io_lock
);
974 if (wait_event_interruptible(file_ext
->rx_wait
,
975 (HECI_READ_COMPLETE
== file_ext
->reading_state
976 || HECI_FILE_INITIALIZING
== file_ext
->state
977 || HECI_FILE_DISCONNECTED
== file_ext
->state
978 || HECI_FILE_DISCONNECTING
== file_ext
->state
))) {
979 if (signal_pending(current
)) {
986 if (HECI_FILE_INITIALIZING
== file_ext
->state
||
987 HECI_FILE_DISCONNECTED
== file_ext
->state
||
988 HECI_FILE_DISCONNECTING
== file_ext
->state
) {
992 spin_lock(&file_ext
->read_io_lock
);
995 priv_cb
= file_ext
->read_cb
;
998 spin_unlock(&file_ext
->read_io_lock
);
1001 if (file_ext
->reading_state
!= HECI_READ_COMPLETE
) {
1002 spin_unlock(&file_ext
->read_io_lock
);
1005 spin_unlock(&file_ext
->read_io_lock
);
1006 /* now copy the data to user space */
1008 DBG("priv_cb->response_buffer size - %d\n",
1009 priv_cb
->response_buffer
.size
);
1010 DBG("priv_cb->information - %lu\n",
1011 priv_cb
->information
);
1012 if (length
== 0 || ubuf
== NULL
||
1013 *offset
> priv_cb
->information
) {
1018 /* length is being turncated to PAGE_SIZE, however, */
1019 /* information size may be longer */
1020 length
= (length
< (priv_cb
->information
- *offset
) ?
1021 length
: (priv_cb
->information
- *offset
));
1023 if (copy_to_user(ubuf
,
1024 priv_cb
->response_buffer
.data
+ *offset
,
1032 if ((unsigned long)*offset
< priv_cb
->information
)
1036 spin_lock_bh(&dev
->device_lock
);
1037 priv_cb_pos
= find_read_list_entry(dev
, file_ext
);
1038 /* Remove entry from read list */
1039 if (priv_cb_pos
!= NULL
)
1040 list_del(&priv_cb_pos
->cb_list
);
1041 spin_unlock_bh(&dev
->device_lock
);
1042 heci_free_cb_private(priv_cb
);
1043 spin_lock(&file_ext
->read_io_lock
);
1044 file_ext
->reading_state
= HECI_IDLE
;
1045 file_ext
->read_cb
= NULL
;
1046 file_ext
->read_pending
= 0;
1047 spin_unlock(&file_ext
->read_io_lock
);
1048 out
: DBG("end heci read rets= %d\n", rets
);
1053 * heci_write - the write function.
1055 * @file: pointer to file structure
1056 * @ubuf: pointer to user buffer
1057 * @length: buffer length
1058 * @offset: data offset in buffer
1060 * returns >=0 data length on success , <0 on error
1062 static ssize_t
heci_write(struct file
*file
, const char __user
*ubuf
,
1063 size_t length
, loff_t
*offset
)
1067 int if_num
= iminor(file
->f_dentry
->d_inode
);
1068 struct heci_file_private
*file_ext
= file
->private_data
;
1069 struct heci_cb_private
*priv_write_cb
= NULL
;
1070 struct heci_msg_hdr heci_hdr
;
1071 struct iamt_heci_device
*dev
;
1072 unsigned long currtime
= get_seconds();
1077 dev
= pci_get_drvdata(heci_device
);
1079 if ((if_num
!= HECI_MINOR_NUMBER
) || (!dev
) || (!file_ext
))
1082 spin_lock_bh(&dev
->device_lock
);
1084 if (dev
->heci_state
!= HECI_ENABLED
) {
1085 spin_unlock_bh(&dev
->device_lock
);
1088 if (file_ext
== &dev
->iamthif_file_ext
) {
1089 priv_write_cb
= find_pthi_read_list_entry(dev
, file
);
1090 if ((priv_write_cb
!= NULL
) &&
1091 (((currtime
- priv_write_cb
->read_time
) >
1092 IAMTHIF_READ_TIMER
) ||
1093 (file_ext
->reading_state
== HECI_READ_COMPLETE
))) {
1095 list_del(&priv_write_cb
->cb_list
);
1096 heci_free_cb_private(priv_write_cb
);
1097 priv_write_cb
= NULL
;
1101 /* free entry used in read */
1102 if (file_ext
->reading_state
== HECI_READ_COMPLETE
) {
1104 priv_write_cb
= find_read_list_entry(dev
, file_ext
);
1105 if (priv_write_cb
!= NULL
) {
1106 list_del(&priv_write_cb
->cb_list
);
1107 heci_free_cb_private(priv_write_cb
);
1108 priv_write_cb
= NULL
;
1109 spin_lock(&file_ext
->read_io_lock
);
1110 file_ext
->reading_state
= HECI_IDLE
;
1111 file_ext
->read_cb
= NULL
;
1112 file_ext
->read_pending
= 0;
1113 spin_unlock(&file_ext
->read_io_lock
);
1115 } else if (file_ext
->reading_state
== HECI_IDLE
&&
1116 file_ext
->read_pending
== 0)
1119 spin_unlock_bh(&dev
->device_lock
);
1121 priv_write_cb
= kzalloc(sizeof(struct heci_cb_private
), GFP_KERNEL
);
1125 priv_write_cb
->file_object
= file
;
1126 priv_write_cb
->file_private
= file_ext
;
1127 priv_write_cb
->request_buffer
.data
= kmalloc(length
, GFP_KERNEL
);
1128 if (!priv_write_cb
->request_buffer
.data
) {
1129 kfree(priv_write_cb
);
1132 DBG("length =%d\n", (int) length
);
1134 if (copy_from_user(priv_write_cb
->request_buffer
.data
,
1140 spin_lock(&file_ext
->file_lock
);
1141 file_ext
->sm_state
= 0;
1142 if ((length
== 4) &&
1143 ((memcmp(heci_wd_state_independence_msg
[0], ubuf
, 4) == 0) ||
1144 (memcmp(heci_wd_state_independence_msg
[1], ubuf
, 4) == 0) ||
1145 (memcmp(heci_wd_state_independence_msg
[2], ubuf
, 4) == 0)))
1146 file_ext
->sm_state
|= HECI_WD_STATE_INDEPENDENCE_MSG_SENT
;
1147 spin_unlock(&file_ext
->file_lock
);
1149 INIT_LIST_HEAD(&priv_write_cb
->cb_list
);
1150 if (file_ext
== &dev
->iamthif_file_ext
) {
1151 priv_write_cb
->response_buffer
.data
=
1152 kmalloc(IAMTHIF_MTU
, GFP_KERNEL
);
1153 if (!priv_write_cb
->response_buffer
.data
) {
1157 spin_lock_bh(&dev
->device_lock
);
1158 if (dev
->heci_state
!= HECI_ENABLED
) {
1159 spin_unlock_bh(&dev
->device_lock
);
1163 for (i
= 0; i
< dev
->num_heci_me_clients
; i
++) {
1164 if (dev
->me_clients
[i
].client_id
==
1165 dev
->iamthif_file_ext
.me_client_id
)
1169 BUG_ON(dev
->me_clients
[i
].client_id
!= file_ext
->me_client_id
);
1170 if ((i
== dev
->num_heci_me_clients
) ||
1171 (dev
->me_clients
[i
].client_id
!=
1172 dev
->iamthif_file_ext
.me_client_id
)) {
1174 spin_unlock_bh(&dev
->device_lock
);
1177 } else if ((length
> dev
->me_clients
[i
].props
.max_msg_length
)
1179 spin_unlock_bh(&dev
->device_lock
);
1185 priv_write_cb
->response_buffer
.size
= IAMTHIF_MTU
;
1186 priv_write_cb
->major_file_operations
= HECI_IOCTL
;
1187 priv_write_cb
->information
= 0;
1188 priv_write_cb
->request_buffer
.size
= length
;
1189 if (dev
->iamthif_file_ext
.state
!= HECI_FILE_CONNECTED
) {
1190 spin_unlock_bh(&dev
->device_lock
);
1195 if (!list_empty(&dev
->pthi_cmd_list
.heci_cb
.cb_list
)
1196 || dev
->iamthif_state
!= HECI_IAMTHIF_IDLE
) {
1197 DBG("pthi_state = %d\n", (int) dev
->iamthif_state
);
1198 DBG("add PTHI cb to pthi cmd waiting list\n");
1199 list_add_tail(&priv_write_cb
->cb_list
,
1200 &dev
->pthi_cmd_list
.heci_cb
.cb_list
);
1203 DBG("call pthi write\n");
1204 rets
= pthi_write(dev
, priv_write_cb
);
1207 DBG("pthi write failed with status = %d\n",
1209 spin_unlock_bh(&dev
->device_lock
);
1214 spin_unlock_bh(&dev
->device_lock
);
1218 priv_write_cb
->major_file_operations
= HECI_WRITE
;
1219 /* make sure information is zero before we start */
1221 priv_write_cb
->information
= 0;
1222 priv_write_cb
->request_buffer
.size
= length
;
1224 spin_lock(&file_ext
->write_io_lock
);
1225 DBG("host client = %d, ME client = %d\n",
1226 file_ext
->host_client_id
, file_ext
->me_client_id
);
1227 if (file_ext
->state
!= HECI_FILE_CONNECTED
) {
1229 DBG("host client = %d, is not connected to ME client = %d",
1230 file_ext
->host_client_id
,
1231 file_ext
->me_client_id
);
1235 for (i
= 0; i
< dev
->num_heci_me_clients
; i
++) {
1236 if (dev
->me_clients
[i
].client_id
==
1237 file_ext
->me_client_id
)
1240 BUG_ON(dev
->me_clients
[i
].client_id
!= file_ext
->me_client_id
);
1241 if (i
== dev
->num_heci_me_clients
) {
1245 if (length
> dev
->me_clients
[i
].props
.max_msg_length
|| length
<= 0) {
1249 priv_write_cb
->file_private
= file_ext
;
1251 spin_lock_bh(&dev
->device_lock
);
1252 if (flow_ctrl_creds(dev
, file_ext
) &&
1253 dev
->host_buffer_is_empty
) {
1254 spin_unlock_bh(&dev
->device_lock
);
1255 dev
->host_buffer_is_empty
= 0;
1256 if (length
> ((((dev
->host_hw_state
& H_CBD
) >> 24) *
1257 sizeof(__u32
)) - sizeof(struct heci_msg_hdr
))) {
1260 (((dev
->host_hw_state
& H_CBD
) >> 24) *
1262 sizeof(struct heci_msg_hdr
);
1263 heci_hdr
.msg_complete
= 0;
1265 heci_hdr
.length
= length
;
1266 heci_hdr
.msg_complete
= 1;
1268 heci_hdr
.host_addr
= file_ext
->host_client_id
;
1269 heci_hdr
.me_addr
= file_ext
->me_client_id
;
1270 heci_hdr
.reserved
= 0;
1271 DBG("call heci_write_message header=%08x.\n",
1272 *((__u32
*) &heci_hdr
));
1273 spin_unlock(&file_ext
->write_io_lock
);
1274 /* protect heci low level write */
1275 spin_lock_bh(&dev
->device_lock
);
1276 if (!heci_write_message(dev
, &heci_hdr
,
1277 (unsigned char *) (priv_write_cb
->request_buffer
.data
),
1280 spin_unlock_bh(&dev
->device_lock
);
1281 heci_free_cb_private(priv_write_cb
);
1283 priv_write_cb
->information
= 0;
1286 file_ext
->writing_state
= HECI_WRITING
;
1287 priv_write_cb
->information
= heci_hdr
.length
;
1288 if (heci_hdr
.msg_complete
) {
1289 flow_ctrl_reduce(dev
, file_ext
);
1290 list_add_tail(&priv_write_cb
->cb_list
,
1291 &dev
->write_waiting_list
.heci_cb
.cb_list
);
1293 list_add_tail(&priv_write_cb
->cb_list
,
1294 &dev
->write_list
.heci_cb
.cb_list
);
1296 spin_unlock_bh(&dev
->device_lock
);
1300 spin_unlock_bh(&dev
->device_lock
);
1301 priv_write_cb
->information
= 0;
1302 file_ext
->writing_state
= HECI_WRITING
;
1303 spin_unlock(&file_ext
->write_io_lock
);
1304 list_add_tail(&priv_write_cb
->cb_list
,
1305 &dev
->write_list
.heci_cb
.cb_list
);
1310 spin_unlock(&file_ext
->write_io_lock
);
1312 heci_free_cb_private(priv_write_cb
);
1318 * heci_ioctl - the IOCTL function
1320 * @inode: pointer to inode structure
1321 * @file: pointer to file structure
1322 * @cmd: ioctl command
1323 * @data: pointer to heci message structure
1325 * returns 0 on success , <0 on error
1327 static int heci_ioctl(struct inode
*inode
, struct file
*file
,
1328 unsigned int cmd
, unsigned long data
)
1331 int if_num
= iminor(inode
);
1332 struct heci_file_private
*file_ext
= file
->private_data
;
1334 struct heci_message_data
*u_msg
= (struct heci_message_data
*) data
;
1335 struct heci_message_data k_msg
; /* all in kernel on the stack */
1336 struct iamt_heci_device
*dev
;
1338 if (!capable(CAP_SYS_ADMIN
))
1344 dev
= pci_get_drvdata(heci_device
);
1345 if ((if_num
!= HECI_MINOR_NUMBER
) || (!dev
) || (!file_ext
))
1348 spin_lock_bh(&dev
->device_lock
);
1349 if (dev
->heci_state
!= HECI_ENABLED
) {
1350 spin_unlock_bh(&dev
->device_lock
);
1353 spin_unlock_bh(&dev
->device_lock
);
1355 /* first copy from user all data needed */
1356 if (copy_from_user(&k_msg
, u_msg
, sizeof(k_msg
))) {
1357 DBG("first copy from user all data needed filled\n");
1360 DBG("user message size is %d\n", k_msg
.size
);
1363 case IOCTL_HECI_GET_VERSION
:
1364 DBG(": IOCTL_HECI_GET_VERSION\n");
1365 rets
= heci_ioctl_get_version(dev
, if_num
, u_msg
, k_msg
,
1369 case IOCTL_HECI_CONNECT_CLIENT
:
1370 DBG(": IOCTL_HECI_CONNECT_CLIENT.\n");
1371 rets
= heci_ioctl_connect_client(dev
, if_num
, u_msg
, k_msg
,
1376 DBG(": IOCTL_HECI_WD.\n");
1377 rets
= heci_ioctl_wd(dev
, if_num
, k_msg
, file_ext
);
1380 case IOCTL_HECI_BYPASS_WD
:
1381 DBG(": IOCTL_HECI_BYPASS_WD.\n");
1382 rets
= heci_ioctl_bypass_wd(dev
, if_num
, k_msg
, file_ext
);
1393 * heci_poll - the poll function
1395 * @file: pointer to file structure
1396 * @wait: pointer to poll_table structure
1400 static unsigned int heci_poll(struct file
*file
, poll_table
*wait
)
1402 int if_num
= iminor(file
->f_dentry
->d_inode
);
1403 unsigned int mask
= 0;
1404 struct heci_file_private
*file_ext
= file
->private_data
;
1405 struct iamt_heci_device
*dev
;
1410 dev
= pci_get_drvdata(heci_device
);
1412 if ((if_num
!= HECI_MINOR_NUMBER
) || (!dev
) || (!file_ext
))
1415 spin_lock_bh(&dev
->device_lock
);
1416 if (dev
->heci_state
!= HECI_ENABLED
) {
1417 spin_unlock_bh(&dev
->device_lock
);
1420 spin_unlock_bh(&dev
->device_lock
);
1422 if (file_ext
== &dev
->iamthif_file_ext
) {
1423 poll_wait(file
, &dev
->iamthif_file_ext
.wait
, wait
);
1424 spin_lock(&dev
->iamthif_file_ext
.file_lock
);
1425 if (dev
->iamthif_state
== HECI_IAMTHIF_READ_COMPLETE
1426 && dev
->iamthif_file_object
== file
) {
1427 mask
|= (POLLIN
| POLLRDNORM
);
1428 spin_lock_bh(&dev
->device_lock
);
1429 DBG("run next pthi cb\n");
1430 run_next_iamthif_cmd(dev
);
1431 spin_unlock_bh(&dev
->device_lock
);
1433 spin_unlock(&dev
->iamthif_file_ext
.file_lock
);
1436 poll_wait(file
, &file_ext
->tx_wait
, wait
);
1437 spin_lock(&file_ext
->write_io_lock
);
1438 if (HECI_WRITE_COMPLETE
== file_ext
->writing_state
)
1439 mask
|= (POLLIN
| POLLRDNORM
);
1441 spin_unlock(&file_ext
->write_io_lock
);
1448 static int heci_suspend(struct pci_dev
*pdev
, pm_message_t state
)
1450 struct iamt_heci_device
*dev
= pci_get_drvdata(pdev
);
1453 spin_lock_bh(&dev
->device_lock
);
1454 if (dev
->reinit_tsk
!= NULL
) {
1455 kthread_stop(dev
->reinit_tsk
);
1456 dev
->reinit_tsk
= NULL
;
1458 spin_unlock_bh(&dev
->device_lock
);
1460 /* Stop watchdog if exists */
1461 del_timer_sync(&dev
->wd_timer
);
1462 if (dev
->wd_file_ext
.state
== HECI_FILE_CONNECTED
1463 && dev
->wd_timeout
) {
1464 spin_lock_bh(&dev
->device_lock
);
1465 g_sus_wd_timeout
= dev
->wd_timeout
;
1466 dev
->wd_timeout
= 0;
1467 dev
->wd_due_counter
= 0;
1468 memcpy(dev
->wd_data
, heci_stop_wd_params
,
1469 HECI_WD_PARAMS_SIZE
);
1471 if (dev
->host_buffer_is_empty
&&
1472 flow_ctrl_creds(dev
, &dev
->wd_file_ext
)) {
1473 dev
->host_buffer_is_empty
= 0;
1474 if (!heci_send_wd(dev
))
1475 DBG("send stop WD failed\n");
1477 flow_ctrl_reduce(dev
, &dev
->wd_file_ext
);
1479 dev
->wd_pending
= 0;
1481 dev
->wd_pending
= 1;
1483 spin_unlock_bh(&dev
->device_lock
);
1486 err
= wait_event_interruptible_timeout(dev
->wait_stop_wd
,
1489 if (!dev
->wd_stoped
)
1490 DBG("stop wd failed to complete.\n");
1492 DBG("stop wd complete %d.\n", err
);
1496 /* Set new heci state */
1497 spin_lock_bh(&dev
->device_lock
);
1498 if (dev
->heci_state
== HECI_ENABLED
||
1499 dev
->heci_state
== HECI_RECOVERING_FROM_RESET
) {
1500 dev
->heci_state
= HECI_POWER_DOWN
;
1503 spin_unlock_bh(&dev
->device_lock
);
1505 pci_save_state(pdev
);
1507 pci_disable_device(pdev
);
1508 free_irq(pdev
->irq
, dev
);
1510 pci_set_power_state(pdev
, PCI_D3hot
);
1515 static int heci_resume(struct pci_dev
*pdev
)
1517 struct iamt_heci_device
*dev
;
1520 pci_set_power_state(pdev
, PCI_D0
);
1521 pci_restore_state(pdev
);
1523 dev
= pci_get_drvdata(pdev
);
1527 /* request and enable interrupt */
1528 err
= request_irq(pdev
->irq
, heci_isr_interrupt
, IRQF_SHARED
,
1529 heci_driver_name
, dev
);
1531 printk(KERN_ERR
"heci: Request_irq failure. irq = %d \n",
1536 spin_lock_bh(&dev
->device_lock
);
1537 dev
->heci_state
= HECI_POWER_UP
;
1539 spin_unlock_bh(&dev
->device_lock
);
1541 /* Start watchdog if stopped in suspend */
1542 if (g_sus_wd_timeout
!= 0) {
1543 dev
->wd_timeout
= g_sus_wd_timeout
;
1545 memcpy(dev
->wd_data
, heci_start_wd_params
,
1546 HECI_WD_PARAMS_SIZE
);
1547 memcpy(dev
->wd_data
+ HECI_WD_PARAMS_SIZE
,
1548 &dev
->wd_timeout
, sizeof(__u16
));
1549 dev
->wd_due_counter
= 1;
1551 if (dev
->wd_timeout
)
1552 mod_timer(&dev
->wd_timer
, jiffies
);
1554 g_sus_wd_timeout
= 0;
1560 MODULE_AUTHOR("Intel Corporation");
1561 MODULE_DESCRIPTION("Intel(R) Management Engine Interface");
1562 MODULE_LICENSE("Dual BSD/GPL");
1563 MODULE_VERSION(HECI_DRIVER_VERSION
);