Merge branch 'for-2.6.31' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
[pandora-kernel.git] / drivers / staging / heci / heci_main.c
1 /*
2  * Part of Intel(R) Manageability Engine Interface Linux driver
3  *
4  * Copyright (c) 2003 - 2008 Intel Corp.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
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.
21  *
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.
25  *
26  * NO WARRANTY
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.
38  *
39  */
40
41
42 #include <linux/module.h>
43 #include <linux/moduleparam.h>
44 #include <linux/kernel.h>
45 #include <linux/slab.h>
46 #include <linux/fs.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>
61
62 #include "heci.h"
63 #include "heci_interface.h"
64 #include "heci_version.h"
65
66
67 #define HECI_READ_TIMEOUT       45
68
69 #define HECI_DRIVER_NAME        "heci"
70
71 /*
72  *  heci driver strings
73  */
74 static char heci_driver_name[] = HECI_DRIVER_NAME;
75 static char heci_driver_string[] = "Intel(R) Management Engine Interface";
76 static char heci_driver_version[] = HECI_DRIVER_VERSION;
77 static char heci_copyright[] = "Copyright (c) 2003 - 2008 Intel Corporation.";
78
79
80 #ifdef HECI_DEBUG
81 int heci_debug = 1;
82 #else
83 int heci_debug;
84 #endif
85 MODULE_PARM_DESC(heci_debug,  "Debug enabled or not");
86 module_param(heci_debug, int, 0644);
87
88
89 #define HECI_DEV_NAME   "heci"
90
91 /* heci char device for registration */
92 static struct cdev heci_cdev;
93
94 /* major number for device */
95 static int heci_major;
96 /* The device pointer */
97 static struct pci_dev *heci_device;
98
99 static struct class *heci_class;
100
101
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 */
129         {0, }
130 };
131
132 MODULE_DEVICE_TABLE(pci, heci_pci_tbl);
133
134 /*
135  * Local Function Prototypes
136  */
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);
154 #ifdef CONFIG_PM
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;
158 #else
159 #define heci_suspend NULL
160 #define heci_resume NULL
161 #endif
162 /*
163  *  PCI driver structure
164  */
165 static struct pci_driver heci_driver = {
166         .name = heci_driver_name,
167         .id_table = heci_pci_tbl,
168         .probe = heci_probe,
169         .remove = __devexit_p(heci_remove),
170         .shutdown = __devexit_p(heci_remove),
171         .suspend = heci_suspend,
172         .resume = heci_resume
173 };
174
175 /*
176  * file operations structure will be use heci char device.
177  */
178 static const struct file_operations heci_fops = {
179         .owner = THIS_MODULE,
180         .read = heci_read,
181         .ioctl = heci_ioctl,
182         .open = heci_open,
183         .release = heci_release,
184         .write = heci_write,
185         .poll = heci_poll,
186 };
187
188 /**
189  * heci_registration_cdev - set up the cdev structure for heci device.
190  *
191  * @dev: char device struct
192  * @hminor: minor number for registration char device
193  * @fops: file operations structure
194  *
195  * returns 0 on success, <0 on failure.
196  */
197 static int heci_registration_cdev(struct cdev *dev, int hminor,
198                                   const struct file_operations *fops)
199 {
200         int ret, devno = MKDEV(heci_major, hminor);
201
202         cdev_init(dev, fops);
203         dev->owner = THIS_MODULE;
204         ret = cdev_add(dev, devno, 1);
205         /* Fail gracefully if need be */
206         if (ret) {
207                 printk(KERN_ERR "heci: Error %d registering heci device %d\n",
208                        ret, hminor);
209         }
210         return ret;
211 }
212
213 /* Display the version of heci driver. */
214 static ssize_t version_show(struct class *dev, char *buf)
215 {
216         return sprintf(buf, "%s %s.\n",
217                        heci_driver_string, heci_driver_version);
218 }
219
220 static CLASS_ATTR(version, S_IRUGO, version_show, NULL);
221
222 /**
223  * heci_register_cdev - registers heci char device
224  *
225  * returns 0 on success, <0 on failure.
226  */
227 static int heci_register_cdev(void)
228 {
229         int ret;
230         dev_t dev;
231
232         /* registration of char devices */
233         ret = alloc_chrdev_region(&dev, HECI_MINORS_BASE, HECI_MINORS_COUNT,
234                                   HECI_DRIVER_NAME);
235         if (ret) {
236                 printk(KERN_ERR "heci: Error allocating char device region.\n");
237                 return ret;
238         }
239
240         heci_major = MAJOR(dev);
241
242         ret = heci_registration_cdev(&heci_cdev, HECI_MINOR_NUMBER,
243                                      &heci_fops);
244         if (ret)
245                 unregister_chrdev_region(MKDEV(heci_major, HECI_MINORS_BASE),
246                                          HECI_MINORS_COUNT);
247
248         return ret;
249 }
250
251 /**
252  * heci_unregister_cdev - unregisters heci char device
253  */
254 static void heci_unregister_cdev(void)
255 {
256         cdev_del(&heci_cdev);
257         unregister_chrdev_region(MKDEV(heci_major, HECI_MINORS_BASE),
258                                  HECI_MINORS_COUNT);
259 }
260
261 #ifndef HECI_DEVICE_CREATE
262 #define HECI_DEVICE_CREATE device_create
263 #endif
264 /**
265  * heci_sysfs_device_create - adds device entry to sysfs
266  *
267  * returns 0 on success, <0 on failure.
268  */
269 static int heci_sysfs_device_create(void)
270 {
271         struct class *class;
272         void *tmphdev;
273         int err = 0;
274
275         class = class_create(THIS_MODULE, HECI_DRIVER_NAME);
276         if (IS_ERR(class)) {
277                 err = PTR_ERR(class);
278                 printk(KERN_ERR "heci: Error creating heci class.\n");
279                 goto err_out;
280         }
281
282         err = class_create_file(class, &class_attr_version);
283         if (err) {
284                 class_destroy(class);
285                 printk(KERN_ERR "heci: Error creating heci class file.\n");
286                 goto err_out;
287         }
288
289         tmphdev = HECI_DEVICE_CREATE(class, NULL, heci_cdev.dev, NULL,
290                                         HECI_DEV_NAME);
291         if (IS_ERR(tmphdev)) {
292                 err = PTR_ERR(tmphdev);
293                 class_remove_file(class, &class_attr_version);
294                 class_destroy(class);
295                 goto err_out;
296         }
297
298         heci_class = class;
299 err_out:
300         return err;
301 }
302
303 /**
304  * heci_sysfs_device_remove - unregisters the device entry on sysfs
305  */
306 static void heci_sysfs_device_remove(void)
307 {
308         if ((heci_class == NULL) || (IS_ERR(heci_class)))
309                 return;
310
311         device_destroy(heci_class, heci_cdev.dev);
312         class_remove_file(heci_class, &class_attr_version);
313         class_destroy(heci_class);
314 }
315
316 /**
317  * heci_init_module - Driver Registration Routine
318  *
319  * heci_init_module is the first routine called when the driver is
320  * loaded. All it does is register with the PCI subsystem.
321  *
322  * returns 0 on success, <0 on failure.
323  */
324 static int __init heci_init_module(void)
325 {
326         int ret = 0;
327
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);
331
332         /* init pci module */
333         ret = pci_register_driver(&heci_driver);
334         if (ret < 0) {
335                 printk(KERN_ERR "heci: Error registering driver.\n");
336                 goto end;
337         }
338
339         ret = heci_register_cdev();
340         if (ret)
341                 goto unregister_pci;
342
343         ret = heci_sysfs_device_create();
344         if (ret)
345                 goto unregister_cdev;
346
347         return ret;
348
349 unregister_cdev:
350         heci_unregister_cdev();
351 unregister_pci:
352         pci_unregister_driver(&heci_driver);
353 end:
354         return ret;
355 }
356
357 module_init(heci_init_module);
358
359
360 /**
361  * heci_exit_module - Driver Exit Cleanup Routine
362  *
363  * heci_exit_module is called just before the driver is removed
364  * from memory.
365  */
366 static void __exit heci_exit_module(void)
367 {
368         pci_unregister_driver(&heci_driver);
369         heci_sysfs_device_remove();
370         heci_unregister_cdev();
371 }
372
373 module_exit(heci_exit_module);
374
375
376 /**
377  * heci_probe - Device Initialization Routine
378  *
379  * @pdev: PCI device information struct
380  * @ent: entry in kcs_pci_tbl
381  *
382  * returns 0 on success, <0 on failure.
383  */
384 static int __devinit heci_probe(struct pci_dev *pdev,
385                                 const struct pci_device_id *ent)
386 {
387         struct iamt_heci_device *dev = NULL;
388         int i, err = 0;
389
390         if (heci_device) {
391                 err = -EEXIST;
392                 goto end;
393         }
394         /* enable pci dev */
395         err = pci_enable_device(pdev);
396         if (err) {
397                 printk(KERN_ERR "heci: Failed to enable pci device.\n");
398                 goto end;
399         }
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);
404         if (err) {
405                 printk(KERN_ERR "heci: Failed to get pci regions.\n");
406                 goto disable_device;
407         }
408         /* allocates and initializes the heci dev structure */
409         dev = init_heci_device(pdev);
410         if (!dev) {
411                 err = -ENOMEM;
412                 goto release_regions;
413         }
414         /* mapping  IO device memory */
415         for (i = 0; i <= 5; i++) {
416                 if (pci_resource_len(pdev, i) == 0)
417                         continue;
418                 if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
419                         printk(KERN_ERR "heci: heci has IO ports.\n");
420                         goto free_device;
421                 } else if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) {
422                         if (dev->mem_base) {
423                                 printk(KERN_ERR
424                                         "heci: Too many mem addresses.\n");
425                                 goto free_device;
426                         }
427                         dev->mem_base = pci_resource_start(pdev, i);
428                         dev->mem_length = pci_resource_len(pdev, i);
429                 }
430         }
431         if (!dev->mem_base) {
432                 printk(KERN_ERR "heci: No address to use.\n");
433                 err = -ENODEV;
434                 goto free_device;
435         }
436         dev->mem_addr = ioremap_nocache(dev->mem_base,
437                         dev->mem_length);
438         if (!dev->mem_addr) {
439                 printk(KERN_ERR "heci: Remap IO device memory failure.\n");
440                 err = -ENOMEM;
441                 goto free_device;
442         }
443         /* request and enable interrupt   */
444         err = request_irq(pdev->irq, heci_isr_interrupt, IRQF_SHARED,
445                         heci_driver_name, dev);
446         if (err) {
447                 printk(KERN_ERR "heci: Request_irq failure. irq = %d \n",
448                        pdev->irq);
449                 goto unmap_memory;
450         }
451
452         if (heci_hw_init(dev)) {
453                 printk(KERN_ERR "heci: Init hw failure.\n");
454                 err = -ENODEV;
455                 goto release_irq;
456         }
457         init_timer(&dev->wd_timer);
458
459         heci_initialize_clients(dev);
460         if (dev->heci_state != HECI_ENABLED) {
461                 err = -ENODEV;
462                 goto release_hw;
463         }
464
465         spin_lock_bh(&dev->device_lock);
466         heci_device = pdev;
467         pci_set_drvdata(pdev, dev);
468         spin_unlock_bh(&dev->device_lock);
469
470         if (dev->wd_timeout)
471                 mod_timer(&dev->wd_timer, jiffies);
472
473 #ifdef CONFIG_PM
474         g_sus_wd_timeout = 0;
475 #endif
476         printk(KERN_INFO "heci driver initialization successful.\n");
477         return 0;
478
479 release_hw:
480         /* disable interrupts */
481         dev->host_hw_state = read_heci_register(dev, H_CSR);
482         heci_csr_disable_interrupts(dev);
483
484         del_timer_sync(&dev->wd_timer);
485
486         flush_scheduled_work();
487
488 release_irq:
489         free_irq(pdev->irq, dev);
490 unmap_memory:
491         if (dev->mem_addr)
492                 iounmap(dev->mem_addr);
493 free_device:
494         kfree(dev);
495 release_regions:
496         pci_release_regions(pdev);
497 disable_device:
498         pci_disable_device(pdev);
499 end:
500         printk(KERN_ERR "heci driver initialization failed.\n");
501         return err;
502 }
503
504 /**
505  * heci_remove - Device Removal Routine
506  *
507  * @pdev: PCI device information struct
508  *
509  * heci_remove is called by the PCI subsystem to alert the driver
510  * that it should release a PCI device.
511  */
512 static void __devexit heci_remove(struct pci_dev *pdev)
513 {
514         struct iamt_heci_device *dev = pci_get_drvdata(pdev);
515
516         if (heci_device != pdev)
517                 return;
518
519         if (dev == NULL)
520                 return;
521
522         spin_lock_bh(&dev->device_lock);
523         if (heci_device != pdev) {
524                 spin_unlock_bh(&dev->device_lock);
525                 return;
526         }
527
528         if (dev->reinit_tsk != NULL) {
529                 kthread_stop(dev->reinit_tsk);
530                 dev->reinit_tsk = NULL;
531         }
532
533         del_timer_sync(&dev->wd_timer);
534         if (dev->wd_file_ext.state == HECI_FILE_CONNECTED
535             && dev->wd_timeout) {
536                 dev->wd_timeout = 0;
537                 dev->wd_due_counter = 0;
538                 memcpy(dev->wd_data, heci_stop_wd_params, HECI_WD_PARAMS_SIZE);
539                 dev->stop = 1;
540                 if (dev->host_buffer_is_empty &&
541                     flow_ctrl_creds(dev, &dev->wd_file_ext)) {
542                         dev->host_buffer_is_empty = 0;
543
544                         if (!heci_send_wd(dev))
545                                 DBG("send stop WD failed\n");
546                         else
547                                 flow_ctrl_reduce(dev, &dev->wd_file_ext);
548
549                         dev->wd_pending = 0;
550                 } else {
551                         dev->wd_pending = 1;
552                 }
553                 dev->wd_stoped = 0;
554                 spin_unlock_bh(&dev->device_lock);
555
556                 wait_event_interruptible_timeout(dev->wait_stop_wd,
557                                 (dev->wd_stoped), 10 * HZ);
558                 spin_lock_bh(&dev->device_lock);
559                 if (!dev->wd_stoped)
560                         DBG("stop wd failed to complete.\n");
561                 else
562                         DBG("stop wd complete.\n");
563
564         }
565
566         heci_device = NULL;
567         spin_unlock_bh(&dev->device_lock);
568
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);
573         }
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,
577                                             &dev->wd_file_ext);
578         }
579
580         spin_lock_bh(&dev->device_lock);
581
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.
585                                           host_client_id);
586         heci_remove_client_from_file_list(dev,
587                         dev->iamthif_file_ext.host_client_id);
588
589         dev->iamthif_current_cb = NULL;
590         dev->iamthif_file_ext.file = NULL;
591         dev->num_heci_me_clients = 0;
592
593         spin_unlock_bh(&dev->device_lock);
594
595         flush_scheduled_work();
596
597         /* disable interrupts */
598         heci_csr_disable_interrupts(dev);
599
600         free_irq(pdev->irq, dev);
601         pci_set_drvdata(pdev, NULL);
602
603         if (dev->mem_addr)
604                 iounmap(dev->mem_addr);
605
606         kfree(dev);
607
608         pci_release_regions(pdev);
609         pci_disable_device(pdev);
610 }
611
612 /**
613  * heci_clear_list - remove all callbacks associated with file
614  *              from heci_cb_list
615  *
616  * @file: file information struct
617  * @heci_cb_list: callbacks list
618  *
619  * heci_clear_list is called to clear resources associated with file
620  * when application calls close function or Ctrl-C was pressed
621  *
622  * returns 1 if callback removed from the list, 0 otherwise
623  */
624 static int heci_clear_list(struct iamt_heci_device *dev,
625                 struct file *file, struct list_head *heci_cb_list)
626 {
627         struct heci_cb_private *priv_cb_pos = NULL;
628         struct heci_cb_private *priv_cb_next = NULL;
629         struct file *file_temp;
630         int rets = 0;
631
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);
646                         }
647                         /* free all allocated buffers */
648                         heci_free_cb_private(priv_cb_pos);
649                         rets = 1;
650                 }
651         }
652         return rets;
653 }
654
655 /**
656  * heci_clear_lists - remove all callbacks associated with file
657  *
658  * @dev: device information struct
659  * @file: file information struct
660  *
661  * heci_clear_lists is called to clear resources associated with file
662  * when application calls close function or Ctrl-C was pressed
663  *
664  * returns 1 if callback removed from the list, 0 otherwise
665  */
666 static int heci_clear_lists(struct iamt_heci_device *dev, struct file *file)
667 {
668         int rets = 0;
669
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))
674                 rets = 1;
675
676         heci_clear_list(dev, file, &dev->ctrl_rd_list.heci_cb.cb_list);
677
678         if (heci_clear_list(dev, file, &dev->ctrl_wr_list.heci_cb.cb_list))
679                 rets = 1;
680
681         if (heci_clear_list(dev, file,
682                             &dev->write_waiting_list.heci_cb.cb_list))
683                 rets = 1;
684
685         if (heci_clear_list(dev, file, &dev->write_list.heci_cb.cb_list))
686                 rets = 1;
687
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) {
692                         /* remove cb */
693                         heci_free_cb_private(dev->iamthif_current_cb);
694                         dev->iamthif_current_cb = NULL;
695                         rets = 1;
696                 }
697         }
698         return rets;
699 }
700
701 /**
702  * heci_open - the open function
703  *
704  * @inode: pointer to inode structure
705  * @file: pointer to file structure
706  *
707  * returns 0 on success, <0 on error
708  */
709 static int heci_open(struct inode *inode, struct file *file)
710 {
711         struct heci_file_private *file_ext;
712         int if_num = iminor(inode);
713         struct iamt_heci_device *dev;
714
715         if (!heci_device)
716                 return -ENODEV;
717
718         dev = pci_get_drvdata(heci_device);
719         if ((if_num != HECI_MINOR_NUMBER) || (!dev))
720                 return -ENODEV;
721
722         file_ext = heci_alloc_file_private(file);
723         if (file_ext == NULL)
724                 return -ENOMEM;
725
726         spin_lock_bh(&dev->device_lock);
727         if (dev->heci_state != HECI_ENABLED) {
728                 spin_unlock_bh(&dev->device_lock);
729                 kfree(file_ext);
730                 return -ENODEV;
731         }
732         if (dev->open_handle_count >= HECI_MAX_OPEN_HANDLE_COUNT) {
733                 spin_unlock_bh(&dev->device_lock);
734                 kfree(file_ext);
735                 return -ENFILE;
736         };
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) {
741
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);
747         }
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         spin_lock_bh(&dev->device_lock);
755         file_ext->state = HECI_FILE_INITIALIZING;
756         spin_unlock_bh(&dev->device_lock);
757         file_ext->sm_state = 0;
758
759         file->private_data = file_ext;
760         spin_unlock(&file_ext->file_lock);
761
762         return 0;
763 }
764
765 /**
766  * heci_release - the release function
767  *
768  * @inode: pointer to inode structure
769  * @file: pointer to file structure
770  *
771  * returns 0 on success, <0 on error
772  */
773 static int heci_release(struct inode *inode, struct file *file)
774 {
775         int rets = 0;
776         int if_num = iminor(inode);
777         struct heci_file_private *file_ext = file->private_data;
778         struct heci_cb_private *priv_cb = NULL;
779         struct iamt_heci_device *dev;
780
781         if (!heci_device)
782                 return -ENODEV;
783
784         dev = pci_get_drvdata(heci_device);
785         if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext))
786                 return -ENODEV;
787
788         if (file_ext != &dev->iamthif_file_ext) {
789                 spin_lock(&file_ext->file_lock);
790                 spin_lock_bh(&dev->device_lock);
791                 if (file_ext->state == HECI_FILE_CONNECTED) {
792                         file_ext->state = HECI_FILE_DISCONNECTING;
793                         spin_unlock_bh(&dev->device_lock);
794                         spin_unlock(&file_ext->file_lock);
795                         DBG("disconnecting client host client = %d, "
796                             "ME client = %d\n",
797                             file_ext->host_client_id,
798                             file_ext->me_client_id);
799                         rets = heci_disconnect_host_client(dev, file_ext);
800                         spin_lock(&file_ext->file_lock);
801                         spin_lock_bh(&dev->device_lock);
802                 }
803                 heci_flush_queues(dev, file_ext);
804                 DBG("remove client host client = %d, ME client = %d\n",
805                     file_ext->host_client_id,
806                     file_ext->me_client_id);
807
808                 if (dev->open_handle_count > 0) {
809                         dev->heci_host_clients[file_ext->host_client_id / 8] &=
810                         ~(1 << (file_ext->host_client_id % 8));
811                         dev->open_handle_count--;
812                 }
813                 heci_remove_client_from_file_list(dev,
814                                 file_ext->host_client_id);
815
816                 /* free read cb */
817                 if (file_ext->read_cb != NULL) {
818                         priv_cb = find_read_list_entry(dev, file_ext);
819                         /* Remove entry from read list */
820                         if (priv_cb != NULL)
821                                 list_del(&priv_cb->cb_list);
822
823                         priv_cb = file_ext->read_cb;
824                         file_ext->read_cb = NULL;
825                 }
826
827                 spin_unlock_bh(&dev->device_lock);
828                 file->private_data = NULL;
829                 spin_unlock(&file_ext->file_lock);
830
831                 if (priv_cb != NULL)
832                         heci_free_cb_private(priv_cb);
833
834                 kfree(file_ext);
835         } else {
836                 spin_lock_bh(&dev->device_lock);
837
838                 if (dev->open_handle_count > 0)
839                         dev->open_handle_count--;
840
841                 if (dev->iamthif_file_object == file
842                     && dev->iamthif_state != HECI_IAMTHIF_IDLE) {
843                         DBG("pthi canceled iamthif state %d\n",
844                             dev->iamthif_state);
845                         dev->iamthif_canceled = 1;
846                         if (dev->iamthif_state == HECI_IAMTHIF_READ_COMPLETE) {
847                                 DBG("run next pthi iamthif cb\n");
848                                 run_next_iamthif_cmd(dev);
849                         }
850                 }
851
852                 if (heci_clear_lists(dev, file))
853                         dev->iamthif_state = HECI_IAMTHIF_IDLE;
854
855                 spin_unlock_bh(&dev->device_lock);
856         }
857         return rets;
858 }
859
860 static struct heci_cb_private *find_read_list_entry(
861                 struct iamt_heci_device *dev,
862                 struct heci_file_private *file_ext)
863 {
864         struct heci_cb_private *priv_cb_pos = NULL;
865         struct heci_cb_private *priv_cb_next = NULL;
866         struct heci_file_private *file_ext_list_temp;
867
868         if (dev->read_list.status == 0
869             && !list_empty(&dev->read_list.heci_cb.cb_list)) {
870                 DBG("remove read_list CB \n");
871                 list_for_each_entry_safe(priv_cb_pos,
872                                 priv_cb_next,
873                                 &dev->read_list.heci_cb.cb_list, cb_list) {
874
875                         file_ext_list_temp = (struct heci_file_private *)
876                                 priv_cb_pos->file_private;
877
878                         if ((file_ext_list_temp != NULL) &&
879                             heci_fe_same_id(file_ext, file_ext_list_temp))
880                                 return priv_cb_pos;
881
882                 }
883         }
884         return NULL;
885 }
886
887 /**
888  * heci_read - the read client message function.
889  *
890  * @file: pointer to file structure
891  * @ubuf: pointer to user buffer
892  * @length: buffer length
893  * @offset: data offset in buffer
894  *
895  * returns >=0 data length on success , <0 on error
896  */
897 static ssize_t heci_read(struct file *file, char __user *ubuf,
898                          size_t length, loff_t *offset)
899 {
900         int i;
901         int rets = 0, err = 0;
902         int if_num = iminor(file->f_dentry->d_inode);
903         struct heci_file_private *file_ext = file->private_data;
904         struct heci_cb_private *priv_cb_pos = NULL;
905         struct heci_cb_private *priv_cb = NULL;
906         struct iamt_heci_device *dev;
907
908         if (!heci_device)
909                 return -ENODEV;
910
911         dev = pci_get_drvdata(heci_device);
912         if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext))
913                 return -ENODEV;
914
915         spin_lock_bh(&dev->device_lock);
916         if (dev->heci_state != HECI_ENABLED) {
917                 spin_unlock_bh(&dev->device_lock);
918                 return -ENODEV;
919         }
920         spin_unlock_bh(&dev->device_lock);
921
922         spin_lock(&file_ext->file_lock);
923         if ((file_ext->sm_state & HECI_WD_STATE_INDEPENDENCE_MSG_SENT) == 0) {
924                 spin_unlock(&file_ext->file_lock);
925                 /* Do not allow to read watchdog client */
926                 for (i = 0; i < dev->num_heci_me_clients; i++) {
927                         if (memcmp(&heci_wd_guid,
928                                    &dev->me_clients[i].props.protocol_name,
929                                    sizeof(struct guid)) == 0) {
930                                 if (file_ext->me_client_id ==
931                                     dev->me_clients[i].client_id)
932                                         return -EBADF;
933                         }
934                 }
935         } else {
936                 file_ext->sm_state &= ~HECI_WD_STATE_INDEPENDENCE_MSG_SENT;
937                 spin_unlock(&file_ext->file_lock);
938         }
939
940         if (file_ext == &dev->iamthif_file_ext) {
941                 rets = pthi_read(dev, if_num, file, ubuf, length, offset);
942                 goto out;
943         }
944
945         if (file_ext->read_cb && file_ext->read_cb->information > *offset) {
946                 priv_cb = file_ext->read_cb;
947                 goto copy_buffer;
948         } else if (file_ext->read_cb && file_ext->read_cb->information > 0 &&
949                    file_ext->read_cb->information <= *offset) {
950                 priv_cb = file_ext->read_cb;
951                 rets = 0;
952                 goto free;
953         } else if ((!file_ext->read_cb || file_ext->read_cb->information == 0)
954                     && *offset > 0) {
955                 /*Offset needs to be cleaned for contingous reads*/
956                 *offset = 0;
957                 rets = 0;
958                 goto out;
959         }
960
961         err = heci_start_read(dev, if_num, file_ext);
962         spin_lock_bh(&file_ext->read_io_lock);
963         if (err != 0 && err != -EBUSY) {
964                 DBG("heci start read failure with status = %d\n", err);
965                 spin_unlock_bh(&file_ext->read_io_lock);
966                 rets = err;
967                 goto out;
968         }
969         if (HECI_READ_COMPLETE != file_ext->reading_state
970                         && !waitqueue_active(&file_ext->rx_wait)) {
971                 if (file->f_flags & O_NONBLOCK) {
972                         rets = -EAGAIN;
973                         spin_unlock_bh(&file_ext->read_io_lock);
974                         goto out;
975                 }
976                 spin_unlock_bh(&file_ext->read_io_lock);
977
978                 if (wait_event_interruptible(file_ext->rx_wait,
979                         (HECI_READ_COMPLETE == file_ext->reading_state
980                          || HECI_FILE_INITIALIZING == file_ext->state
981                          || HECI_FILE_DISCONNECTED == file_ext->state
982                          || HECI_FILE_DISCONNECTING == file_ext->state))) {
983                         if (signal_pending(current)) {
984                                 rets = -EINTR;
985                                 goto out;
986                         }
987                         return -ERESTARTSYS;
988                 }
989
990                 spin_lock_bh(&dev->device_lock);
991                 if (HECI_FILE_INITIALIZING == file_ext->state ||
992                     HECI_FILE_DISCONNECTED == file_ext->state ||
993                     HECI_FILE_DISCONNECTING == file_ext->state) {
994                         spin_unlock_bh(&dev->device_lock);
995                         rets = -EBUSY;
996                         goto out;
997                 }
998                 spin_unlock_bh(&dev->device_lock);
999                 spin_lock_bh(&file_ext->read_io_lock);
1000         }
1001
1002         priv_cb = file_ext->read_cb;
1003
1004         if (!priv_cb) {
1005                 spin_unlock_bh(&file_ext->read_io_lock);
1006                 return -ENODEV;
1007         }
1008         if (file_ext->reading_state != HECI_READ_COMPLETE) {
1009                 spin_unlock_bh(&file_ext->read_io_lock);
1010                 return 0;
1011         }
1012         spin_unlock_bh(&file_ext->read_io_lock);
1013         /* now copy the data to user space */
1014 copy_buffer:
1015         DBG("priv_cb->response_buffer size - %d\n",
1016             priv_cb->response_buffer.size);
1017         DBG("priv_cb->information - %lu\n",
1018             priv_cb->information);
1019         if (length == 0 || ubuf == NULL ||
1020             *offset > priv_cb->information) {
1021                 rets = -EMSGSIZE;
1022                 goto free;
1023         }
1024
1025         /* length is being turncated to PAGE_SIZE, however, */
1026         /* information size may be longer */
1027         length = (length < (priv_cb->information - *offset) ?
1028                         length : (priv_cb->information - *offset));
1029
1030         if (copy_to_user(ubuf,
1031                          priv_cb->response_buffer.data + *offset,
1032                          length)) {
1033                 rets = -EFAULT;
1034                 goto free;
1035         }
1036
1037         rets = length;
1038         *offset += length;
1039         if ((unsigned long)*offset < priv_cb->information)
1040                 goto out;
1041
1042 free:
1043         spin_lock_bh(&dev->device_lock);
1044         priv_cb_pos = find_read_list_entry(dev, file_ext);
1045         /* Remove entry from read list */
1046         if (priv_cb_pos != NULL)
1047                 list_del(&priv_cb_pos->cb_list);
1048         spin_unlock_bh(&dev->device_lock);
1049         heci_free_cb_private(priv_cb);
1050         spin_lock_bh(&file_ext->read_io_lock);
1051         file_ext->reading_state = HECI_IDLE;
1052         file_ext->read_cb = NULL;
1053         file_ext->read_pending = 0;
1054         spin_unlock_bh(&file_ext->read_io_lock);
1055 out:    DBG("end heci read rets= %d\n", rets);
1056         return rets;
1057 }
1058
1059 /**
1060  * heci_write - the write function.
1061  *
1062  * @file: pointer to file structure
1063  * @ubuf: pointer to user buffer
1064  * @length: buffer length
1065  * @offset: data offset in buffer
1066  *
1067  * returns >=0 data length on success , <0 on error
1068  */
1069 static ssize_t heci_write(struct file *file, const char __user *ubuf,
1070                           size_t length, loff_t *offset)
1071 {
1072         int rets = 0;
1073         __u8 i;
1074         int if_num = iminor(file->f_dentry->d_inode);
1075         struct heci_file_private *file_ext = file->private_data;
1076         struct heci_cb_private *priv_write_cb = NULL;
1077         struct heci_msg_hdr heci_hdr;
1078         struct iamt_heci_device *dev;
1079         unsigned long currtime = get_seconds();
1080
1081         if (!heci_device)
1082                 return -ENODEV;
1083
1084         dev = pci_get_drvdata(heci_device);
1085
1086         if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext))
1087                 return -ENODEV;
1088
1089         spin_lock_bh(&dev->device_lock);
1090
1091         if (dev->heci_state != HECI_ENABLED) {
1092                 spin_unlock_bh(&dev->device_lock);
1093                 return -ENODEV;
1094         }
1095         if (file_ext == &dev->iamthif_file_ext) {
1096                 priv_write_cb = find_pthi_read_list_entry(dev, file);
1097                 if ((priv_write_cb != NULL) &&
1098                      (((currtime - priv_write_cb->read_time) >=
1099                             IAMTHIF_READ_TIMER) ||
1100                       (file_ext->reading_state == HECI_READ_COMPLETE))) {
1101                         (*offset) = 0;
1102                         list_del(&priv_write_cb->cb_list);
1103                         heci_free_cb_private(priv_write_cb);
1104                         priv_write_cb = NULL;
1105                 }
1106         }
1107
1108         /* free entry used in read */
1109         if (file_ext->reading_state == HECI_READ_COMPLETE) {
1110                 *offset = 0;
1111                 priv_write_cb = find_read_list_entry(dev, file_ext);
1112                 if (priv_write_cb != NULL) {
1113                         list_del(&priv_write_cb->cb_list);
1114                         heci_free_cb_private(priv_write_cb);
1115                         priv_write_cb = NULL;
1116                         spin_lock_bh(&file_ext->read_io_lock);
1117                         file_ext->reading_state = HECI_IDLE;
1118                         file_ext->read_cb = NULL;
1119                         file_ext->read_pending = 0;
1120                         spin_unlock_bh(&file_ext->read_io_lock);
1121                 }
1122         } else if (file_ext->reading_state == HECI_IDLE &&
1123                         file_ext->read_pending == 0)
1124                 (*offset) = 0;
1125
1126         spin_unlock_bh(&dev->device_lock);
1127
1128         priv_write_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL);
1129         if (!priv_write_cb)
1130                 return -ENOMEM;
1131
1132         priv_write_cb->file_object = file;
1133         priv_write_cb->file_private = file_ext;
1134         priv_write_cb->request_buffer.data = kmalloc(length, GFP_KERNEL);
1135         if (!priv_write_cb->request_buffer.data) {
1136                 kfree(priv_write_cb);
1137                 return -ENOMEM;
1138         }
1139         DBG("length =%d\n", (int) length);
1140
1141         if (copy_from_user(priv_write_cb->request_buffer.data,
1142                 ubuf, length)) {
1143                 rets = -EFAULT;
1144                 goto fail;
1145         }
1146
1147         spin_lock(&file_ext->file_lock);
1148         file_ext->sm_state = 0;
1149         if ((length == 4) &&
1150             ((memcmp(heci_wd_state_independence_msg[0],
1151                                  priv_write_cb->request_buffer.data, 4) == 0) ||
1152              (memcmp(heci_wd_state_independence_msg[1],
1153                                  priv_write_cb->request_buffer.data, 4) == 0) ||
1154              (memcmp(heci_wd_state_independence_msg[2],
1155                                  priv_write_cb->request_buffer.data, 4) == 0)))
1156                 file_ext->sm_state |= HECI_WD_STATE_INDEPENDENCE_MSG_SENT;
1157         spin_unlock(&file_ext->file_lock);
1158
1159         INIT_LIST_HEAD(&priv_write_cb->cb_list);
1160         if (file_ext == &dev->iamthif_file_ext) {
1161                 priv_write_cb->response_buffer.data =
1162                     kmalloc(IAMTHIF_MTU, GFP_KERNEL);
1163                 if (!priv_write_cb->response_buffer.data) {
1164                         rets = -ENOMEM;
1165                         goto fail;
1166                 }
1167                 spin_lock_bh(&dev->device_lock);
1168                 if (dev->heci_state != HECI_ENABLED) {
1169                         spin_unlock_bh(&dev->device_lock);
1170                         rets = -ENODEV;
1171                         goto fail;
1172                 }
1173                 for (i = 0; i < dev->num_heci_me_clients; i++) {
1174                         if (dev->me_clients[i].client_id ==
1175                                 dev->iamthif_file_ext.me_client_id)
1176                                 break;
1177                 }
1178
1179                 BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id);
1180                 if ((i == dev->num_heci_me_clients) ||
1181                     (dev->me_clients[i].client_id !=
1182                       dev->iamthif_file_ext.me_client_id)) {
1183
1184                         spin_unlock_bh(&dev->device_lock);
1185                         rets = -ENODEV;
1186                         goto fail;
1187                 } else if ((length > dev->me_clients[i].props.max_msg_length)
1188                             || (length <= 0)) {
1189                         spin_unlock_bh(&dev->device_lock);
1190                         rets = -EMSGSIZE;
1191                         goto fail;
1192                 }
1193
1194
1195                 priv_write_cb->response_buffer.size = IAMTHIF_MTU;
1196                 priv_write_cb->major_file_operations = HECI_IOCTL;
1197                 priv_write_cb->information = 0;
1198                 priv_write_cb->request_buffer.size = length;
1199                 if (dev->iamthif_file_ext.state != HECI_FILE_CONNECTED) {
1200                         spin_unlock_bh(&dev->device_lock);
1201                         rets = -ENODEV;
1202                         goto fail;
1203                 }
1204
1205                 if (!list_empty(&dev->pthi_cmd_list.heci_cb.cb_list)
1206                                 || dev->iamthif_state != HECI_IAMTHIF_IDLE) {
1207                         DBG("pthi_state = %d\n", (int) dev->iamthif_state);
1208                         DBG("add PTHI cb to pthi cmd waiting list\n");
1209                         list_add_tail(&priv_write_cb->cb_list,
1210                                         &dev->pthi_cmd_list.heci_cb.cb_list);
1211                         rets = length;
1212                 } else {
1213                         DBG("call pthi write\n");
1214                         rets = pthi_write(dev, priv_write_cb);
1215
1216                         if (rets != 0) {
1217                                 DBG("pthi write failed with status = %d\n",
1218                                     rets);
1219                                 spin_unlock_bh(&dev->device_lock);
1220                                 goto fail;
1221                         }
1222                         rets = length;
1223                 }
1224                 spin_unlock_bh(&dev->device_lock);
1225                 return rets;
1226         }
1227
1228         priv_write_cb->major_file_operations = HECI_WRITE;
1229         /* make sure information is zero before we start */
1230
1231         priv_write_cb->information = 0;
1232         priv_write_cb->request_buffer.size = length;
1233
1234         spin_lock(&file_ext->write_io_lock);
1235         spin_lock_bh(&dev->device_lock);
1236         DBG("host client = %d, ME client = %d\n",
1237             file_ext->host_client_id, file_ext->me_client_id);
1238         if (file_ext->state != HECI_FILE_CONNECTED) {
1239                 rets = -ENODEV;
1240                 DBG("host client = %d,  is not connected to ME client = %d",
1241                     file_ext->host_client_id,
1242                     file_ext->me_client_id);
1243                 spin_unlock_bh(&dev->device_lock);
1244                 goto unlock;
1245         }
1246         for (i = 0; i < dev->num_heci_me_clients; i++) {
1247                 if (dev->me_clients[i].client_id ==
1248                     file_ext->me_client_id)
1249                         break;
1250         }
1251         BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id);
1252         if (i == dev->num_heci_me_clients) {
1253                 rets = -ENODEV;
1254                 spin_unlock_bh(&dev->device_lock);
1255                 goto unlock;
1256         }
1257         if (length > dev->me_clients[i].props.max_msg_length || length <= 0) {
1258                 rets = -EINVAL;
1259                 spin_unlock_bh(&dev->device_lock);
1260                 goto unlock;
1261         }
1262         priv_write_cb->file_private = file_ext;
1263
1264         if (flow_ctrl_creds(dev, file_ext) &&
1265                 dev->host_buffer_is_empty) {
1266                 spin_unlock_bh(&dev->device_lock);
1267                 dev->host_buffer_is_empty = 0;
1268                 if (length > ((((dev->host_hw_state & H_CBD) >> 24) *
1269                         sizeof(__u32)) - sizeof(struct heci_msg_hdr))) {
1270
1271                         heci_hdr.length =
1272                                 (((dev->host_hw_state & H_CBD) >> 24) *
1273                                 sizeof(__u32)) -
1274                                 sizeof(struct heci_msg_hdr);
1275                         heci_hdr.msg_complete = 0;
1276                 } else {
1277                         heci_hdr.length = length;
1278                         heci_hdr.msg_complete = 1;
1279                 }
1280                 heci_hdr.host_addr = file_ext->host_client_id;
1281                 heci_hdr.me_addr = file_ext->me_client_id;
1282                 heci_hdr.reserved = 0;
1283                 DBG("call heci_write_message header=%08x.\n",
1284                     *((__u32 *) &heci_hdr));
1285                 spin_unlock(&file_ext->write_io_lock);
1286                 /*  protect heci low level write */
1287                 spin_lock_bh(&dev->device_lock);
1288                 if (!heci_write_message(dev, &heci_hdr,
1289                         (unsigned char *) (priv_write_cb->request_buffer.data),
1290                         heci_hdr.length)) {
1291
1292                         spin_unlock_bh(&dev->device_lock);
1293                         heci_free_cb_private(priv_write_cb);
1294                         rets = -ENODEV;
1295                         priv_write_cb->information = 0;
1296                         return rets;
1297                 }
1298                 file_ext->writing_state = HECI_WRITING;
1299                 priv_write_cb->information = heci_hdr.length;
1300                 if (heci_hdr.msg_complete) {
1301                         flow_ctrl_reduce(dev, file_ext);
1302                         list_add_tail(&priv_write_cb->cb_list,
1303                                       &dev->write_waiting_list.heci_cb.cb_list);
1304                 } else {
1305                         list_add_tail(&priv_write_cb->cb_list,
1306                                       &dev->write_list.heci_cb.cb_list);
1307                 }
1308                 spin_unlock_bh(&dev->device_lock);
1309
1310         } else {
1311
1312                 spin_unlock_bh(&dev->device_lock);
1313                 priv_write_cb->information = 0;
1314                 file_ext->writing_state = HECI_WRITING;
1315                 spin_unlock(&file_ext->write_io_lock);
1316                 list_add_tail(&priv_write_cb->cb_list,
1317                               &dev->write_list.heci_cb.cb_list);
1318         }
1319         return length;
1320
1321 unlock:
1322         spin_unlock(&file_ext->write_io_lock);
1323 fail:
1324         heci_free_cb_private(priv_write_cb);
1325         return rets;
1326
1327 }
1328
1329 /**
1330  * heci_ioctl - the IOCTL function
1331  *
1332  * @inode: pointer to inode structure
1333  * @file: pointer to file structure
1334  * @cmd: ioctl command
1335  * @data: pointer to heci message structure
1336  *
1337  * returns 0 on success , <0 on error
1338  */
1339 static int heci_ioctl(struct inode *inode, struct file *file,
1340                       unsigned int cmd, unsigned long data)
1341 {
1342         int rets = 0;
1343         int if_num = iminor(inode);
1344         struct heci_file_private *file_ext = file->private_data;
1345         /* in user space */
1346         struct heci_message_data __user *u_msg;
1347         struct heci_message_data k_msg; /* all in kernel on the stack */
1348         struct iamt_heci_device *dev;
1349
1350         if (!capable(CAP_SYS_ADMIN))
1351                 return -EPERM;
1352
1353         if (!heci_device)
1354                 return -ENODEV;
1355
1356         dev = pci_get_drvdata(heci_device);
1357         if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext))
1358                 return -ENODEV;
1359
1360         spin_lock_bh(&dev->device_lock);
1361         if (dev->heci_state != HECI_ENABLED) {
1362                 spin_unlock_bh(&dev->device_lock);
1363                 return -ENODEV;
1364         }
1365         spin_unlock_bh(&dev->device_lock);
1366
1367         /* first copy from user all data needed */
1368         u_msg = (struct heci_message_data __user *)data;
1369         if (copy_from_user(&k_msg, u_msg, sizeof(k_msg))) {
1370                 DBG("first copy from user all data needed filled\n");
1371                 return -EFAULT;
1372         }
1373         DBG("user message size is %d\n", k_msg.size);
1374
1375         switch (cmd) {
1376         case IOCTL_HECI_GET_VERSION:
1377                 DBG(": IOCTL_HECI_GET_VERSION\n");
1378                 rets = heci_ioctl_get_version(dev, if_num, u_msg, k_msg,
1379                                               file_ext);
1380                 break;
1381
1382         case IOCTL_HECI_CONNECT_CLIENT:
1383                 DBG(": IOCTL_HECI_CONNECT_CLIENT.\n");
1384                 rets = heci_ioctl_connect_client(dev, if_num, u_msg, k_msg,
1385                                                  file);
1386                 break;
1387
1388         case IOCTL_HECI_WD:
1389                 DBG(": IOCTL_HECI_WD.\n");
1390                 rets = heci_ioctl_wd(dev, if_num, k_msg, file_ext);
1391                 break;
1392
1393         case IOCTL_HECI_BYPASS_WD:
1394                 DBG(": IOCTL_HECI_BYPASS_WD.\n");
1395                 rets = heci_ioctl_bypass_wd(dev, if_num, k_msg, file_ext);
1396                 break;
1397
1398         default:
1399                 rets = -EINVAL;
1400                 break;
1401         }
1402         return rets;
1403 }
1404
1405 /**
1406  * heci_poll - the poll function
1407  *
1408  * @file: pointer to file structure
1409  * @wait: pointer to poll_table structure
1410  *
1411  * returns poll mask
1412  */
1413 static unsigned int heci_poll(struct file *file, poll_table *wait)
1414 {
1415         int if_num = iminor(file->f_dentry->d_inode);
1416         unsigned int mask = 0;
1417         struct heci_file_private *file_ext = file->private_data;
1418         struct iamt_heci_device *dev;
1419
1420         if (!heci_device)
1421                 return mask;
1422
1423         dev = pci_get_drvdata(heci_device);
1424
1425         if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext))
1426                 return mask;
1427
1428         spin_lock_bh(&dev->device_lock);
1429         if (dev->heci_state != HECI_ENABLED) {
1430                 spin_unlock_bh(&dev->device_lock);
1431                 return mask;
1432         }
1433         spin_unlock_bh(&dev->device_lock);
1434
1435         if (file_ext == &dev->iamthif_file_ext) {
1436                 poll_wait(file, &dev->iamthif_file_ext.wait, wait);
1437                 spin_lock(&dev->iamthif_file_ext.file_lock);
1438                 if (dev->iamthif_state == HECI_IAMTHIF_READ_COMPLETE
1439                     && dev->iamthif_file_object == file) {
1440                         mask |= (POLLIN | POLLRDNORM);
1441                         spin_lock_bh(&dev->device_lock);
1442                         DBG("run next pthi cb\n");
1443                         run_next_iamthif_cmd(dev);
1444                         spin_unlock_bh(&dev->device_lock);
1445                 }
1446                 spin_unlock(&dev->iamthif_file_ext.file_lock);
1447
1448         } else{
1449                 poll_wait(file, &file_ext->tx_wait, wait);
1450                 spin_lock(&file_ext->write_io_lock);
1451                 if (HECI_WRITE_COMPLETE == file_ext->writing_state)
1452                         mask |= (POLLIN | POLLRDNORM);
1453
1454                 spin_unlock(&file_ext->write_io_lock);
1455         }
1456
1457         return mask;
1458 }
1459
1460 #ifdef CONFIG_PM
1461 static int heci_suspend(struct pci_dev *pdev, pm_message_t state)
1462 {
1463         struct iamt_heci_device *dev = pci_get_drvdata(pdev);
1464         int err = 0;
1465
1466         spin_lock_bh(&dev->device_lock);
1467         if (dev->reinit_tsk != NULL) {
1468                 kthread_stop(dev->reinit_tsk);
1469                 dev->reinit_tsk = NULL;
1470         }
1471         spin_unlock_bh(&dev->device_lock);
1472
1473         /* Stop watchdog if exists */
1474         del_timer_sync(&dev->wd_timer);
1475         if (dev->wd_file_ext.state == HECI_FILE_CONNECTED
1476             && dev->wd_timeout) {
1477                 spin_lock_bh(&dev->device_lock);
1478                 g_sus_wd_timeout = dev->wd_timeout;
1479                 dev->wd_timeout = 0;
1480                 dev->wd_due_counter = 0;
1481                 memcpy(dev->wd_data, heci_stop_wd_params,
1482                                         HECI_WD_PARAMS_SIZE);
1483                 dev->stop = 1;
1484                 if (dev->host_buffer_is_empty &&
1485                     flow_ctrl_creds(dev, &dev->wd_file_ext)) {
1486                         dev->host_buffer_is_empty = 0;
1487                         if (!heci_send_wd(dev))
1488                                 DBG("send stop WD failed\n");
1489                         else
1490                                 flow_ctrl_reduce(dev, &dev->wd_file_ext);
1491
1492                         dev->wd_pending = 0;
1493                 } else {
1494                         dev->wd_pending = 1;
1495                 }
1496                 spin_unlock_bh(&dev->device_lock);
1497                 dev->wd_stoped = 0;
1498
1499                 err = wait_event_interruptible_timeout(dev->wait_stop_wd,
1500                                                        (dev->wd_stoped),
1501                                                        10 * HZ);
1502                 if (!dev->wd_stoped)
1503                         DBG("stop wd failed to complete.\n");
1504                 else {
1505                         DBG("stop wd complete %d.\n", err);
1506                         err = 0;
1507                 }
1508         }
1509         /* Set new heci state */
1510         spin_lock_bh(&dev->device_lock);
1511         if (dev->heci_state == HECI_ENABLED ||
1512             dev->heci_state == HECI_RECOVERING_FROM_RESET) {
1513                 dev->heci_state = HECI_POWER_DOWN;
1514                 heci_reset(dev, 0);
1515         }
1516         spin_unlock_bh(&dev->device_lock);
1517
1518         pci_save_state(pdev);
1519
1520         pci_disable_device(pdev);
1521         free_irq(pdev->irq, dev);
1522
1523         pci_set_power_state(pdev, PCI_D3hot);
1524
1525         return err;
1526 }
1527
1528 static int heci_resume(struct pci_dev *pdev)
1529 {
1530         struct iamt_heci_device *dev;
1531         int err = 0;
1532
1533         pci_set_power_state(pdev, PCI_D0);
1534         pci_restore_state(pdev);
1535
1536         dev = pci_get_drvdata(pdev);
1537         if (!dev)
1538                 return -ENODEV;
1539
1540         /* request and enable interrupt   */
1541         err = request_irq(pdev->irq, heci_isr_interrupt, IRQF_SHARED,
1542                         heci_driver_name, dev);
1543         if (err) {
1544                 printk(KERN_ERR "heci: Request_irq failure. irq = %d \n",
1545                        pdev->irq);
1546                 return err;
1547         }
1548
1549         spin_lock_bh(&dev->device_lock);
1550         dev->heci_state = HECI_POWER_UP;
1551         heci_reset(dev, 1);
1552         spin_unlock_bh(&dev->device_lock);
1553
1554         /* Start watchdog if stopped in suspend */
1555         if (g_sus_wd_timeout != 0) {
1556                 dev->wd_timeout = g_sus_wd_timeout;
1557
1558                 memcpy(dev->wd_data, heci_start_wd_params,
1559                                         HECI_WD_PARAMS_SIZE);
1560                 memcpy(dev->wd_data + HECI_WD_PARAMS_SIZE,
1561                        &dev->wd_timeout, sizeof(__u16));
1562                 dev->wd_due_counter = 1;
1563
1564                 if (dev->wd_timeout)
1565                         mod_timer(&dev->wd_timer, jiffies);
1566
1567                 g_sus_wd_timeout = 0;
1568         }
1569         return err;
1570 }
1571 #endif
1572
1573 MODULE_AUTHOR("Intel Corporation");
1574 MODULE_DESCRIPTION("Intel(R) Management Engine Interface");
1575 MODULE_LICENSE("Dual BSD/GPL");
1576 MODULE_VERSION(HECI_DRIVER_VERSION);