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>
64 #include "heci_interface.h"
65 #include "heci_version.h"
68 #define HECI_READ_TIMEOUT 45
70 #define HECI_DRIVER_NAME "heci"
75 char heci_driver_name
[] = HECI_DRIVER_NAME
;
76 char heci_driver_string
[] = "Intel(R) Management Engine Interface";
77 char heci_driver_version
[] = HECI_DRIVER_VERSION
;
78 char heci_copyright
[] = "Copyright (c) 2003 - 2008 Intel Corporation.";
86 MODULE_PARM_DESC(heci_debug
, "Debug enabled or not");
87 module_param(heci_debug
, int, 0644);
90 #define HECI_DEV_NAME "heci"
92 /* heci char device for registration */
93 static struct cdev heci_cdev
;
95 /* major number for device */
96 static int heci_major
;
97 /* The device pointer */
98 static struct pci_dev
*heci_device
;
100 struct class *heci_class
;
103 /* heci_pci_tbl - PCI Device ID Table */
104 static struct pci_device_id heci_pci_tbl
[] = {
105 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_82946GZ
)},
106 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_82G35
)},
107 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_82Q965
)},
108 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_82G965
)},
109 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_82GM965
)},
110 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_82GME965
)},
111 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9_82Q35
)},
112 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9_82G33
)},
113 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9_82Q33
)},
114 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9_82X38
)},
115 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9_3200
)},
116 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9_6
)},
117 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9_7
)},
118 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9_8
)},
119 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9_9
)},
120 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9_10
)},
121 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9M_1
)},
122 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9M_2
)},
123 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9M_3
)},
124 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH9M_4
)},
125 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH10_1
)},
126 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH10_2
)},
127 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH10_3
)},
128 {PCI_DEVICE(PCI_VENDOR_ID_INTEL
, HECI_DEV_ID_ICH10_4
)},
129 /* required last entry */
133 MODULE_DEVICE_TABLE(pci
, heci_pci_tbl
);
136 * Local Function Prototypes
138 static int __init
heci_init_module(void);
139 static void __exit
heci_exit_module(void);
140 static int __devinit
heci_probe(struct pci_dev
*pdev
,
141 const struct pci_device_id
*ent
);
142 static void __devexit
heci_remove(struct pci_dev
*pdev
);
143 static int heci_open(struct inode
*inode
, struct file
*file
);
144 static int heci_release(struct inode
*inode
, struct file
*file
);
145 static ssize_t
heci_read(struct file
*file
, char __user
*ubuf
,
146 size_t length
, loff_t
*offset
);
147 static int heci_ioctl(struct inode
*inode
, struct file
*file
,
148 unsigned int cmd
, unsigned long data
);
149 static ssize_t
heci_write(struct file
*file
, const char __user
*ubuf
,
150 size_t length
, loff_t
*offset
);
151 static unsigned int heci_poll(struct file
*file
, poll_table
*wait
);
152 static struct heci_cb_private
*find_read_list_entry(
153 struct iamt_heci_device
*dev
,
154 struct heci_file_private
*file_ext
);
156 static int heci_suspend(struct pci_dev
*pdev
, pm_message_t state
);
157 static int heci_resume(struct pci_dev
*pdev
);
158 static __u16 g_sus_wd_timeout
;
160 #define heci_suspend NULL
161 #define heci_resume NULL
164 * PCI driver structure
166 static struct pci_driver heci_driver
= {
167 .name
= heci_driver_name
,
168 .id_table
= heci_pci_tbl
,
170 .remove
= __devexit_p(heci_remove
),
171 .shutdown
= __devexit_p(heci_remove
),
172 .suspend
= heci_suspend
,
173 .resume
= heci_resume
177 * file operations structure will be use heci char device.
179 static struct file_operations heci_fops
= {
180 .owner
= THIS_MODULE
,
184 .release
= heci_release
,
190 * heci_registration_cdev - set up the cdev structure for heci device.
192 * @dev: char device struct
193 * @hminor: minor number for registration char device
194 * @fops: file operations structure
196 * returns 0 on success, <0 on failure.
198 static int heci_registration_cdev(struct cdev
*dev
, int hminor
,
199 struct file_operations
*fops
)
201 int ret
, devno
= MKDEV(heci_major
, hminor
);
203 cdev_init(dev
, fops
);
204 dev
->owner
= THIS_MODULE
;
205 ret
= cdev_add(dev
, devno
, 1);
206 /* Fail gracefully if need be */
208 printk(KERN_ERR
"heci: Error %d registering heci device %d\n",
214 /* Display the version of heci driver. */
215 static ssize_t
version_show(struct class *dev
, char *buf
)
217 return sprintf(buf
, "%s %s.\n",
218 heci_driver_string
, heci_driver_version
);
221 static CLASS_ATTR(version
, S_IRUGO
, version_show
, NULL
);
224 * heci_register_cdev - registers heci char device
226 * returns 0 on success, <0 on failure.
228 static int heci_register_cdev(void)
233 /* registration of char devices */
234 ret
= alloc_chrdev_region(&dev
, HECI_MINORS_BASE
, HECI_MINORS_COUNT
,
237 printk(KERN_ERR
"heci: Error allocating char device region.\n");
241 heci_major
= MAJOR(dev
);
243 ret
= heci_registration_cdev(&heci_cdev
, HECI_MINOR_NUMBER
,
246 unregister_chrdev_region(MKDEV(heci_major
, HECI_MINORS_BASE
),
253 * heci_unregister_cdev - unregisters heci char device
255 static void heci_unregister_cdev(void)
257 cdev_del(&heci_cdev
);
258 unregister_chrdev_region(MKDEV(heci_major
, HECI_MINORS_BASE
),
262 #ifndef HECI_DEVICE_CREATE
263 #define HECI_DEVICE_CREATE device_create
266 * heci_sysfs_device_create - adds device entry to sysfs
268 * returns 0 on success, <0 on failure.
270 static int heci_sysfs_device_create(void)
276 class = class_create(THIS_MODULE
, HECI_DRIVER_NAME
);
278 err
= PTR_ERR(class);
279 printk(KERN_ERR
"heci: Error creating heci class.\n");
283 err
= class_create_file(class, &class_attr_version
);
285 class_destroy(class);
286 printk(KERN_ERR
"heci: Error creating heci class file.\n");
290 tmphdev
= HECI_DEVICE_CREATE(class, NULL
, heci_cdev
.dev
, NULL
,
292 if (IS_ERR(tmphdev
)) {
293 err
= PTR_ERR(tmphdev
);
294 class_remove_file(class, &class_attr_version
);
295 class_destroy(class);
305 * heci_sysfs_device_remove - unregisters the device entry on sysfs
307 static void heci_sysfs_device_remove(void)
309 if ((heci_class
== NULL
) || (IS_ERR(heci_class
)))
312 device_destroy(heci_class
, heci_cdev
.dev
);
313 class_remove_file(heci_class
, &class_attr_version
);
314 class_destroy(heci_class
);
318 * heci_init_module - Driver Registration Routine
320 * heci_init_module is the first routine called when the driver is
321 * loaded. All it does is register with the PCI subsystem.
323 * returns 0 on success, <0 on failure.
325 static int __init
heci_init_module(void)
329 printk(KERN_INFO
"heci: %s - version %s\n", heci_driver_string
,
330 heci_driver_version
);
331 printk(KERN_INFO
"heci: %s\n", heci_copyright
);
333 /* init pci module */
334 ret
= pci_register_driver(&heci_driver
);
336 printk(KERN_ERR
"heci: Error registering driver.\n");
340 ret
= heci_register_cdev();
344 ret
= heci_sysfs_device_create();
346 goto unregister_cdev
;
351 heci_unregister_cdev();
353 pci_unregister_driver(&heci_driver
);
358 module_init(heci_init_module
);
362 * heci_exit_module - Driver Exit Cleanup Routine
364 * heci_exit_module is called just before the driver is removed
367 static void __exit
heci_exit_module(void)
369 pci_unregister_driver(&heci_driver
);
370 heci_sysfs_device_remove();
371 heci_unregister_cdev();
374 module_exit(heci_exit_module
);
378 * heci_probe - Device Initialization Routine
380 * @pdev: PCI device information struct
381 * @ent: entry in kcs_pci_tbl
383 * returns 0 on success, <0 on failure.
385 static int __devinit
heci_probe(struct pci_dev
*pdev
,
386 const struct pci_device_id
*ent
)
388 struct iamt_heci_device
*dev
= NULL
;
396 err
= pci_enable_device(pdev
);
398 printk(KERN_ERR
"heci: Failed to enable pci device.\n");
401 /* set PCI host mastering */
402 pci_set_master(pdev
);
403 /* pci request regions for heci driver */
404 err
= pci_request_regions(pdev
, heci_driver_name
);
406 printk(KERN_ERR
"heci: Failed to get pci regions.\n");
409 /* allocates and initializes the heci dev structure */
410 dev
= init_heci_device(pdev
);
413 goto release_regions
;
415 /* mapping IO device memory */
416 for (i
= 0; i
<= 5; i
++) {
417 if (pci_resource_len(pdev
, i
) == 0)
419 if (pci_resource_flags(pdev
, i
) & IORESOURCE_IO
) {
420 printk(KERN_ERR
"heci: heci has IO ports.\n");
422 } else if (pci_resource_flags(pdev
, i
) & IORESOURCE_MEM
) {
425 "heci: Too many mem addresses.\n");
428 dev
->mem_base
= pci_resource_start(pdev
, i
);
429 dev
->mem_length
= pci_resource_len(pdev
, i
);
432 if (!dev
->mem_base
) {
433 printk(KERN_ERR
"heci: No address to use.\n");
437 dev
->mem_addr
= ioremap_nocache(dev
->mem_base
,
439 if (!dev
->mem_addr
) {
440 printk(KERN_ERR
"heci: Remap IO device memory failure.\n");
444 /* request and enable interrupt */
445 err
= request_irq(pdev
->irq
, heci_isr_interrupt
, IRQF_SHARED
,
446 heci_driver_name
, dev
);
448 printk(KERN_ERR
"heci: Request_irq failure. irq = %d \n",
453 if (heci_hw_init(dev
)) {
454 printk(KERN_ERR
"heci: Init hw failure.\n");
458 init_timer(&dev
->wd_timer
);
460 heci_initialize_clients(dev
);
461 if (dev
->heci_state
!= HECI_ENABLED
) {
466 spin_lock_bh(&dev
->device_lock
);
468 pci_set_drvdata(pdev
, dev
);
469 spin_unlock_bh(&dev
->device_lock
);
472 mod_timer(&dev
->wd_timer
, jiffies
);
475 g_sus_wd_timeout
= 0;
477 printk(KERN_INFO
"heci driver initialization successful.\n");
481 /* disable interrupts */
482 dev
->host_hw_state
= read_heci_register(dev
, H_CSR
);
483 heci_csr_disable_interrupts(dev
);
485 del_timer_sync(&dev
->wd_timer
);
487 flush_scheduled_work();
490 free_irq(pdev
->irq
, dev
);
493 iounmap(dev
->mem_addr
);
497 pci_release_regions(pdev
);
499 pci_disable_device(pdev
);
501 printk(KERN_ERR
"heci driver initialization failed.\n");
506 * heci_remove - Device Removal Routine
508 * @pdev: PCI device information struct
510 * heci_remove is called by the PCI subsystem to alert the driver
511 * that it should release a PCI device.
513 static void __devexit
heci_remove(struct pci_dev
*pdev
)
515 struct iamt_heci_device
*dev
= pci_get_drvdata(pdev
);
517 if (heci_device
!= pdev
)
523 spin_lock_bh(&dev
->device_lock
);
524 if (heci_device
!= pdev
) {
525 spin_unlock_bh(&dev
->device_lock
);
529 if (dev
->reinit_tsk
!= NULL
) {
530 kthread_stop(dev
->reinit_tsk
);
531 dev
->reinit_tsk
= NULL
;
534 del_timer_sync(&dev
->wd_timer
);
535 if (dev
->wd_file_ext
.state
== HECI_FILE_CONNECTED
536 && dev
->wd_timeout
) {
538 dev
->wd_due_counter
= 0;
539 memcpy(dev
->wd_data
, heci_stop_wd_params
, HECI_WD_PARAMS_SIZE
);
541 if (dev
->host_buffer_is_empty
&&
542 flow_ctrl_creds(dev
, &dev
->wd_file_ext
)) {
543 dev
->host_buffer_is_empty
= 0;
545 if (!heci_send_wd(dev
))
546 DBG("send stop WD failed\n");
548 flow_ctrl_reduce(dev
, &dev
->wd_file_ext
);
555 spin_unlock_bh(&dev
->device_lock
);
557 wait_event_interruptible_timeout(dev
->wait_stop_wd
,
558 (dev
->wd_stoped
), 10 * HZ
);
559 spin_lock_bh(&dev
->device_lock
);
561 DBG("stop wd failed to complete.\n");
563 DBG("stop wd complete.\n");
568 spin_unlock_bh(&dev
->device_lock
);
570 if (dev
->iamthif_file_ext
.state
== HECI_FILE_CONNECTED
) {
571 dev
->iamthif_file_ext
.state
= HECI_FILE_DISCONNECTING
;
572 heci_disconnect_host_client(dev
,
573 &dev
->iamthif_file_ext
);
575 if (dev
->wd_file_ext
.state
== HECI_FILE_CONNECTED
) {
576 dev
->wd_file_ext
.state
= HECI_FILE_DISCONNECTING
;
577 heci_disconnect_host_client(dev
,
581 spin_lock_bh(&dev
->device_lock
);
583 /* remove entry if already in list */
584 DBG("list del iamthif and wd file list.\n");
585 heci_remove_client_from_file_list(dev
, dev
->wd_file_ext
.
587 heci_remove_client_from_file_list(dev
,
588 dev
->iamthif_file_ext
.host_client_id
);
590 dev
->iamthif_current_cb
= NULL
;
591 dev
->iamthif_file_ext
.file
= NULL
;
592 dev
->num_heci_me_clients
= 0;
594 spin_unlock_bh(&dev
->device_lock
);
596 flush_scheduled_work();
598 /* disable interrupts */
599 heci_csr_disable_interrupts(dev
);
601 free_irq(pdev
->irq
, dev
);
602 pci_set_drvdata(pdev
, NULL
);
605 iounmap(dev
->mem_addr
);
609 pci_release_regions(pdev
);
610 pci_disable_device(pdev
);
614 * heci_clear_list - remove all callbacks associated with file
617 * @file: file information struct
618 * @heci_cb_list: callbacks list
620 * heci_clear_list is called to clear resources associated with file
621 * when application calls close function or Ctrl-C was pressed
623 * returns 1 if callback removed from the list, 0 otherwise
625 static int heci_clear_list(struct iamt_heci_device
*dev
,
626 struct file
*file
, struct list_head
*heci_cb_list
)
628 struct heci_cb_private
*priv_cb_pos
= NULL
;
629 struct heci_cb_private
*priv_cb_next
= NULL
;
630 struct file
*file_temp
;
633 /* list all list member */
634 list_for_each_entry_safe(priv_cb_pos
, priv_cb_next
,
635 heci_cb_list
, cb_list
) {
636 file_temp
= (struct file
*)priv_cb_pos
->file_object
;
637 /* check if list member associated with a file */
638 if (file_temp
== file
) {
639 /* remove member from the list */
640 list_del(&priv_cb_pos
->cb_list
);
641 /* check if cb equal to current iamthif cb */
642 if (dev
->iamthif_current_cb
== priv_cb_pos
) {
643 dev
->iamthif_current_cb
= NULL
;
644 /* send flow control to iamthif client */
645 heci_send_flow_control(dev
,
646 &dev
->iamthif_file_ext
);
648 /* free all allocated buffers */
649 heci_free_cb_private(priv_cb_pos
);
657 * heci_clear_lists - remove all callbacks associated with file
659 * @dev: device information struct
660 * @file: file information struct
662 * heci_clear_lists is called to clear resources associated with file
663 * when application calls close function or Ctrl-C was pressed
665 * returns 1 if callback removed from the list, 0 otherwise
667 static int heci_clear_lists(struct iamt_heci_device
*dev
, struct file
*file
)
671 /* remove callbacks associated with a file */
672 heci_clear_list(dev
, file
, &dev
->pthi_cmd_list
.heci_cb
.cb_list
);
673 if (heci_clear_list(dev
, file
,
674 &dev
->pthi_read_complete_list
.heci_cb
.cb_list
))
677 heci_clear_list(dev
, file
, &dev
->ctrl_rd_list
.heci_cb
.cb_list
);
679 if (heci_clear_list(dev
, file
, &dev
->ctrl_wr_list
.heci_cb
.cb_list
))
682 if (heci_clear_list(dev
, file
,
683 &dev
->write_waiting_list
.heci_cb
.cb_list
))
686 if (heci_clear_list(dev
, file
, &dev
->write_list
.heci_cb
.cb_list
))
689 /* check if iamthif_current_cb not NULL */
690 if (dev
->iamthif_current_cb
&& (!rets
)) {
691 /* check file and iamthif current cb association */
692 if (dev
->iamthif_current_cb
->file_object
== file
) {
694 heci_free_cb_private(dev
->iamthif_current_cb
);
695 dev
->iamthif_current_cb
= NULL
;
703 * heci_open - the open function
705 * @inode: pointer to inode structure
706 * @file: pointer to file structure
708 * returns 0 on success, <0 on error
710 static int heci_open(struct inode
*inode
, struct file
*file
)
712 struct heci_file_private
*file_ext
;
713 int if_num
= iminor(inode
);
714 struct iamt_heci_device
*dev
;
719 dev
= pci_get_drvdata(heci_device
);
720 if ((if_num
!= HECI_MINOR_NUMBER
) || (!dev
))
723 file_ext
= heci_alloc_file_private(file
);
724 if (file_ext
== NULL
)
727 spin_lock_bh(&dev
->device_lock
);
728 if (dev
->heci_state
!= HECI_ENABLED
) {
729 spin_unlock_bh(&dev
->device_lock
);
733 if (dev
->open_handle_count
>= HECI_MAX_OPEN_HANDLE_COUNT
) {
734 spin_unlock_bh(&dev
->device_lock
);
738 dev
->open_handle_count
++;
739 list_add_tail(&file_ext
->link
, &dev
->file_list
);
740 while ((dev
->heci_host_clients
[dev
->current_host_client_id
/ 8]
741 & (1 << (dev
->current_host_client_id
% 8))) != 0) {
743 dev
->current_host_client_id
++; /* allow overflow */
744 DBG("current_host_client_id = %d\n",
745 dev
->current_host_client_id
);
746 DBG("dev->open_handle_count = %lu\n",
747 dev
->open_handle_count
);
749 DBG("current_host_client_id = %d\n", dev
->current_host_client_id
);
750 file_ext
->host_client_id
= dev
->current_host_client_id
;
751 dev
->heci_host_clients
[file_ext
->host_client_id
/ 8] |=
752 (1 << (file_ext
->host_client_id
% 8));
753 spin_unlock_bh(&dev
->device_lock
);
754 spin_lock(&file_ext
->file_lock
);
755 file_ext
->state
= HECI_FILE_INITIALIZING
;
756 file_ext
->sm_state
= 0;
758 file
->private_data
= file_ext
;
759 spin_unlock(&file_ext
->file_lock
);
765 * heci_release - the release function
767 * @inode: pointer to inode structure
768 * @file: pointer to file structure
770 * returns 0 on success, <0 on error
772 static int heci_release(struct inode
*inode
, struct file
*file
)
775 int if_num
= iminor(inode
);
776 struct heci_file_private
*file_ext
= file
->private_data
;
777 struct heci_cb_private
*priv_cb
= NULL
;
778 struct iamt_heci_device
*dev
;
783 dev
= pci_get_drvdata(heci_device
);
784 if ((if_num
!= HECI_MINOR_NUMBER
) || (!dev
) || (!file_ext
))
787 if (file_ext
!= &dev
->iamthif_file_ext
) {
788 spin_lock(&file_ext
->file_lock
);
789 if (file_ext
->state
== HECI_FILE_CONNECTED
) {
790 file_ext
->state
= HECI_FILE_DISCONNECTING
;
791 spin_unlock(&file_ext
->file_lock
);
792 DBG("disconnecting client host client = %d, "
794 file_ext
->host_client_id
,
795 file_ext
->me_client_id
);
796 rets
= heci_disconnect_host_client(dev
, file_ext
);
797 spin_lock(&file_ext
->file_lock
);
799 spin_lock_bh(&dev
->device_lock
);
800 heci_flush_queues(dev
, file_ext
);
801 DBG("remove client host client = %d, ME client = %d\n",
802 file_ext
->host_client_id
,
803 file_ext
->me_client_id
);
805 if (dev
->open_handle_count
> 0) {
806 dev
->heci_host_clients
[file_ext
->host_client_id
/ 8] &=
807 ~(1 << (file_ext
->host_client_id
% 8));
808 dev
->open_handle_count
--;
810 heci_remove_client_from_file_list(dev
,
811 file_ext
->host_client_id
);
814 if (file_ext
->read_cb
!= NULL
) {
815 priv_cb
= find_read_list_entry(dev
, file_ext
);
816 /* Remove entry from read list */
818 list_del(&priv_cb
->cb_list
);
820 priv_cb
= file_ext
->read_cb
;
821 file_ext
->read_cb
= NULL
;
824 spin_unlock_bh(&dev
->device_lock
);
825 file
->private_data
= NULL
;
826 spin_unlock(&file_ext
->file_lock
);
829 heci_free_cb_private(priv_cb
);
833 spin_lock_bh(&dev
->device_lock
);
835 if (dev
->open_handle_count
> 0)
836 dev
->open_handle_count
--;
838 if (dev
->iamthif_file_object
== file
839 && dev
->iamthif_state
!= HECI_IAMTHIF_IDLE
) {
840 DBG("pthi canceled iamthif state %d\n",
842 dev
->iamthif_canceled
= 1;
843 if (dev
->iamthif_state
== HECI_IAMTHIF_READ_COMPLETE
) {
844 DBG("run next pthi iamthif cb\n");
845 run_next_iamthif_cmd(dev
);
849 if (heci_clear_lists(dev
, file
))
850 dev
->iamthif_state
= HECI_IAMTHIF_IDLE
;
852 spin_unlock_bh(&dev
->device_lock
);
857 static struct heci_cb_private
*find_read_list_entry(
858 struct iamt_heci_device
*dev
,
859 struct heci_file_private
*file_ext
)
861 struct heci_cb_private
*priv_cb_pos
= NULL
;
862 struct heci_cb_private
*priv_cb_next
= NULL
;
863 struct heci_file_private
*file_ext_list_temp
;
865 if (dev
->read_list
.status
== 0
866 && !list_empty(&dev
->read_list
.heci_cb
.cb_list
)) {
867 DBG("remove read_list CB \n");
868 list_for_each_entry_safe(priv_cb_pos
,
870 &dev
->read_list
.heci_cb
.cb_list
, cb_list
) {
872 file_ext_list_temp
= (struct heci_file_private
*)
873 priv_cb_pos
->file_private
;
875 if ((file_ext_list_temp
!= NULL
) &&
876 heci_fe_same_id(file_ext
, file_ext_list_temp
))
885 * heci_read - the read client message function.
887 * @file: pointer to file structure
888 * @ubuf: pointer to user buffer
889 * @length: buffer length
890 * @offset: data offset in buffer
892 * returns >=0 data length on success , <0 on error
894 static ssize_t
heci_read(struct file
*file
, char __user
*ubuf
,
895 size_t length
, loff_t
*offset
)
898 int rets
= 0, err
= 0;
899 int if_num
= iminor(file
->f_dentry
->d_inode
);
900 struct heci_file_private
*file_ext
= file
->private_data
;
901 struct heci_cb_private
*priv_cb_pos
= NULL
;
902 struct heci_cb_private
*priv_cb
= NULL
;
903 struct iamt_heci_device
*dev
;
908 dev
= pci_get_drvdata(heci_device
);
909 if ((if_num
!= HECI_MINOR_NUMBER
) || (!dev
) || (!file_ext
))
912 spin_lock_bh(&dev
->device_lock
);
913 if (dev
->heci_state
!= HECI_ENABLED
) {
914 spin_unlock_bh(&dev
->device_lock
);
917 spin_unlock_bh(&dev
->device_lock
);
919 spin_lock(&file_ext
->file_lock
);
920 if ((file_ext
->sm_state
& HECI_WD_STATE_INDEPENDENCE_MSG_SENT
) == 0) {
921 spin_unlock(&file_ext
->file_lock
);
922 /* Do not allow to read watchdog client */
923 for (i
= 0; i
< dev
->num_heci_me_clients
; i
++) {
924 if (memcmp(&heci_wd_guid
,
925 &dev
->me_clients
[i
].props
.protocol_name
,
926 sizeof(struct guid
)) == 0) {
927 if (file_ext
->me_client_id
==
928 dev
->me_clients
[i
].client_id
)
933 file_ext
->sm_state
&= ~HECI_WD_STATE_INDEPENDENCE_MSG_SENT
;
934 spin_unlock(&file_ext
->file_lock
);
937 if (file_ext
== &dev
->iamthif_file_ext
) {
938 rets
= pthi_read(dev
, if_num
, file
, ubuf
, length
, offset
);
942 if (file_ext
->read_cb
&& file_ext
->read_cb
->information
> *offset
) {
943 priv_cb
= file_ext
->read_cb
;
945 } else if (file_ext
->read_cb
&& file_ext
->read_cb
->information
> 0 &&
946 file_ext
->read_cb
->information
<= *offset
) {
947 priv_cb
= file_ext
->read_cb
;
950 } else if ((!file_ext
->read_cb
|| file_ext
->read_cb
->information
== 0)
952 /*Offset needs to be cleaned for contingous reads*/
958 spin_lock(&file_ext
->read_io_lock
);
959 err
= heci_start_read(dev
, if_num
, file_ext
);
960 if (err
!= 0 && err
!= -EBUSY
) {
961 DBG("heci start read failure with status = %d\n", err
);
962 spin_unlock(&file_ext
->read_io_lock
);
966 if (HECI_READ_COMPLETE
!= file_ext
->reading_state
967 && !waitqueue_active(&file_ext
->rx_wait
)) {
968 if (file
->f_flags
& O_NONBLOCK
) {
970 spin_unlock(&file_ext
->read_io_lock
);
973 spin_unlock(&file_ext
->read_io_lock
);
975 if (wait_event_interruptible(file_ext
->rx_wait
,
976 (HECI_READ_COMPLETE
== file_ext
->reading_state
977 || HECI_FILE_INITIALIZING
== file_ext
->state
978 || HECI_FILE_DISCONNECTED
== file_ext
->state
979 || HECI_FILE_DISCONNECTING
== file_ext
->state
))) {
980 if (signal_pending(current
)) {
987 if (HECI_FILE_INITIALIZING
== file_ext
->state
||
988 HECI_FILE_DISCONNECTED
== file_ext
->state
||
989 HECI_FILE_DISCONNECTING
== file_ext
->state
) {
993 spin_lock(&file_ext
->read_io_lock
);
996 priv_cb
= file_ext
->read_cb
;
999 spin_unlock(&file_ext
->read_io_lock
);
1002 if (file_ext
->reading_state
!= HECI_READ_COMPLETE
) {
1003 spin_unlock(&file_ext
->read_io_lock
);
1006 spin_unlock(&file_ext
->read_io_lock
);
1007 /* now copy the data to user space */
1009 DBG("priv_cb->response_buffer size - %d\n",
1010 priv_cb
->response_buffer
.size
);
1011 DBG("priv_cb->information - %lu\n",
1012 priv_cb
->information
);
1013 if (length
== 0 || ubuf
== NULL
||
1014 *offset
> priv_cb
->information
) {
1019 /* length is being turncated to PAGE_SIZE, however, */
1020 /* information size may be longer */
1021 length
= (length
< (priv_cb
->information
- *offset
) ?
1022 length
: (priv_cb
->information
- *offset
));
1024 if (copy_to_user(ubuf
,
1025 priv_cb
->response_buffer
.data
+ *offset
,
1033 if ((unsigned long)*offset
< priv_cb
->information
)
1037 spin_lock_bh(&dev
->device_lock
);
1038 priv_cb_pos
= find_read_list_entry(dev
, file_ext
);
1039 /* Remove entry from read list */
1040 if (priv_cb_pos
!= NULL
)
1041 list_del(&priv_cb_pos
->cb_list
);
1042 spin_unlock_bh(&dev
->device_lock
);
1043 heci_free_cb_private(priv_cb
);
1044 spin_lock(&file_ext
->read_io_lock
);
1045 file_ext
->reading_state
= HECI_IDLE
;
1046 file_ext
->read_cb
= NULL
;
1047 file_ext
->read_pending
= 0;
1048 spin_unlock(&file_ext
->read_io_lock
);
1049 out
: DBG("end heci read rets= %d\n", rets
);
1054 * heci_write - the write function.
1056 * @file: pointer to file structure
1057 * @ubuf: pointer to user buffer
1058 * @length: buffer length
1059 * @offset: data offset in buffer
1061 * returns >=0 data length on success , <0 on error
1063 static ssize_t
heci_write(struct file
*file
, const char __user
*ubuf
,
1064 size_t length
, loff_t
*offset
)
1068 int if_num
= iminor(file
->f_dentry
->d_inode
);
1069 struct heci_file_private
*file_ext
= file
->private_data
;
1070 struct heci_cb_private
*priv_write_cb
= NULL
;
1071 struct heci_msg_hdr heci_hdr
;
1072 struct iamt_heci_device
*dev
;
1073 unsigned long currtime
= get_seconds();
1078 dev
= pci_get_drvdata(heci_device
);
1080 if ((if_num
!= HECI_MINOR_NUMBER
) || (!dev
) || (!file_ext
))
1083 spin_lock_bh(&dev
->device_lock
);
1085 if (dev
->heci_state
!= HECI_ENABLED
) {
1086 spin_unlock_bh(&dev
->device_lock
);
1089 if (file_ext
== &dev
->iamthif_file_ext
) {
1090 priv_write_cb
= find_pthi_read_list_entry(dev
, file
);
1091 if ((priv_write_cb
!= NULL
) &&
1092 (((currtime
- priv_write_cb
->read_time
) >
1093 IAMTHIF_READ_TIMER
) ||
1094 (file_ext
->reading_state
== HECI_READ_COMPLETE
))) {
1096 list_del(&priv_write_cb
->cb_list
);
1097 heci_free_cb_private(priv_write_cb
);
1098 priv_write_cb
= NULL
;
1102 /* free entry used in read */
1103 if (file_ext
->reading_state
== HECI_READ_COMPLETE
) {
1105 priv_write_cb
= find_read_list_entry(dev
, file_ext
);
1106 if (priv_write_cb
!= NULL
) {
1107 list_del(&priv_write_cb
->cb_list
);
1108 heci_free_cb_private(priv_write_cb
);
1109 priv_write_cb
= NULL
;
1110 spin_lock(&file_ext
->read_io_lock
);
1111 file_ext
->reading_state
= HECI_IDLE
;
1112 file_ext
->read_cb
= NULL
;
1113 file_ext
->read_pending
= 0;
1114 spin_unlock(&file_ext
->read_io_lock
);
1116 } else if (file_ext
->reading_state
== HECI_IDLE
&&
1117 file_ext
->read_pending
== 0)
1120 spin_unlock_bh(&dev
->device_lock
);
1122 priv_write_cb
= kzalloc(sizeof(struct heci_cb_private
), GFP_KERNEL
);
1126 priv_write_cb
->file_object
= file
;
1127 priv_write_cb
->file_private
= file_ext
;
1128 priv_write_cb
->request_buffer
.data
= kmalloc(length
, GFP_KERNEL
);
1129 if (!priv_write_cb
->request_buffer
.data
) {
1130 kfree(priv_write_cb
);
1133 DBG("length =%d\n", (int) length
);
1135 if (copy_from_user(priv_write_cb
->request_buffer
.data
,
1141 spin_lock(&file_ext
->file_lock
);
1142 file_ext
->sm_state
= 0;
1143 if ((length
== 4) &&
1144 ((memcmp(heci_wd_state_independence_msg
[0], ubuf
, 4) == 0) ||
1145 (memcmp(heci_wd_state_independence_msg
[1], ubuf
, 4) == 0) ||
1146 (memcmp(heci_wd_state_independence_msg
[2], ubuf
, 4) == 0)))
1147 file_ext
->sm_state
|= HECI_WD_STATE_INDEPENDENCE_MSG_SENT
;
1148 spin_unlock(&file_ext
->file_lock
);
1150 INIT_LIST_HEAD(&priv_write_cb
->cb_list
);
1151 if (file_ext
== &dev
->iamthif_file_ext
) {
1152 priv_write_cb
->response_buffer
.data
=
1153 kmalloc(IAMTHIF_MTU
, GFP_KERNEL
);
1154 if (!priv_write_cb
->response_buffer
.data
) {
1158 spin_lock_bh(&dev
->device_lock
);
1159 if (dev
->heci_state
!= HECI_ENABLED
) {
1160 spin_unlock_bh(&dev
->device_lock
);
1164 for (i
= 0; i
< dev
->num_heci_me_clients
; i
++) {
1165 if (dev
->me_clients
[i
].client_id
==
1166 dev
->iamthif_file_ext
.me_client_id
)
1170 BUG_ON(dev
->me_clients
[i
].client_id
!= file_ext
->me_client_id
);
1171 if ((i
== dev
->num_heci_me_clients
) ||
1172 (dev
->me_clients
[i
].client_id
!=
1173 dev
->iamthif_file_ext
.me_client_id
)) {
1175 spin_unlock_bh(&dev
->device_lock
);
1178 } else if ((length
> dev
->me_clients
[i
].props
.max_msg_length
)
1180 spin_unlock_bh(&dev
->device_lock
);
1186 priv_write_cb
->response_buffer
.size
= IAMTHIF_MTU
;
1187 priv_write_cb
->major_file_operations
= HECI_IOCTL
;
1188 priv_write_cb
->information
= 0;
1189 priv_write_cb
->request_buffer
.size
= length
;
1190 if (dev
->iamthif_file_ext
.state
!= HECI_FILE_CONNECTED
) {
1191 spin_unlock_bh(&dev
->device_lock
);
1196 if (!list_empty(&dev
->pthi_cmd_list
.heci_cb
.cb_list
)
1197 || dev
->iamthif_state
!= HECI_IAMTHIF_IDLE
) {
1198 DBG("pthi_state = %d\n", (int) dev
->iamthif_state
);
1199 DBG("add PTHI cb to pthi cmd waiting list\n");
1200 list_add_tail(&priv_write_cb
->cb_list
,
1201 &dev
->pthi_cmd_list
.heci_cb
.cb_list
);
1204 DBG("call pthi write\n");
1205 rets
= pthi_write(dev
, priv_write_cb
);
1208 DBG("pthi write failed with status = %d\n",
1210 spin_unlock_bh(&dev
->device_lock
);
1215 spin_unlock_bh(&dev
->device_lock
);
1219 priv_write_cb
->major_file_operations
= HECI_WRITE
;
1220 /* make sure information is zero before we start */
1222 priv_write_cb
->information
= 0;
1223 priv_write_cb
->request_buffer
.size
= length
;
1225 spin_lock(&file_ext
->write_io_lock
);
1226 DBG("host client = %d, ME client = %d\n",
1227 file_ext
->host_client_id
, file_ext
->me_client_id
);
1228 if (file_ext
->state
!= HECI_FILE_CONNECTED
) {
1230 DBG("host client = %d, is not connected to ME client = %d",
1231 file_ext
->host_client_id
,
1232 file_ext
->me_client_id
);
1236 for (i
= 0; i
< dev
->num_heci_me_clients
; i
++) {
1237 if (dev
->me_clients
[i
].client_id
==
1238 file_ext
->me_client_id
)
1241 BUG_ON(dev
->me_clients
[i
].client_id
!= file_ext
->me_client_id
);
1242 if (i
== dev
->num_heci_me_clients
) {
1246 if (length
> dev
->me_clients
[i
].props
.max_msg_length
|| length
<= 0) {
1250 priv_write_cb
->file_private
= file_ext
;
1252 spin_lock_bh(&dev
->device_lock
);
1253 if (flow_ctrl_creds(dev
, file_ext
) &&
1254 dev
->host_buffer_is_empty
) {
1255 spin_unlock_bh(&dev
->device_lock
);
1256 dev
->host_buffer_is_empty
= 0;
1257 if (length
> ((((dev
->host_hw_state
& H_CBD
) >> 24) *
1258 sizeof(__u32
)) - sizeof(struct heci_msg_hdr
))) {
1261 (((dev
->host_hw_state
& H_CBD
) >> 24) *
1263 sizeof(struct heci_msg_hdr
);
1264 heci_hdr
.msg_complete
= 0;
1266 heci_hdr
.length
= length
;
1267 heci_hdr
.msg_complete
= 1;
1269 heci_hdr
.host_addr
= file_ext
->host_client_id
;
1270 heci_hdr
.me_addr
= file_ext
->me_client_id
;
1271 heci_hdr
.reserved
= 0;
1272 DBG("call heci_write_message header=%08x.\n",
1273 *((__u32
*) &heci_hdr
));
1274 spin_unlock(&file_ext
->write_io_lock
);
1275 /* protect heci low level write */
1276 spin_lock_bh(&dev
->device_lock
);
1277 if (!heci_write_message(dev
, &heci_hdr
,
1278 (unsigned char *) (priv_write_cb
->request_buffer
.data
),
1281 spin_unlock_bh(&dev
->device_lock
);
1282 heci_free_cb_private(priv_write_cb
);
1284 priv_write_cb
->information
= 0;
1287 file_ext
->writing_state
= HECI_WRITING
;
1288 priv_write_cb
->information
= heci_hdr
.length
;
1289 if (heci_hdr
.msg_complete
) {
1290 flow_ctrl_reduce(dev
, file_ext
);
1291 list_add_tail(&priv_write_cb
->cb_list
,
1292 &dev
->write_waiting_list
.heci_cb
.cb_list
);
1294 list_add_tail(&priv_write_cb
->cb_list
,
1295 &dev
->write_list
.heci_cb
.cb_list
);
1297 spin_unlock_bh(&dev
->device_lock
);
1301 spin_unlock_bh(&dev
->device_lock
);
1302 priv_write_cb
->information
= 0;
1303 file_ext
->writing_state
= HECI_WRITING
;
1304 spin_unlock(&file_ext
->write_io_lock
);
1305 list_add_tail(&priv_write_cb
->cb_list
,
1306 &dev
->write_list
.heci_cb
.cb_list
);
1311 spin_unlock(&file_ext
->write_io_lock
);
1313 heci_free_cb_private(priv_write_cb
);
1319 * heci_ioctl - the IOCTL function
1321 * @inode: pointer to inode structure
1322 * @file: pointer to file structure
1323 * @cmd: ioctl command
1324 * @data: pointer to heci message structure
1326 * returns 0 on success , <0 on error
1328 static int heci_ioctl(struct inode
*inode
, struct file
*file
,
1329 unsigned int cmd
, unsigned long data
)
1332 int if_num
= iminor(inode
);
1333 struct heci_file_private
*file_ext
= file
->private_data
;
1335 struct heci_message_data
*u_msg
= (struct heci_message_data
*) data
;
1336 struct heci_message_data k_msg
; /* all in kernel on the stack */
1337 struct iamt_heci_device
*dev
;
1339 if (!capable(CAP_SYS_ADMIN
))
1345 dev
= pci_get_drvdata(heci_device
);
1346 if ((if_num
!= HECI_MINOR_NUMBER
) || (!dev
) || (!file_ext
))
1349 spin_lock_bh(&dev
->device_lock
);
1350 if (dev
->heci_state
!= HECI_ENABLED
) {
1351 spin_unlock_bh(&dev
->device_lock
);
1354 spin_unlock_bh(&dev
->device_lock
);
1356 /* first copy from user all data needed */
1357 if (copy_from_user(&k_msg
, u_msg
, sizeof(k_msg
))) {
1358 DBG("first copy from user all data needed filled\n");
1361 DBG("user message size is %d\n", k_msg
.size
);
1364 case IOCTL_HECI_GET_VERSION
:
1365 DBG(": IOCTL_HECI_GET_VERSION\n");
1366 rets
= heci_ioctl_get_version(dev
, if_num
, u_msg
, k_msg
,
1370 case IOCTL_HECI_CONNECT_CLIENT
:
1371 DBG(": IOCTL_HECI_CONNECT_CLIENT.\n");
1372 rets
= heci_ioctl_connect_client(dev
, if_num
, u_msg
, k_msg
,
1377 DBG(": IOCTL_HECI_WD.\n");
1378 rets
= heci_ioctl_wd(dev
, if_num
, k_msg
, file_ext
);
1381 case IOCTL_HECI_BYPASS_WD
:
1382 DBG(": IOCTL_HECI_BYPASS_WD.\n");
1383 rets
= heci_ioctl_bypass_wd(dev
, if_num
, k_msg
, file_ext
);
1394 * heci_poll - the poll function
1396 * @file: pointer to file structure
1397 * @wait: pointer to poll_table structure
1401 static unsigned int heci_poll(struct file
*file
, poll_table
*wait
)
1403 int if_num
= iminor(file
->f_dentry
->d_inode
);
1404 unsigned int mask
= 0;
1405 struct heci_file_private
*file_ext
= file
->private_data
;
1406 struct iamt_heci_device
*dev
;
1411 dev
= pci_get_drvdata(heci_device
);
1413 if ((if_num
!= HECI_MINOR_NUMBER
) || (!dev
) || (!file_ext
))
1416 spin_lock_bh(&dev
->device_lock
);
1417 if (dev
->heci_state
!= HECI_ENABLED
) {
1418 spin_unlock_bh(&dev
->device_lock
);
1421 spin_unlock_bh(&dev
->device_lock
);
1423 if (file_ext
== &dev
->iamthif_file_ext
) {
1424 poll_wait(file
, &dev
->iamthif_file_ext
.wait
, wait
);
1425 spin_lock(&dev
->iamthif_file_ext
.file_lock
);
1426 if (dev
->iamthif_state
== HECI_IAMTHIF_READ_COMPLETE
1427 && dev
->iamthif_file_object
== file
) {
1428 mask
|= (POLLIN
| POLLRDNORM
);
1429 spin_lock_bh(&dev
->device_lock
);
1430 DBG("run next pthi cb\n");
1431 run_next_iamthif_cmd(dev
);
1432 spin_unlock_bh(&dev
->device_lock
);
1434 spin_unlock(&dev
->iamthif_file_ext
.file_lock
);
1437 poll_wait(file
, &file_ext
->tx_wait
, wait
);
1438 spin_lock(&file_ext
->write_io_lock
);
1439 if (HECI_WRITE_COMPLETE
== file_ext
->writing_state
)
1440 mask
|= (POLLIN
| POLLRDNORM
);
1442 spin_unlock(&file_ext
->write_io_lock
);
1449 static int heci_suspend(struct pci_dev
*pdev
, pm_message_t state
)
1451 struct iamt_heci_device
*dev
= pci_get_drvdata(pdev
);
1454 spin_lock_bh(&dev
->device_lock
);
1455 if (dev
->reinit_tsk
!= NULL
) {
1456 kthread_stop(dev
->reinit_tsk
);
1457 dev
->reinit_tsk
= NULL
;
1459 spin_unlock_bh(&dev
->device_lock
);
1461 /* Stop watchdog if exists */
1462 del_timer_sync(&dev
->wd_timer
);
1463 if (dev
->wd_file_ext
.state
== HECI_FILE_CONNECTED
1464 && dev
->wd_timeout
) {
1465 spin_lock_bh(&dev
->device_lock
);
1466 g_sus_wd_timeout
= dev
->wd_timeout
;
1467 dev
->wd_timeout
= 0;
1468 dev
->wd_due_counter
= 0;
1469 memcpy(dev
->wd_data
, heci_stop_wd_params
,
1470 HECI_WD_PARAMS_SIZE
);
1472 if (dev
->host_buffer_is_empty
&&
1473 flow_ctrl_creds(dev
, &dev
->wd_file_ext
)) {
1474 dev
->host_buffer_is_empty
= 0;
1475 if (!heci_send_wd(dev
))
1476 DBG("send stop WD failed\n");
1478 flow_ctrl_reduce(dev
, &dev
->wd_file_ext
);
1480 dev
->wd_pending
= 0;
1482 dev
->wd_pending
= 1;
1484 spin_unlock_bh(&dev
->device_lock
);
1487 err
= wait_event_interruptible_timeout(dev
->wait_stop_wd
,
1490 if (!dev
->wd_stoped
)
1491 DBG("stop wd failed to complete.\n");
1493 DBG("stop wd complete %d.\n", err
);
1497 /* Set new heci state */
1498 spin_lock_bh(&dev
->device_lock
);
1499 if (dev
->heci_state
== HECI_ENABLED
||
1500 dev
->heci_state
== HECI_RECOVERING_FROM_RESET
) {
1501 dev
->heci_state
= HECI_POWER_DOWN
;
1504 spin_unlock_bh(&dev
->device_lock
);
1506 pci_save_state(pdev
);
1508 pci_disable_device(pdev
);
1509 free_irq(pdev
->irq
, dev
);
1511 pci_set_power_state(pdev
, PCI_D3hot
);
1516 static int heci_resume(struct pci_dev
*pdev
)
1518 struct iamt_heci_device
*dev
;
1521 pci_set_power_state(pdev
, PCI_D0
);
1522 pci_restore_state(pdev
);
1524 dev
= pci_get_drvdata(pdev
);
1528 /* request and enable interrupt */
1529 err
= request_irq(pdev
->irq
, heci_isr_interrupt
, IRQF_SHARED
,
1530 heci_driver_name
, dev
);
1532 printk(KERN_ERR
"heci: Request_irq failure. irq = %d \n",
1537 spin_lock_bh(&dev
->device_lock
);
1538 dev
->heci_state
= HECI_POWER_UP
;
1540 spin_unlock_bh(&dev
->device_lock
);
1542 /* Start watchdog if stopped in suspend */
1543 if (g_sus_wd_timeout
!= 0) {
1544 dev
->wd_timeout
= g_sus_wd_timeout
;
1546 memcpy(dev
->wd_data
, heci_start_wd_params
,
1547 HECI_WD_PARAMS_SIZE
);
1548 memcpy(dev
->wd_data
+ HECI_WD_PARAMS_SIZE
,
1549 &dev
->wd_timeout
, sizeof(__u16
));
1550 dev
->wd_due_counter
= 1;
1552 if (dev
->wd_timeout
)
1553 mod_timer(&dev
->wd_timer
, jiffies
);
1555 g_sus_wd_timeout
= 0;
1561 MODULE_AUTHOR("Intel Corporation");
1562 MODULE_DESCRIPTION("Intel(R) Management Engine Interface");
1563 MODULE_LICENSE("Dual BSD/GPL");
1564 MODULE_VERSION(HECI_DRIVER_VERSION
);