OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [misc/] [ibmasm/] [module.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
 
2
/*
3
 * IBM ASM Service Processor Device Driver
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
 *
19
 * Copyright (C) IBM Corporation, 2004
20
 *
21
 * Author: Max Asböck <amax@us.ibm.com>
22
 *
23
 * This driver is based on code originally written by Pete Reynolds
24
 * and others.
25
 *
26
 */
27
 
28
/*
29
 * The ASM device driver does the following things:
30
 *
31
 * 1) When loaded it sends a message to the service processor,
32
 * indicating that an OS is * running. This causes the service processor
33
 * to send periodic heartbeats to the OS.
34
 *
35
 * 2) Answers the periodic heartbeats sent by the service processor.
36
 * Failure to do so would result in system reboot.
37
 *
38
 * 3) Acts as a pass through for dot commands sent from user applications.
39
 * The interface for this is the ibmasmfs file system.
40
 *
41
 * 4) Allows user applications to register for event notification. Events
42
 * are sent to the driver through interrupts. They can be read from user
43
 * space through the ibmasmfs file system.
44
 *
45
 * 5) Allows user space applications to send heartbeats to the service
46
 * processor (aka reverse heartbeats). Again this happens through ibmasmfs.
47
 *
48
 * 6) Handles remote mouse and keyboard event interrupts and makes them
49
 * available to user applications through ibmasmfs.
50
 *
51
 */
52
 
53
#include <linux/pci.h>
54
#include <linux/init.h>
55
#include "ibmasm.h"
56
#include "lowlevel.h"
57
#include "remote.h"
58
 
59
int ibmasm_debug = 0;
60
module_param(ibmasm_debug, int , S_IRUGO | S_IWUSR);
61
MODULE_PARM_DESC(ibmasm_debug, " Set debug mode on or off");
62
 
63
 
64
static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
65
{
66
        int result;
67
        struct service_processor *sp;
68
 
69
        if ((result = pci_enable_device(pdev))) {
70
                dev_err(&pdev->dev, "Failed to enable PCI device\n");
71
                return result;
72
        }
73
        if ((result = pci_request_regions(pdev, DRIVER_NAME))) {
74
                dev_err(&pdev->dev, "Failed to allocate PCI resources\n");
75
                goto error_resources;
76
        }
77
        /* vnc client won't work without bus-mastering */
78
        pci_set_master(pdev);
79
 
80
        sp = kzalloc(sizeof(struct service_processor), GFP_KERNEL);
81
        if (sp == NULL) {
82
                dev_err(&pdev->dev, "Failed to allocate memory\n");
83
                result = -ENOMEM;
84
                goto error_kmalloc;
85
        }
86
 
87
        spin_lock_init(&sp->lock);
88
        INIT_LIST_HEAD(&sp->command_queue);
89
 
90
        pci_set_drvdata(pdev, (void *)sp);
91
        sp->dev = &pdev->dev;
92
        sp->number = pdev->bus->number;
93
        snprintf(sp->dirname, IBMASM_NAME_SIZE, "%d", sp->number);
94
        snprintf(sp->devname, IBMASM_NAME_SIZE, "%s%d", DRIVER_NAME, sp->number);
95
 
96
        if (ibmasm_event_buffer_init(sp)) {
97
                dev_err(sp->dev, "Failed to allocate event buffer\n");
98
                goto error_eventbuffer;
99
        }
100
 
101
        if (ibmasm_heartbeat_init(sp)) {
102
                dev_err(sp->dev, "Failed to allocate heartbeat command\n");
103
                goto error_heartbeat;
104
        }
105
 
106
        sp->irq = pdev->irq;
107
        sp->base_address = ioremap(pci_resource_start(pdev, 0),
108
                                        pci_resource_len(pdev, 0));
109
        if (sp->base_address == 0) {
110
                dev_err(sp->dev, "Failed to ioremap pci memory\n");
111
                result =  -ENODEV;
112
                goto error_ioremap;
113
        }
114
 
115
        result = request_irq(sp->irq, ibmasm_interrupt_handler, IRQF_SHARED, sp->devname, (void*)sp);
116
        if (result) {
117
                dev_err(sp->dev, "Failed to register interrupt handler\n");
118
                goto error_request_irq;
119
        }
120
 
121
        enable_sp_interrupts(sp->base_address);
122
 
123
        result = ibmasm_init_remote_input_dev(sp);
124
        if (result) {
125
                dev_err(sp->dev, "Failed to initialize remote queue\n");
126
                goto error_send_message;
127
        }
128
 
129
        result = ibmasm_send_driver_vpd(sp);
130
        if (result) {
131
                dev_err(sp->dev, "Failed to send driver VPD to service processor\n");
132
                goto error_send_message;
133
        }
134
        result = ibmasm_send_os_state(sp, SYSTEM_STATE_OS_UP);
135
        if (result) {
136
                dev_err(sp->dev, "Failed to send OS state to service processor\n");
137
                goto error_send_message;
138
        }
139
        ibmasmfs_add_sp(sp);
140
 
141
        ibmasm_register_uart(sp);
142
 
143
        return 0;
144
 
145
error_send_message:
146
        disable_sp_interrupts(sp->base_address);
147
        ibmasm_free_remote_input_dev(sp);
148
        free_irq(sp->irq, (void *)sp);
149
error_request_irq:
150
        iounmap(sp->base_address);
151
error_ioremap:
152
        ibmasm_heartbeat_exit(sp);
153
error_heartbeat:
154
        ibmasm_event_buffer_exit(sp);
155
error_eventbuffer:
156
        pci_set_drvdata(pdev, NULL);
157
        kfree(sp);
158
error_kmalloc:
159
        pci_release_regions(pdev);
160
error_resources:
161
        pci_disable_device(pdev);
162
 
163
        return result;
164
}
165
 
166
static void __devexit ibmasm_remove_one(struct pci_dev *pdev)
167
{
168
        struct service_processor *sp = (struct service_processor *)pci_get_drvdata(pdev);
169
 
170
        dbg("Unregistering UART\n");
171
        ibmasm_unregister_uart(sp);
172
        dbg("Sending OS down message\n");
173
        if (ibmasm_send_os_state(sp, SYSTEM_STATE_OS_DOWN))
174
                err("failed to get repsonse to 'Send OS State' command\n");
175
        dbg("Disabling heartbeats\n");
176
        ibmasm_heartbeat_exit(sp);
177
        dbg("Disabling interrupts\n");
178
        disable_sp_interrupts(sp->base_address);
179
        dbg("Freeing SP irq\n");
180
        free_irq(sp->irq, (void *)sp);
181
        dbg("Cleaning up\n");
182
        ibmasm_free_remote_input_dev(sp);
183
        iounmap(sp->base_address);
184
        ibmasm_event_buffer_exit(sp);
185
        pci_set_drvdata(pdev, NULL);
186
        kfree(sp);
187
        pci_release_regions(pdev);
188
        pci_disable_device(pdev);
189
}
190
 
191
static struct pci_device_id ibmasm_pci_table[] =
192
{
193
        { PCI_DEVICE(VENDORID_IBM, DEVICEID_RSA) },
194
        {},
195
};
196
 
197
static struct pci_driver ibmasm_driver = {
198
        .name           = DRIVER_NAME,
199
        .id_table       = ibmasm_pci_table,
200
        .probe          = ibmasm_init_one,
201
        .remove         = __devexit_p(ibmasm_remove_one),
202
};
203
 
204
static void __exit ibmasm_exit (void)
205
{
206
        ibmasm_unregister_panic_notifier();
207
        ibmasmfs_unregister();
208
        pci_unregister_driver(&ibmasm_driver);
209
        info(DRIVER_DESC " version " DRIVER_VERSION " unloaded");
210
}
211
 
212
static int __init ibmasm_init(void)
213
{
214
        int result;
215
 
216
        result = ibmasmfs_register();
217
        if (result) {
218
                err("Failed to register ibmasmfs file system");
219
                return result;
220
        }
221
        result = pci_register_driver(&ibmasm_driver);
222
        if (result) {
223
                ibmasmfs_unregister();
224
                return result;
225
        }
226
        ibmasm_register_panic_notifier();
227
        info(DRIVER_DESC " version " DRIVER_VERSION " loaded");
228
        return 0;
229
}
230
 
231
module_init(ibmasm_init);
232
module_exit(ibmasm_exit);
233
 
234
MODULE_AUTHOR(DRIVER_AUTHOR);
235
MODULE_DESCRIPTION(DRIVER_DESC);
236
MODULE_LICENSE("GPL");
237
MODULE_DEVICE_TABLE(pci, ibmasm_pci_table);
238
 

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.