double unlock
File: drivers/char/ipmi/.tmp_ipmi_si_intf.o.preproc
Full description: {AutomatonChecker of /usr/share/stanse/checkers/AutomatonChecker/kernel_locking_irq.xml} in function 'start_next_msg' double unlock [traces: 1]
Importance: 0
Checker: AutomatonChecker of /usr/share/stanse/checkers/AutomatonChecker/kernel_locking_irq.xml
Trace:
line 794: not affected ==> the lock is still unlocked.
line 795: not affected ==> the lock is still unlocked.
line 795: not affected ==> the lock is still unlocked.
line 795: not affected ==> the lock is still unlocked.
line 795: not affected ==> the lock is still unlocked.
line 796: not affected ==> the lock is still unlocked.
line 258: not affected ==> the lock is still unlocked.
line 259: not affected ==> the lock is still unlocked.
line 259: not affected ==> the lock is still unlocked.
line 263: not affected ==> the lock is still unlocked.
line 263: not affected ==> the lock is still unlocked.
line 264: not affected ==> the lock is still unlocked.
line 269: not affected ==> the lock is still unlocked.
line 269: not affected ==> the lock is still unlocked.
line 270: not affected ==> the lock is still unlocked.
line 271: not affected ==> the lock is still unlocked.
line 299: not affected ==> the lock is still unlocked.
line 299: not affected ==> the lock is still unlocked.
line 300: The lock is unlocked and here is an attempt to unlock it twice.[& . * smi_info msg_lock]
This one is:
False positive index (the lower the better): 0
File contents (this file is distributed under the terms specified in the original file):
1|enum si_intf_state {
2| SI_NORMAL,
3| SI_GETTING_FLAGS,
4| SI_GETTING_EVENTS,
5| SI_CLEARING_FLAGS,
6| SI_CLEARING_FLAGS_THEN_SET_IRQ,
7| SI_GETTING_MESSAGES,
8| SI_ENABLE_INTERRUPTS1,
9| SI_ENABLE_INTERRUPTS2,
10| SI_DISABLE_INTERRUPTS1,
11| SI_DISABLE_INTERRUPTS2
12|
13|};
14|
15|
16|
17|
18|
19|
20|enum si_type {
21| SI_KCS, SI_SMIC, SI_BT
22|};
23|static char *si_to_str[] = { "kcs", "smic", "bt" };
24|
25|enum ipmi_addr_src {
26| SI_INVALID = 0, SI_HOTMOD, SI_HARDCODED, SI_SPMI, SI_ACPI, SI_SMBIOS,
27| SI_PCI, SI_DEVICETREE, SI_DEFAULT
28|};
29|static char *ipmi_addr_src_to_str[] = { ((void *)0), "hotmod", "hardcoded", "SPMI",
30| "ACPI", "SMBIOS", "PCI",
31| "device-tree", "default" };
32|
33|
34|
35|static struct platform_driver ipmi_driver = {
36| .driver = {
37| .name = "ipmi_si",
38| .bus = &platform_bus_type
39| }
40|};
41|
42|
43|
44|
45|
46|enum si_stat_indexes {
47|
48|
49|
50|
51| SI_STAT_short_timeouts = 0,
52|
53|
54|
55|
56|
57| SI_STAT_long_timeouts,
58|
59|
60| SI_STAT_idles,
61|
62|
63| SI_STAT_interrupts,
64|
65|
66| SI_STAT_attentions,
67|
68|
69| SI_STAT_flag_fetches,
70|
71|
72| SI_STAT_hosed_count,
73|
74|
75| SI_STAT_complete_transactions,
76|
77|
78| SI_STAT_events,
79|
80|
81| SI_STAT_watchdog_pretimeouts,
82|
83|
84| SI_STAT_incoming_messages,
85|
86|
87|
88| SI_NUM_STATS
89|};
90|
91|struct smi_info {
92| int intf_num;
93| ipmi_smi_t intf;
94| struct si_sm_data *si_sm;
95| struct si_sm_handlers *handlers;
96| enum si_type si_type;
97| spinlock_t si_lock;
98| spinlock_t msg_lock;
99| struct list_head xmit_msgs;
100| struct list_head hp_xmit_msgs;
101| struct ipmi_smi_msg *curr_msg;
102| enum si_intf_state si_state;
103|
104|
105|
106|
107|
108| struct si_sm_io io;
109| int (*io_setup)(struct smi_info *info);
110| void (*io_cleanup)(struct smi_info *info);
111| int (*irq_setup)(struct smi_info *info);
112| void (*irq_cleanup)(struct smi_info *info);
113| unsigned int io_size;
114| enum ipmi_addr_src addr_source;
115| void (*addr_source_cleanup)(struct smi_info *info);
116| void *addr_source_data;
117|
118|
119|
120|
121|
122|
123| int (*oem_data_avail_handler)(struct smi_info *smi_info);
124| unsigned char msg_flags;
125|
126|
127| char has_event_buffer;
128|
129|
130|
131|
132|
133| atomic_t req_events;
134|
135|
136|
137|
138|
139|
140| int run_to_completion;
141|
142|
143| int port;
144|
145|
146|
147|
148|
149|
150| unsigned int spacing;
151|
152|
153| int irq;
154|
155|
156| struct timer_list si_timer;
157|
158|
159| unsigned long last_timeout_jiffies;
160|
161|
162| atomic_t stop_operation;
163|
164|
165|
166|
167|
168|
169|
170| int interrupt_disabled;
171|
172|
173| struct ipmi_device_id device_id;
174|
175|
176| struct device *dev;
177| struct platform_device *pdev;
178|
179|
180|
181|
182|
183| int dev_registered;
184|
185|
186| unsigned char slave_addr;
187|
188|
189| atomic_t stats[SI_NUM_STATS];
190|
191| struct task_struct *thread;
192|
193| struct list_head link;
194|};
195|static int force_kipmid[4];
196|static int num_force_kipmid;
197|
198|static int pci_registered;
199|
200|
201|static int pnp_registered;
202|
203|
204|
205|
206|
207|static unsigned int kipmid_max_busy_us[4];
208|static int num_max_busy_us;
209|
210|static int unload_when_empty = 1;
211|
212|static int add_smi(struct smi_info *smi);
213|static int try_smi_init(struct smi_info *smi);
214|static void cleanup_one_si(struct smi_info *to_clean);
215|
216|static struct atomic_notifier_head xaction_notifier_list = { .lock = (spinlock_t ) { { .rlock = { .raw_lock = { 0 }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "xaction_notifier_list.lock" } } } }, .head = ((void *)0) };
217|static int register_xaction_notifier(struct notifier_block *nb)
218|{
219| return atomic_notifier_chain_register(&xaction_notifier_list, nb);
220|}
221|
222|static void deliver_recv_msg(struct smi_info *smi_info,
223| struct ipmi_smi_msg *msg)
224|{
225|
226|
227|
228| if (smi_info->run_to_completion) {
229| ipmi_smi_msg_received(smi_info->intf, msg);
230| } else {
231| __st_spin_unlock_st__(&(smi_info->si_lock));
232| ipmi_smi_msg_received(smi_info->intf, msg);
233| __st_spin_lock_st__(&(smi_info->si_lock));
234| }
235|}
236|
237|static void return_hosed_msg(struct smi_info *smi_info, int cCode)
238|{
239| struct ipmi_smi_msg *msg = smi_info->curr_msg;
240|
241| if (cCode < 0 || cCode > 0xff)
242| cCode = 0xff;
243|
244|
245|
246| msg->rsp[0] = msg->data[0] | 4;
247| msg->rsp[1] = msg->data[1];
248| msg->rsp[2] = cCode;
249| msg->rsp_size = 3;
250|
251| smi_info->curr_msg = ((void *)0);
252| deliver_recv_msg(smi_info, msg);
253|}
254|
255|static enum si_sm_result start_next_msg(struct smi_info *smi_info)
256|{
257| int rv;
258| struct list_head *entry = ((void *)0);
|not affected ==> the lock is still unlocked. prev next
259| if (!smi_info->run_to_completion)
|not affected ==> the lock is still unlocked. prev next
260| __st_spin_lock_st__(&(smi_info->msg_lock));
261|
262|
263| if (!list_empty(&(smi_info->hp_xmit_msgs))) {
|not affected ==> the lock is still unlocked. prev next
264| entry = smi_info->hp_xmit_msgs.next;
|not affected ==> the lock is still unlocked. prev next
265| } else if (!list_empty(&(smi_info->xmit_msgs))) {
266| entry = smi_info->xmit_msgs.next;
267| }
268|
269| if (!entry) {
|not affected ==> the lock is still unlocked. prev next
270| smi_info->curr_msg = ((void *)0);
|not affected ==> the lock is still unlocked. prev next
271| rv = SI_SM_IDLE;
|not affected ==> the lock is still unlocked. prev next
272| } else {
273| int err;
274|
275| list_del(entry);
276| smi_info->curr_msg = ({ const typeof( ((struct ipmi_smi_msg *)0)->link ) *__mptr = (entry); (struct ipmi_smi_msg *)( (char *)__mptr - 1 );})
277|
278| ;
279|
280|
281|
282|
283| err = atomic_notifier_call_chain(&xaction_notifier_list,
284| 0, smi_info);
285| if (err & 0x8000) {
286| rv = SI_SM_CALL_WITHOUT_DELAY;
287| goto out;
288| }
289| err = smi_info->handlers->start_transaction(
290| smi_info->si_sm,
291| smi_info->curr_msg->data,
292| smi_info->curr_msg->data_size);
293| if (err)
294| return_hosed_msg(smi_info, err);
295|
296| rv = SI_SM_CALL_WITHOUT_DELAY;
297| }
298| out:
299| if (!smi_info->run_to_completion)
|not affected ==> the lock is still unlocked. prev next
300| __st_spin_unlock_st__(&(smi_info->msg_lock));
|The lock is unlocked and here is an attempt to unlock it twice.[& . * smi_info msg_lock] prev
301|
302| return rv;
303|}
304|
305|static void start_enable_irq(struct smi_info *smi_info)
306|{
307| unsigned char msg[2];
308|
309|
310|
311|
312|
313| msg[0] = (0x06 << 2);
314| msg[1] = 0x2f;
315|
316| smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
317| smi_info->si_state = SI_ENABLE_INTERRUPTS1;
318|}
319|
320|static void start_disable_irq(struct smi_info *smi_info)
321|{
322| unsigned char msg[2];
323|
324| msg[0] = (0x06 << 2);
325| msg[1] = 0x2f;
326|
327| smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
328| smi_info->si_state = SI_DISABLE_INTERRUPTS1;
329|}
330|
331|static void start_clear_flags(struct smi_info *smi_info)
332|{
333| unsigned char msg[3];
334|
335|
336| msg[0] = (0x06 << 2);
337| msg[1] = 0x30;
338| msg[2] = 0x08;
339|
340| smi_info->handlers->start_transaction(smi_info->si_sm, msg, 3);
341| smi_info->si_state = SI_CLEARING_FLAGS;
342|}
343|
344|
345|
346|
347|
348|
349|
350|static inline void disable_si_irq(struct smi_info *smi_info)
351|{
352| if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
353| start_disable_irq(smi_info);
354| smi_info->interrupt_disabled = 1;
355| if (!atomic_read(&smi_info->stop_operation))
356| mod_timer(&smi_info->si_timer,
357| jiffies + (10000/(1000000/250)));
358| }
359|}
360|
361|static inline void enable_si_irq(struct smi_info *smi_info)
362|{
363| if ((smi_info->irq) && (smi_info->interrupt_disabled)) {
364| start_enable_irq(smi_info);
365| smi_info->interrupt_disabled = 0;
366| }
367|}
368|
369|static void handle_flags(struct smi_info *smi_info)
370|{
371| retry:
372| if (smi_info->msg_flags & 0x08) {
373|
374| atomic_inc(&(smi_info)->stats[SI_STAT_watchdog_pretimeouts]);
375|
376| start_clear_flags(smi_info);
377| smi_info->msg_flags &= ~0x08;
378| __st_spin_unlock_st__(&(smi_info->si_lock));
379| ipmi_smi_watchdog_pretimeout(smi_info->intf);
380| __st_spin_lock_st__(&(smi_info->si_lock));
381| } else if (smi_info->msg_flags & 0x01) {
382|
383| smi_info->curr_msg = ipmi_alloc_smi_msg();
384| if (!smi_info->curr_msg) {
385| disable_si_irq(smi_info);
386| smi_info->si_state = SI_NORMAL;
387| return;
388| }
389| enable_si_irq(smi_info);
390|
391| smi_info->curr_msg->data[0] = (0x06 << 2);
392| smi_info->curr_msg->data[1] = 0x33;
393| smi_info->curr_msg->data_size = 2;
394|
395| smi_info->handlers->start_transaction(
396| smi_info->si_sm,
397| smi_info->curr_msg->data,
398| smi_info->curr_msg->data_size);
399| smi_info->si_state = SI_GETTING_MESSAGES;
400| } else if (smi_info->msg_flags & 0x02) {
401|
402| smi_info->curr_msg = ipmi_alloc_smi_msg();
403| if (!smi_info->curr_msg) {
404| disable_si_irq(smi_info);
405| smi_info->si_state = SI_NORMAL;
406| return;
407| }
408| enable_si_irq(smi_info);
409|
410| smi_info->curr_msg->data[0] = (0x06 << 2);
411| smi_info->curr_msg->data[1] = 0x35;
412| smi_info->curr_msg->data_size = 2;
413|
414| smi_info->handlers->start_transaction(
415| smi_info->si_sm,
416| smi_info->curr_msg->data,
417| smi_info->curr_msg->data_size);
418| smi_info->si_state = SI_GETTING_EVENTS;
419| } else if (smi_info->msg_flags & (0x20 | 0x40 | 0x80) &&
420| smi_info->oem_data_avail_handler) {
421| if (smi_info->oem_data_avail_handler(smi_info))
422| goto retry;
423| } else
424| smi_info->si_state = SI_NORMAL;
425|}
426|
427|static void handle_transaction_done(struct smi_info *smi_info)
428|{
429| struct ipmi_smi_msg *msg;
430|
431|
432|
433|
434|
435|
436| switch (smi_info->si_state) {
437| case SI_NORMAL:
438| if (!smi_info->curr_msg)
439| break;
440|
441| smi_info->curr_msg->rsp_size
442| = smi_info->handlers->get_result(
443| smi_info->si_sm,
444| smi_info->curr_msg->rsp,
445| 272);
446|
447|
448|
449|
450|
451|
452| msg = smi_info->curr_msg;
453| smi_info->curr_msg = ((void *)0);
454| deliver_recv_msg(smi_info, msg);
455| break;
456|
457| case SI_GETTING_FLAGS:
458| {
459| unsigned char msg[4];
460| unsigned int len;
461|
462|
463| len = smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
464| if (msg[2] != 0) {
465|
466| smi_info->si_state = SI_NORMAL;
467| } else if (len < 4) {
468|
469|
470|
471|
472| smi_info->si_state = SI_NORMAL;
473| } else {
474| smi_info->msg_flags = msg[3];
475| handle_flags(smi_info);
476| }
477| break;
478| }
479|
480| case SI_CLEARING_FLAGS:
481| case SI_CLEARING_FLAGS_THEN_SET_IRQ:
482| {
483| unsigned char msg[3];
484|
485|
486| smi_info->handlers->get_result(smi_info->si_sm, msg, 3);
487| if (msg[2] != 0) {
488|
489| dev_warn(smi_info->dev,
490| "Error clearing flags: %2.2x\n", msg[2]);
491| }
492| if (smi_info->si_state == SI_CLEARING_FLAGS_THEN_SET_IRQ)
493| start_enable_irq(smi_info);
494| else
495| smi_info->si_state = SI_NORMAL;
496| break;
497| }
498|
499| case SI_GETTING_EVENTS:
500| {
501| smi_info->curr_msg->rsp_size
502| = smi_info->handlers->get_result(
503| smi_info->si_sm,
504| smi_info->curr_msg->rsp,
505| 272);
506|
507|
508|
509|
510|
511|
512| msg = smi_info->curr_msg;
513| smi_info->curr_msg = ((void *)0);
514| if (msg->rsp[2] != 0) {
515|
516| msg->done(msg);
517|
518|
519| smi_info->msg_flags &= ~0x02;
520| handle_flags(smi_info);
521| } else {
522| atomic_inc(&(smi_info)->stats[SI_STAT_events]);
523|
524|
525|
526|
527|
528|
529|
530| handle_flags(smi_info);
531|
532| deliver_recv_msg(smi_info, msg);
533| }
534| break;
535| }
536|
537| case SI_GETTING_MESSAGES:
538| {
539| smi_info->curr_msg->rsp_size
540| = smi_info->handlers->get_result(
541| smi_info->si_sm,
542| smi_info->curr_msg->rsp,
543| 272);
544|
545|
546|
547|
548|
549|
550| msg = smi_info->curr_msg;
551| smi_info->curr_msg = ((void *)0);
552| if (msg->rsp[2] != 0) {
553|
554| msg->done(msg);
555|
556|
557| smi_info->msg_flags &= ~0x01;
558| handle_flags(smi_info);
559| } else {
560| atomic_inc(&(smi_info)->stats[SI_STAT_incoming_messages]);
561|
562|
563|
564|
565|
566|
567|
568| handle_flags(smi_info);
569|
570| deliver_recv_msg(smi_info, msg);
571| }
572| break;
573| }
574|
575| case SI_ENABLE_INTERRUPTS1:
576| {
577| unsigned char msg[4];
578|
579|
580| smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
581| if (msg[2] != 0) {
582| dev_warn(smi_info->dev, "Could not enable interrupts"
583| ", failed get, using polled mode.\n");
584| smi_info->si_state = SI_NORMAL;
585| } else {
586| msg[0] = (0x06 << 2);
587| msg[1] = 0x2e;
588| msg[2] = (msg[3] |
589| 0x01 |
590| 0x02);
591| smi_info->handlers->start_transaction(
592| smi_info->si_sm, msg, 3);
593| smi_info->si_state = SI_ENABLE_INTERRUPTS2;
594| }
595| break;
596| }
597|
598| case SI_ENABLE_INTERRUPTS2:
599| {
600| unsigned char msg[4];
601|
602|
603| smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
604| if (msg[2] != 0)
605| dev_warn(smi_info->dev, "Could not enable interrupts"
606| ", failed set, using polled mode.\n");
607| else
608| smi_info->interrupt_disabled = 0;
609| smi_info->si_state = SI_NORMAL;
610| break;
611| }
612|
613| case SI_DISABLE_INTERRUPTS1:
614| {
615| unsigned char msg[4];
616|
617|
618| smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
619| if (msg[2] != 0) {
620| dev_warn(smi_info->dev, "Could not disable interrupts"
621| ", failed get.\n");
622| smi_info->si_state = SI_NORMAL;
623| } else {
624| msg[0] = (0x06 << 2);
625| msg[1] = 0x2e;
626| msg[2] = (msg[3] &
627| ~(0x01 |
628| 0x02));
629| smi_info->handlers->start_transaction(
630| smi_info->si_sm, msg, 3);
631| smi_info->si_state = SI_DISABLE_INTERRUPTS2;
632| }
633| break;
634| }
635|
636| case SI_DISABLE_INTERRUPTS2:
637| {
638| unsigned char msg[4];
639|
640|
641| smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
642| if (msg[2] != 0) {
643| dev_warn(smi_info->dev, "Could not disable interrupts"
644| ", failed set.\n");
645| }
646| smi_info->si_state = SI_NORMAL;
647| break;
648| }
649| }
650|}
651|
652|
653|
654|
655|
656|
657|static enum si_sm_result smi_event_handler(struct smi_info *smi_info,
658| int time)
659|{
660| enum si_sm_result si_sm_result;
661|
662| restart:
663| si_sm_result = smi_info->handlers->event(smi_info->si_sm, time);
664| time = 0;
665| while (si_sm_result == SI_SM_CALL_WITHOUT_DELAY)
666| si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0);
667|
668| if (si_sm_result == SI_SM_TRANSACTION_COMPLETE) {
669| atomic_inc(&(smi_info)->stats[SI_STAT_complete_transactions]);
670|
671| handle_transaction_done(smi_info);
672| si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0);
673| } else if (si_sm_result == SI_SM_HOSED) {
674| atomic_inc(&(smi_info)->stats[SI_STAT_hosed_count]);
675|
676|
677|
678|
679|
680| smi_info->si_state = SI_NORMAL;
681| if (smi_info->curr_msg != ((void *)0)) {
682|
683|
684|
685|
686|
687| return_hosed_msg(smi_info, 0xff);
688| }
689| si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0);
690| }
691|
692|
693|
694|
695|
696| if (smi_info->intf && si_sm_result == SI_SM_ATTN) {
697| unsigned char msg[2];
698|
699| atomic_inc(&(smi_info)->stats[SI_STAT_attentions]);
700| msg[0] = (0x06 << 2);
701| msg[1] = 0x31;
702|
703| smi_info->handlers->start_transaction(
704| smi_info->si_sm, msg, 2);
705| smi_info->si_state = SI_GETTING_FLAGS;
706| goto restart;
707| }
708|
709|
710| if (si_sm_result == SI_SM_IDLE) {
711| atomic_inc(&(smi_info)->stats[SI_STAT_idles]);
712|
713| si_sm_result = start_next_msg(smi_info);
714| if (si_sm_result != SI_SM_IDLE)
715| goto restart;
716| }
717|
718| if ((si_sm_result == SI_SM_IDLE)
719| && (atomic_read(&smi_info->req_events))) {
720|
721|
722|
723|
724| atomic_set(&smi_info->req_events, 0);
725|
726| smi_info->curr_msg = ipmi_alloc_smi_msg();
727| if (!smi_info->curr_msg)
728| goto out;
729|
730| smi_info->curr_msg->data[0] = (0x06 << 2);
731| smi_info->curr_msg->data[1] = 0x35;
732| smi_info->curr_msg->data_size = 2;
733|
734| smi_info->handlers->start_transaction(
735| smi_info->si_sm,
736| smi_info->curr_msg->data,
737| smi_info->curr_msg->data_size);
738| smi_info->si_state = SI_GETTING_EVENTS;
739| goto restart;
740| }
741| out:
742| return si_sm_result;
743|}
744|
745|static void sender(void *send_info,
746| struct ipmi_smi_msg *msg,
747| int priority)
748|{
749| struct smi_info *smi_info = send_info;
750| enum si_sm_result result;
751| unsigned long flags;
752|
753|
754|
755|
756| if (atomic_read(&smi_info->stop_operation)) {
757| msg->rsp[0] = msg->data[0] | 4;
758| msg->rsp[1] = msg->data[1];
759| msg->rsp[2] = 0xff;
760| msg->rsp_size = 3;
761| deliver_recv_msg(smi_info, msg);
762| return;
763| }
764|
765|
766|
767|
768|
769|
770| mod_timer(&smi_info->si_timer, jiffies + (10000/(1000000/250)));
771|
772| if (smi_info->thread)
773| wake_up_process(smi_info->thread);
774|
775| if (smi_info->run_to_completion) {
776| list_add_tail(&(msg->link), &(smi_info->xmit_msgs));
777|
778| result = smi_event_handler(smi_info, 0);
779| while (result != SI_SM_IDLE) {
780| (__builtin_constant_p(250) ? ((250) > 20000 ? __bad_udelay() : __const_udelay((250) * 0x10c7ul)) : __udelay(250));
781| result = smi_event_handler(smi_info,
782| 250);
783| }
784| return;
785| }
786|
787| __st_spin_lock_irqsave_st__(&smi_info->msg_lock, flags);
788| if (priority > 0)
789| list_add_tail(&msg->link, &smi_info->hp_xmit_msgs);
790| else
791| list_add_tail(&msg->link, &smi_info->xmit_msgs);
792| __st_spin_unlock_irqrestore_st__(&smi_info->msg_lock, flags);
|The lock is unlocked here. next
793|
794| __st_spin_lock_irqsave_st__(&smi_info->si_lock, flags);
|not affected ==> the lock is still unlocked. prev next
795| if (smi_info->si_state == SI_NORMAL && smi_info->curr_msg == ((void *)0))
|not affected ==> the lock is still unlocked. prev next
796| start_next_msg(smi_info);
|not affected ==> the lock is still unlocked. prev next
797| __st_spin_unlock_irqrestore_st__(&smi_info->si_lock, flags);
798|}
799|
800|static void set_run_to_completion(void *send_info, int i_run_to_completion)
801|{
802| struct smi_info *smi_info = send_info;
803| enum si_sm_result result;
804|
805| smi_info->run_to_completion = i_run_to_completion;
806| if (i_run_to_completion) {
807| result = smi_event_handler(smi_info, 0);
808| while (result != SI_SM_IDLE) {
809| (__builtin_constant_p(250) ? ((250) > 20000 ? __bad_udelay() : __const_udelay((250) * 0x10c7ul)) : __udelay(250));
810| result = smi_event_handler(smi_info,
811| 250);
812| }
813| }
814|}
815|
816|
817|
818|
819|
820|
821|static inline void ipmi_si_set_not_busy(struct timespec *ts)
822|{
823| ts->tv_nsec = -1;
824|}
825|static inline int ipmi_si_is_busy(struct timespec *ts)
826|{
827| return ts->tv_nsec != -1;
828|}
829|
830|static int ipmi_thread_busy_wait(enum si_sm_result smi_result,
831| const struct smi_info *smi_info,
832| struct timespec *busy_until)
833|{
834| unsigned int max_busy_us = 0;
835|
836| if (smi_info->intf_num < num_max_busy_us)
837| max_busy_us = kipmid_max_busy_us[smi_info->intf_num];
838| if (max_busy_us == 0 || smi_result != SI_SM_CALL_WITH_DELAY)
839| ipmi_si_set_not_busy(busy_until);
840| else if (!ipmi_si_is_busy(busy_until)) {
841| getnstimeofday(busy_until);
842| timespec_add_ns(busy_until, max_busy_us*1000L);
843| } else {
844| struct timespec now;
845| getnstimeofday(&now);
846| if (timespec_compare(&now, busy_until) > 0) {
847| ipmi_si_set_not_busy(busy_until);
848| return 0;
849| }
850| }
851| return 1;
852|}
853|static int ipmi_thread(void *data)
854|{
855| struct smi_info *smi_info = data;
856| unsigned long flags;
857| enum si_sm_result smi_result;
858| struct timespec busy_until;
859|
860| ipmi_si_set_not_busy(&busy_until);
861| set_user_nice(get_current(), 19);
862| while (!kthread_should_stop()) {
863| int busy_wait;
864|
865| __st_spin_lock_irqsave_st__(&(smi_info->si_lock), flags);
866| smi_result = smi_event_handler(smi_info, 0);
867| __st_spin_unlock_irqrestore_st__(&(smi_info->si_lock), flags);
868| busy_wait = ipmi_thread_busy_wait(smi_result, smi_info,
869| &busy_until);
870| if (smi_result == SI_SM_CALL_WITHOUT_DELAY)
871| ;
872| else if (smi_result == SI_SM_CALL_WITH_DELAY && busy_wait)
873| schedule();
874| else if (smi_result == SI_SM_IDLE)
875| schedule_timeout_interruptible(100);
876| else
877| schedule_timeout_interruptible(1);
878| }
879| return 0;
880|}
881|
882|
883|static void poll(void *send_info)
884|{
885| struct smi_info *smi_info = send_info;
886| unsigned long flags;
887|
888|
889|
890|
891|
892| (__builtin_constant_p(10) ? ((10) > 20000 ? __bad_udelay() : __const_udelay((10) * 0x10c7ul)) : __udelay(10));
893| __st_spin_lock_irqsave_st__(&smi_info->si_lock, flags);
894| smi_event_handler(smi_info, 10);
895| __st_spin_unlock_irqrestore_st__(&smi_info->si_lock, flags);
896|}
897|
898|static void request_events(void *send_info)
899|{
900| struct smi_info *smi_info = send_info;
901|
902| if (atomic_read(&smi_info->stop_operation) ||
903| !smi_info->has_event_buffer)
904| return;
905|
906| atomic_set(&smi_info->req_events, 1);
907|}
908|
909|static int initialized;
910|
911|static void smi_timeout(unsigned long data)
912|{
913| struct smi_info *smi_info = (struct smi_info *) data;
914| enum si_sm_result smi_result;
915| unsigned long flags;
916| unsigned long jiffies_now;
917| long time_diff;
918| long timeout;
919|
920|
921|
922|
923| __st_spin_lock_irqsave_st__(&(smi_info->si_lock), flags);
924|
925|
926|
927|
928| jiffies_now = jiffies;
929| time_diff = (((long)jiffies_now - (long)smi_info->last_timeout_jiffies)
930| * (1000000/250));
931| smi_result = smi_event_handler(smi_info, time_diff);
932|
933| __st_spin_unlock_irqrestore_st__(&(smi_info->si_lock), flags);
934|
935| smi_info->last_timeout_jiffies = jiffies_now;
936|
937| if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
938|
939| timeout = jiffies + (10000/(1000000/250));
940| atomic_inc(&(smi_info)->stats[SI_STAT_long_timeouts]);
941| goto do_mod_timer;
942| }
943|
944|
945|
946|
947|
948| if (smi_result == SI_SM_CALL_WITH_DELAY) {
949| atomic_inc(&(smi_info)->stats[SI_STAT_short_timeouts]);
950| timeout = jiffies + 1;
951| } else {
952| atomic_inc(&(smi_info)->stats[SI_STAT_long_timeouts]);
953| timeout = jiffies + (10000/(1000000/250));
954| }
955|
956| do_mod_timer:
957| if (smi_result != SI_SM_IDLE)
958| mod_timer(&(smi_info->si_timer), timeout);
959|}
960|
961|static irqreturn_t si_irq_handler(int irq, void *data)
962|{
963| struct smi_info *smi_info = data;
964| unsigned long flags;
965|
966|
967|
968|
969| __st_spin_lock_irqsave_st__(&(smi_info->si_lock), flags);
970|
971| atomic_inc(&(smi_info)->stats[SI_STAT_interrupts]);
972|
973|
974|
975|
976|
977| smi_event_handler(smi_info, 0);
978| __st_spin_unlock_irqrestore_st__(&(smi_info->si_lock), flags);
979| return IRQ_HANDLED;
980|}
981|
982|static irqreturn_t si_bt_irq_handler(int irq, void *data)
983|{
984| struct smi_info *smi_info = data;
985|
986| smi_info->io.outputb(&smi_info->io, 2,
987| 2
988| | 1);
989| return si_irq_handler(irq, data);
990|}
991|
992|static int smi_start_processing(void *send_info,
993| ipmi_smi_t intf)
994|{
995| struct smi_info *new_smi = send_info;
996| int enable = 0;
997|
998| new_smi->intf = intf;
999|
1000|
1001| if (new_smi->irq_setup)
1002| new_smi->irq_setup(new_smi);
1003|
1004|
1005| do { static struct lock_class_key __key; setup_timer_key((&new_smi->si_timer), "&new_smi->si_timer", &__key, (smi_timeout), ((long)new_smi)); } while (0);
1006| new_smi->last_timeout_jiffies = jiffies;
1007| mod_timer(&new_smi->si_timer, jiffies + (10000/(1000000/250)));
1008|
1009|
1010|
1011|
1012| if (new_smi->intf_num < num_force_kipmid)
1013| enable = force_kipmid[new_smi->intf_num];
1014|
1015|
1016|
1017|
1018| else if ((new_smi->si_type != SI_BT) && (!new_smi->irq))
1019| enable = 1;
1020|
1021| if (enable) {
1022| new_smi->thread = ({ struct task_struct *__k = kthread_create(ipmi_thread, new_smi, "kipmi%d", new_smi->intf_num); if (!IS_ERR(__k)) wake_up_process(__k); __k; })
1023| ;
1024| if (IS_ERR(new_smi->thread)) {
1025| dev_notice(new_smi->dev, "Could not start"
1026| " kernel thread due to error %ld, only using"
1027| " timers to drive the interface\n",
1028| PTR_ERR(new_smi->thread));
1029| new_smi->thread = ((void *)0);
1030| }
1031| }
1032|
1033| return 0;
1034|}
1035|
1036|static void set_maintenance_mode(void *send_info, int enable)
1037|{
1038| struct smi_info *smi_info = send_info;
1039|
1040| if (!enable)
1041| atomic_set(&smi_info->req_events, 0);
1042|}
1043|
1044|static struct ipmi_smi_handlers handlers = {
1045| .owner = (&__this_module),
1046| .start_processing = smi_start_processing,
1047| .sender = sender,
1048| .request_events = request_events,
1049| .set_maintenance_mode = set_maintenance_mode,
1050| .set_run_to_completion = set_run_to_completion,
1051| .poll = poll,
1052|};
1053|
1054|
1055|
1056|
1057|
1058|
1059|static struct list_head smi_infos = { &(smi_infos), &(smi_infos) };
1060|static struct mutex smi_infos_lock = { .count = { (1) } , .wait_lock = (spinlock_t ) { { .rlock = { .raw_lock = { 0 }, .magic = 0xdead4ead, .owner_cpu = -1, .owner = ((void *)-1L), .dep_map = { .name = "smi_infos_lock.wait_lock" } } } } , .wait_list = { &(smi_infos_lock.wait_list), &(smi_infos_lock.wait_list) } , .magic = &smi_infos_lock , .dep_map = { .name = "smi_infos_lock" } };
1061|static int smi_num;
1062|
1063|
1064|
1065|
1066|static int si_trydefaults = 1;
1067|static char *si_type[4];
1068|
1069|static char si_type_str[30];
1070|static unsigned long addrs[4];
1071|static unsigned int num_addrs;
1072|static unsigned int ports[4];
1073|static unsigned int num_ports;
1074|static int irqs[4];
1075|static unsigned int num_irqs;
1076|static int regspacings[4];
1077|static unsigned int num_regspacings;
1078|static int regsizes[4];
1079|static unsigned int num_regsizes;
1080|static int regshifts[4];
1081|static unsigned int num_regshifts;
1082|static int slave_addrs[4];
1083|static unsigned int num_slave_addrs;
1084|
1085|
1086|
1087|static char *addr_space_to_str[] = { "i/o", "mem" };
1088|
1089|static int hotmod_handler(const char *val, struct kernel_param *kp);
1090|
1091|static struct kernel_param_ops __param_ops_hotmod = { (void *)hotmod_handler, (void *)((void *)0) }; static int __param_perm_check_hotmod = (sizeof(struct { int:-!!(((0200) + sizeof(__check_old_set_param(hotmod_handler))*0) < 0 || ((0200) + sizeof(__check_old_set_param(hotmod_handler))*0) > 0777 || (((0200) + sizeof(__check_old_set_param(hotmod_handler))*0) & 2)); })) + (sizeof(struct { int:-!!(sizeof("") > (64 - sizeof(unsigned long))); })); static const char __param_str_hotmod[] = "hotmod"; static struct kernel_param const __param_hotmod = { __param_str_hotmod, &__param_ops_hotmod, (0200) + sizeof(__check_old_set_param(hotmod_handler))*0, 0 ? 2 : 0, { ((void *)0) } };
1092|static const char
1093|
1094| __mod_hotmod1247
1095| [] = "parm" "=" "hotmod" ":" "Add and remove interfaces. See" " Documentation/IPMI.txt in the kernel sources for the" " gory details."
1096|
1097| ;
1098|
1099|static inline void __check_trydefaults(void) { ((void)(sizeof(struct { int:-!!(!0 && !0 && !0); }))); }; static int __param_perm_check_trydefaults = (sizeof(struct { int:-!!((0) < 0 || (0) > 0777 || ((0) & 2)); })) + (sizeof(struct { int:-!!(sizeof("") > (64 - sizeof(unsigned long))); })); static const char __param_str_trydefaults[] = "trydefaults"; static struct kernel_param const __param_trydefaults = { __param_str_trydefaults, ¶m_ops_bool, 0, 0 ? 2 : 0, { &si_trydefaults } }; static const char __mod_trydefaultstype1249[] = "parmtype" "=" "trydefaults" ":" "bool";
1100|static const char
1101|
1102| __mod_trydefaults1252
1103| [] = "parm" "=" "trydefaults" ":" "Setting this to 'false' will disable the" " default scan of the KCS and SMIC interface at the standard" " address"
1104|
1105| ;
1106|static const struct kparam_string __param_string_type = { 30, si_type_str }; static int __param_perm_check_type = (sizeof(struct { int:-!!((0) < 0 || (0) > 0777 || ((0) & 2)); })) + (sizeof(struct { int:-!!(sizeof("") > (64 - sizeof(unsigned long))); })); static const char __param_str_type[] = "type"; static struct kernel_param const __param_type = { __param_str_type, ¶m_ops_string, 0, 0 ? 2 : 0, { .str = &__param_string_type } }; static const char __mod_typetype1253[] = "parmtype" "=" "type" ":" "string";
1107|static const char
1108|
1109|
1110| __mod_type1257
1111| [] = "parm" "=" "type" ":" "Defines the type of each interface, each" " interface separated by commas. The types are 'kcs'," " 'smic', and 'bt'. For example si_type=kcs,bt will set" " the first interface to kcs and the second to bt"
1112|
1113|
1114| ;
1115|static const struct kparam_array __param_arr_addrs = { (sizeof(addrs) / sizeof((addrs)[0]) + (sizeof(struct { int:-!!(0); }))), &num_addrs, ¶m_ops_ulong, sizeof(addrs[0]), addrs }; static int __param_perm_check_addrs = (sizeof(struct { int:-!!((0) < 0 || (0) > 0777 || ((0) & 2)); })) + (sizeof(struct { int:-!!(sizeof("") > (64 - sizeof(unsigned long))); })); static const char __param_str_addrs[] = "addrs"; static struct kernel_param const __param_addrs = { __param_str_addrs, ¶m_array_ops, 0, 0 ? 2 : 0, { .arr = &__param_arr_addrs } }; static const char __mod_addrstype1258[] = "parmtype" "=" "addrs" ":" "array of " "ulong";
1116|static const char
1117|
1118|
1119| __mod_addrs1262
1120| [] = "parm" "=" "addrs" ":" "Sets the memory address of each interface, the" " addresses separated by commas. Only use if an interface" " is in memory. Otherwise, set it to zero or leave" " it blank."
1121|
1122|
1123| ;
1124|static const struct kparam_array __param_arr_ports = { (sizeof(ports) / sizeof((ports)[0]) + (sizeof(struct { int:-!!(0); }))), &num_ports, ¶m_ops_uint, sizeof(ports[0]), ports }; static int __param_perm_check_ports = (sizeof(struct { int:-!!((0) < 0 || (0) > 0777 || ((0) & 2)); })) + (sizeof(struct { int:-!!(sizeof("") > (64 - sizeof(unsigned long))); })); static const char __param_str_ports[] = "ports"; static struct kernel_param const __param_ports = { __param_str_ports, ¶m_array_ops, 0, 0 ? 2 : 0, { .arr = &__param_arr_ports } }; static const char __mod_portstype1263[] = "parmtype" "=" "ports" ":" "array of " "uint";
1125|static const char
1126|
1127|
1128| __mod_ports1267
1129| [] = "parm" "=" "ports" ":" "Sets the port address of each interface, the" " addresses separated by commas. Only use if an interface" " is a port. Otherwise, set it to zero or leave" " it blank."
1130|
1131|
1132| ;
1133|static const struct kparam_array __param_arr_irqs = { (sizeof(irqs) / sizeof((irqs)[0]) + (sizeof(struct { int:-!!(0); }))), &num_irqs, ¶m_ops_int, sizeof(irqs[0]), irqs }; static int __param_perm_check_irqs = (sizeof(struct { int:-!!((0) < 0 || (0) > 0777 || ((0) & 2)); })) + (sizeof(struct { int:-!!(sizeof("") > (64 - sizeof(unsigned long))); })); static const char __param_str_irqs[] = "irqs"; static struct kernel_param const __param_irqs = { __param_str_irqs, ¶m_array_ops, 0, 0 ? 2 : 0, { .arr = &__param_arr_irqs } }; static const char __mod_irqstype1268[] = "parmtype" "=" "irqs" ":" "array of " "int";
1134|static const char
1135|
1136|
1137| __mod_irqs1272
1138| [] = "parm" "=" "irqs" ":" "Sets the interrupt of each interface, the" " addresses separated by commas. Only use if an interface" " has an interrupt. Otherwise, set it to zero or leave" " it blank."
1139|
1140|
1141| ;
1142|static const struct kparam_array __param_arr_regspacings = { (sizeof(regspacings) / sizeof((regspacings)[0]) + (sizeof(struct { int:-!!(0); }))), &num_regspacings, ¶m_ops_int, sizeof(regspacings[0]), regspacings }; static int __param_perm_check_regspacings = (sizeof(struct { int:-!!((0) < 0 || (0) > 0777 || ((0) & 2)); })) + (sizeof(struct { int:-!!(sizeof("") > (64 - sizeof(unsigned long))); })); static const char __param_str_regspacings[] = "regspacings"; static struct kernel_param const __param_regspacings = { __param_str_regspacings, ¶m_array_ops, 0, 0 ? 2 : 0, { .arr = &__param_arr_regspacings } }; static const char __mod_regspacingstype1273[] = "parmtype" "=" "regspacings" ":" "array of " "int";
1143|static const char
1144|
1145|
1146|
1147| __mod_regspacings1278
1148| [] = "parm" "=" "regspacings" ":" "The number of bytes between the start address" " and each successive register used by the interface. For" " instance, if the start address is 0xca2 and the spacing" " is 2, then the second address is at 0xca4. Defaults" " to 1."
1149|
1150|
1151|
1152| ;
1153|static const struct kparam_array __param_arr_regsizes = { (sizeof(regsizes) / sizeof((regsizes)[0]) + (sizeof(struct { int:-!!(0); }))), &num_regsizes, ¶m_ops_int, sizeof(regsizes[0]), regsizes }; static int __param_perm_check_regsizes = (sizeof(struct { int:-!!((0) < 0 || (0) > 0777 || ((0) & 2)); })) + (sizeof(struct { int:-!!(sizeof("") > (64 - sizeof(unsigned long))); })); static const char __param_str_regsizes[] = "regsizes"; static struct kernel_param const __param_regsizes = { __param_str_regsizes, ¶m_array_ops, 0, 0 ? 2 : 0, { .arr = &__param_arr_regsizes } }; static const char __mod_regsizestype1279[] = "parmtype" "=" "regsizes" ":" "array of " "int";
1154|static const char
1155|
1156|
1157|
1158| __mod_regsizes1284
1159| [] = "parm" "=" "regsizes" ":" "The size of the specific IPMI register in bytes." " This should generally be 1, 2, 4, or 8 for an 8-bit," " 16-bit, 32-bit, or 64-bit register. Use this if you" " the 8-bit IPMI register has to be read from a larger" " register."
1160|
1161|
1162|
1163| ;
1164|static const struct kparam_array __param_arr_regshifts = { (sizeof(regshifts) / sizeof((regshifts)[0]) + (sizeof(struct { int:-!!(0); }))), &num_regshifts, ¶m_ops_int, sizeof(regshifts[0]), regshifts }; static int __param_perm_check_regshifts = (sizeof(struct { int:-!!((0) < 0 || (0) > 0777 || ((0) & 2)); })) + (sizeof(struct { int:-!!(sizeof("") > (64 - sizeof(unsigned long))); })); static const char __param_str_regshifts[] = "regshifts"; static struct kernel_param const __param_regshifts = { __param_str_regshifts, ¶m_array_ops, 0, 0 ? 2 : 0, { .arr = &__param_arr_regshifts } }; static const char __mod_regshiftstype1285[] = "parmtype" "=" "regshifts" ":" "array of " "int";
1165|static const char
1166|
1167|
1168| __mod_regshifts1289
1169| [] = "parm" "=" "regshifts" ":" "The amount to shift the data read from the." " IPMI register, in bits. For instance, if the data" " is read from a 32-bit word and the IPMI data is in" " bit 8-15, then the shift would be 8"
1170|
1171|
1172| ;
1173|static const struct kparam_array __param_arr_slave_addrs = { (sizeof(slave_addrs) / sizeof((slave_addrs)[0]) + (sizeof(struct { int:-!!(0); }))), &num_slave_addrs, ¶m_ops_int, sizeof(slave_addrs[0]), slave_addrs }; static int __param_perm_check_slave_addrs = (sizeof(struct { int:-!!((0) < 0 || (0) > 0777 || ((0) & 2)); })) + (sizeof(struct { int:-!!(sizeof("") > (64 - sizeof(unsigned long))); })); static const char __param_str_slave_addrs[] = "slave_addrs"; static struct kernel_param const __param_slave_addrs = { __param_str_slave_addrs, ¶m_array_ops, 0, 0 ? 2 : 0, { .arr = &__param_arr_slave_addrs } }; static const char __mod_slave_addrstype1290[] = "parmtype" "=" "slave_addrs" ":" "array of " "int";
1174|static const char
1175|
1176|
1177| __mod_slave_addrs1294
1178| [] = "parm" "=" "slave_addrs" ":" "Set the default IPMB slave address for" " the controller. Normally this is 0x20, but can be" " overridden by this parm. This is an array indexed" " by interface number."
1179|
1180|
1181| ;
1182|static const struct kparam_array __param_arr_force_kipmid = { (sizeof(force_kipmid) / sizeof((force_kipmid)[0]) + (sizeof(struct { int:-!!(0); }))), &num_force_kipmid, ¶m_ops_int, sizeof(force_kipmid[0]), force_kipmid }; static int __param_perm_check_force_kipmid = (sizeof(struct { int:-!!((0) < 0 || (0) > 0777 || ((0) & 2)); })) + (sizeof(struct { int:-!!(sizeof("") > (64 - sizeof(unsigned long))); })); static const char __param_str_force_kipmid[] = "force_kipmid"; static struct kernel_param const __param_force_kipmid = { __param_str_force_kipmid, ¶m_array_ops, 0, 0 ? 2 : 0, { .arr = &__param_arr_force_kipmid } }; static const char __mod_force_kipmidtype1295[] = "parmtype" "=" "force_kipmid" ":" "array of " "int";
1183|static const char
1184|
1185| __mod_force_kipmid1298
1186| [] = "parm" "=" "force_kipmid" ":" "Force the kipmi daemon to be enabled (1) or" " disabled(0). Normally the IPMI driver auto-detects" " this, but the value may be overridden by this parm."
1187|
1188| ;
1189|static inline int *__check_unload_when_empty(void) { return(&(unload_when_empty)); }; static int __param_perm_check_unload_when_empty = (sizeof(struct { int:-!!((0) < 0 || (0) > 0777 || ((0) & 2)); })) + (sizeof(struct { int:-!!(sizeof("") > (64 - sizeof(unsigned long))); })); static const char __param_str_unload_when_empty[] = "unload_when_empty"; static struct kernel_param const __param_unload_when_empty = { __param_str_unload_when_empty, ¶m_ops_int, 0, 0 ? 2 : 0, { &unload_when_empty } }; static const char __mod_unload_when_emptytype1299[] = "parmtype" "=" "unload_when_empty" ":" "int";
1190|static const char
1191|
1192| __mod_unload_when_empty1302
1193| [] = "parm" "=" "unload_when_empty" ":" "Unload the module if no interfaces are" " specified or found, default is 1. Setting to 0" " is useful for hot add of devices using hotmod."
1194|
1195| ;
1196|static const struct kparam_array __param_arr_kipmid_max_busy_us = { (sizeof(kipmid_max_busy_us) / sizeof((kipmid_max_busy_us)[0]) + (sizeof(struct { int:-!!(0); }))), &num_max_busy_us, ¶m_ops_uint, sizeof(kipmid_max_busy_us[0]), kipmid_max_busy_us }; static int __param_perm_check_kipmid_max_busy_us = (sizeof(struct { int:-!!((0644) < 0 || (0644) > 0777 || ((0644) & 2)); })) + (sizeof(struct { int:-!!(sizeof("") > (64 - sizeof(unsigned long))); })); static const char __param_str_kipmid_max_busy_us[] = "kipmid_max_busy_us"; static struct kernel_param const __param_kipmid_max_busy_us = { __param_str_kipmid_max_busy_us, ¶m_array_ops, 0644, 0 ? 2 : 0, { .arr = &__param_arr_kipmid_max_busy_us } }; static const char __mod_kipmid_max_busy_ustype1303[] = "parmtype" "=" "kipmid_max_busy_us" ":" "array of " "uint";
1197|static const char
1198|
1199|
1200| __mod_kipmid_max_busy_us1307
1201| [] = "parm" "=" "kipmid_max_busy_us" ":" "Max time (in microseconds) to busy-wait for IPMI data before" " sleeping. 0 (default) means to wait forever. Set to 100-500" " if kipmid is using up a lot of CPU time."
1202|
1203|
1204| ;
1205|
1206|
1207|static void std_irq_cleanup(struct smi_info *info)
1208|{
1209| if (info->si_type == SI_BT)
1210|
1211| info->io.outputb(&info->io, 2, 0);
1212| free_irq(info->irq, info);
1213|}
1214|
1215|static int std_irq_setup(struct smi_info *info)
1216|{
1217| int rv;
1218|
1219| if (!info->irq)
1220| return 0;
1221|
1222| if (info->si_type == SI_BT) {
1223| rv = request_irq(info->irq,
1224| si_bt_irq_handler,
1225| 0x00000080 | 0x00000020,
1226| "ipmi_si",
1227| info);
1228| if (!rv)
1229|
1230| info->io.outputb(&info->io, 2,
1231| 1);
1232| } else
1233| rv = request_irq(info->irq,
1234| si_irq_handler,
1235| 0x00000080 | 0x00000020,
1236| "ipmi_si",
1237| info);
1238| if (rv) {
1239| dev_warn(info->dev, "%s unable to claim interrupt %d,"
1240| " running polled\n",
1241| "ipmi_si", info->irq);
1242| info->irq = 0;
1243| } else {
1244| info->irq_cleanup = std_irq_cleanup;
1245| _dev_info(info->dev, "Using irq %d\n", info->irq);
1246| }
1247|
1248| return rv;
1249|}
1250|
1251|static unsigned char port_inb(struct si_sm_io *io, unsigned int offset)
1252|{
1253| unsigned int addr = io->addr_data;
1254|
1255| return inb(addr + (offset * io->regspacing));
1256|}
1257|
1258|static void port_outb(struct si_sm_io *io, unsigned int offset,
1259| unsigned char b)
1260|{
1261| unsigned int addr = io->addr_data;
1262|
1263| outb(b, addr + (offset * io->regspacing));
1264|}
1265|
1266|static unsigned char port_inw(struct si_sm_io *io, unsigned int offset)
1267|{
1268| unsigned int addr = io->addr_data;
1269|
1270| return (inw(addr + (offset * io->regspacing)) >> io->regshift) & 0xff;
1271|}
1272|
1273|static void port_outw(struct si_sm_io *io, unsigned int offset,
1274| unsigned char b)
1275|{
1276| unsigned int addr = io->addr_data;
1277|
1278| outw(b << io->regshift, addr + (offset * io->regspacing));
1279|}
1280|
1281|static unsigned char port_inl(struct si_sm_io *io, unsigned int offset)
1282|{
1283| unsigned int addr = io->addr_data;
1284|
1285| return (inl(addr + (offset * io->regspacing)) >> io->regshift) & 0xff;
1286|}
1287|
1288|static void port_outl(struct si_sm_io *io, unsigned int offset,
1289| unsigned char b)
1290|{
1291| unsigned int addr = io->addr_data;
1292|
1293| outl(b << io->regshift, addr+(offset * io->regspacing));
1294|}
1295|
1296|static void port_cleanup(struct smi_info *info)
1297|{
1298| unsigned int addr = info->io.addr_data;
1299| int idx;
1300|
1301| if (addr) {
1302| for (idx = 0; idx < info->io_size; idx++)
1303| __release_region(&ioport_resource, (addr + idx * info->io.regspacing), (info->io.regsize))
1304| ;
1305| }
1306|}
1307|
1308|static int port_setup(struct smi_info *info)
1309|{
1310| unsigned int addr = info->io.addr_data;
1311| int idx;
1312|
1313| if (!addr)
1314| return -19;
1315|
1316| info->io_cleanup = port_cleanup;
1317|
1318|
1319|
1320|
1321|
1322| switch (info->io.regsize) {
1323| case 1:
1324| info->io.inputb = port_inb;
1325| info->io.outputb = port_outb;
1326| break;
1327| case 2:
1328| info->io.inputb = port_inw;
1329| info->io.outputb = port_outw;
1330| break;
1331| case 4:
1332| info->io.inputb = port_inl;
1333| info->io.outputb = port_outl;
1334| break;
1335| default:
1336| dev_warn(info->dev, "Invalid register size: %d\n",
1337| info->io.regsize);
1338| return -22;
1339| }
1340|
1341|
1342|
1343|
1344|
1345|
1346|
1347| for (idx = 0; idx < info->io_size; idx++) {
1348| if (__request_region(&ioport_resource, (addr + idx * info->io.regspacing), (info->io.regsize), ("ipmi_si"), 0)
1349| == ((void *)0)) {
1350|
1351| while (idx--) {
1352| __release_region(&ioport_resource, (addr + idx * info->io.regspacing), (info->io.regsize))
1353| ;
1354| }
1355| return -5;
1356| }
1357| }
1358| return 0;
1359|}
1360|
1361|static unsigned char intf_mem_inb(struct si_sm_io *io, unsigned int offset)
1362|{
1363| return readb((io->addr)+(offset * io->regspacing));
1364|}
1365|
1366|static void intf_mem_outb(struct si_sm_io *io, unsigned int offset,
1367| unsigned char b)
1368|{
1369| writeb(b, (io->addr)+(offset * io->regspacing));
1370|}
1371|
1372|static unsigned char intf_mem_inw(struct si_sm_io *io, unsigned int offset)
1373|{
1374| return (readw((io->addr)+(offset * io->regspacing)) >> io->regshift)
1375| & 0xff;
1376|}
1377|
1378|static void intf_mem_outw(struct si_sm_io *io, unsigned int offset,
1379| unsigned char b)
1380|{
1381| writeb(b << io->regshift, (io->addr)+(offset * io->regspacing));
1382|}
1383|
1384|static unsigned char intf_mem_inl(struct si_sm_io *io, unsigned int offset)
1385|{
1386| return (readl((io->addr)+(offset * io->regspacing)) >> io->regshift)
1387| & 0xff;
1388|}
1389|
1390|static void intf_mem_outl(struct si_sm_io *io, unsigned int offset,
1391| unsigned char b)
1392|{
1393| writel(b << io->regshift, (io->addr)+(offset * io->regspacing));
1394|}
1395|
1396|
1397|static unsigned char mem_inq(struct si_sm_io *io, unsigned int offset)
1398|{
1399| return (readq((io->addr)+(offset * io->regspacing)) >> io->regshift)
1400| & 0xff;
1401|}
1402|
1403|static void mem_outq(struct si_sm_io *io, unsigned int offset,
1404| unsigned char b)
1405|{
1406| writeq(b << io->regshift, (io->addr)+(offset * io->regspacing));
1407|}
1408|
1409|
1410|static void mem_cleanup(struct smi_info *info)
1411|{
1412| unsigned long addr = info->io.addr_data;
1413| int mapsize;
1414|
1415| if (info->io.addr) {
1416| iounmap(info->io.addr);
1417|
1418| mapsize = ((info->io_size * info->io.regspacing)
1419| - (info->io.regspacing - info->io.regsize));
1420|
1421| __release_region(&iomem_resource, (addr), (mapsize));
1422| }
1423|}
1424|
1425|static int mem_setup(struct smi_info *info)
1426|{
1427| unsigned long addr = info->io.addr_data;
1428| int mapsize;
1429|
1430| if (!addr)
1431| return -19;
1432|
1433| info->io_cleanup = mem_cleanup;
1434|
1435|
1436|
1437|
1438|
1439| switch (info->io.regsize) {
1440| case 1:
1441| info->io.inputb = intf_mem_inb;
1442| info->io.outputb = intf_mem_outb;
1443| break;
1444| case 2:
1445| info->io.inputb = intf_mem_inw;
1446| info->io.outputb = intf_mem_outw;
1447| break;
1448| case 4:
1449| info->io.inputb = intf_mem_inl;
1450| info->io.outputb = intf_mem_outl;
1451| break;
1452|
1453| case 8:
1454| info->io.inputb = mem_inq;
1455| info->io.outputb = mem_outq;
1456| break;
1457|
1458| default:
1459| dev_warn(info->dev, "Invalid register size: %d\n",
1460| info->io.regsize);
1461| return -22;
1462| }
1463| mapsize = ((info->io_size * info->io.regspacing)
1464| - (info->io.regspacing - info->io.regsize));
1465|
1466| if (__request_region(&iomem_resource, (addr), (mapsize), ("ipmi_si"), 0) == ((void *)0))
1467| return -5;
1468|
1469| info->io.addr = ioremap(addr, mapsize);
1470| if (info->io.addr == ((void *)0)) {
1471| __release_region(&iomem_resource, (addr), (mapsize));
1472| return -5;
1473| }
1474| return 0;
1475|}
1476|enum hotmod_op { HM_ADD, HM_REMOVE };
1477|struct hotmod_vals {
1478| char *name;
1479| int val;
1480|};
1481|static struct hotmod_vals hotmod_ops[] = {
1482| { "add", HM_ADD },
1483| { "remove", HM_REMOVE },
1484| { ((void *)0) }
1485|};
1486|static struct hotmod_vals hotmod_si[] = {
1487| { "kcs", SI_KCS },
1488| { "smic", SI_SMIC },
1489| { "bt", SI_BT },
1490| { ((void *)0) }
1491|};
1492|static struct hotmod_vals hotmod_as[] = {
1493| { "mem", 1 },
1494| { "i/o", 0 },
1495| { ((void *)0) }
1496|};
1497|
1498|static int parse_str(struct hotmod_vals *v, int *val, char *name, char **curr)
1499|{
1500| char *s;
1501| int i;
1502|
1503| s = strchr(*curr, ',');
1504| if (!s) {
1505| printk("<4>" "ipmi_si: " "No hotmod %s given.\n", name);
1506| return -22;
1507| }
1508| *s = '\0';
1509| s++;
1510| for (i = 0; hotmod_ops[i].name; i++) {
1511| if (strcmp(*curr, v[i].name) == 0) {
1512| *val = v[i].val;
1513| *curr = s;
1514| return 0;
1515| }
1516| }
1517|
1518| printk("<4>" "ipmi_si: " "Invalid hotmod %s '%s'\n", name, *curr);
1519| return -22;
1520|}
1521|
1522|static int check_hotmod_int_op(const char *curr, const char *option,
1523| const char *name, int *val)
1524|{
1525| char *n;
1526|
1527| if (strcmp(curr, name) == 0) {
1528| if (!option) {
1529| printk("<4>" "ipmi_si: "
1530| "No option given for '%s'\n",
1531| curr);
1532| return -22;
1533| }
1534| *val = simple_strtoul(option, &n, 0);
1535| if ((*n != '\0') || (*option == '\0')) {
1536| printk("<4>" "ipmi_si: "
1537| "Bad option given for '%s'\n",
1538| curr);
1539| return -22;
1540| }
1541| return 1;
1542| }
1543| return 0;
1544|}
1545|
1546|static struct smi_info *smi_info_alloc(void)
1547|{
1548| struct smi_info *info = kzalloc(sizeof(*info), __st_GFP_KERNEL_st__);
1549|
1550| if (info) {
1551| do { spinlock_check(&info->si_lock); do { static struct lock_class_key __key; __raw_spin_lock_init((&(&info->si_lock)->rlock), "&(&info->si_lock)->rlock", &__key); } while (0); } while (0);
1552| do { spinlock_check(&info->msg_lock); do { static struct lock_class_key __key; __raw_spin_lock_init((&(&info->msg_lock)->rlock), "&(&info->msg_lock)->rlock", &__key); } while (0); } while (0);
1553| }
1554| return info;
1555|}
1556|
1557|static int hotmod_handler(const char *val, struct kernel_param *kp)
1558|{
1559| char *str = kstrdup(val, __st_GFP_KERNEL_st__);
1560| int rv;
1561| char *next, *curr, *s, *n, *o;
1562| enum hotmod_op op;
1563| enum si_type si_type;
1564| int addr_space;
1565| unsigned long addr;
1566| int regspacing;
1567| int regsize;
1568| int regshift;
1569| int irq;
1570| int ipmb;
1571| int ival;
1572| int len;
1573| struct smi_info *info;
1574|
1575| if (!str)
1576| return -12;
1577|
1578|
1579| len = strlen(str);
1580| ival = len - 1;
1581| while ((ival >= 0) && (((_ctype[(int)(unsigned char)(str[ival])])&(0x20)) != 0)) {
1582| str[ival] = '\0';
1583| ival--;
1584| }
1585|
1586| for (curr = str; curr; curr = next) {
1587| regspacing = 1;
1588| regsize = 1;
1589| regshift = 0;
1590| irq = 0;
1591| ipmb = 0;
1592|
1593| next = strchr(curr, ':');
1594| if (next) {
1595| *next = '\0';
1596| next++;
1597| }
1598|
1599| rv = parse_str(hotmod_ops, &ival, "operation", &curr);
1600| if (rv)
1601| break;
1602| op = ival;
1603|
1604| rv = parse_str(hotmod_si, &ival, "interface type", &curr);
1605| if (rv)
1606| break;
1607| si_type = ival;
1608|
1609| rv = parse_str(hotmod_as, &addr_space, "address space", &curr);
1610| if (rv)
1611| break;
1612|
1613| s = strchr(curr, ',');
1614| if (s) {
1615| *s = '\0';
1616| s++;
1617| }
1618| addr = simple_strtoul(curr, &n, 0);
1619| if ((*n != '\0') || (*curr == '\0')) {
1620| printk("<4>" "ipmi_si: " "Invalid hotmod address"
1621| " '%s'\n", curr);
1622| break;
1623| }
1624|
1625| while (s) {
1626| curr = s;
1627| s = strchr(curr, ',');
1628| if (s) {
1629| *s = '\0';
1630| s++;
1631| }
1632| o = strchr(curr, '=');
1633| if (o) {
1634| *o = '\0';
1635| o++;
1636| }
1637| rv = check_hotmod_int_op(curr, o, "rsp", ®spacing);
1638| if (rv < 0)
1639| goto out;
1640| else if (rv)
1641| continue;
1642| rv = check_hotmod_int_op(curr, o, "rsi", ®size);
1643| if (rv < 0)
1644| goto out;
1645| else if (rv)
1646| continue;
1647| rv = check_hotmod_int_op(curr, o, "rsh", ®shift);
1648| if (rv < 0)
1649| goto out;
1650| else if (rv)
1651| continue;
1652| rv = check_hotmod_int_op(curr, o, "irq", &irq);
1653| if (rv < 0)
1654| goto out;
1655| else if (rv)
1656| continue;
1657| rv = check_hotmod_int_op(curr, o, "ipmb", &ipmb);
1658| if (rv < 0)
1659| goto out;
1660| else if (rv)
1661| continue;
1662|
1663| rv = -22;
1664| printk("<4>" "ipmi_si: "
1665| "Invalid hotmod option '%s'\n",
1666| curr);
1667| goto out;
1668| }
1669|
1670| if (op == HM_ADD) {
1671| info = smi_info_alloc();
1672| if (!info) {
1673| rv = -12;
1674| goto out;
1675| }
1676|
1677| info->addr_source = SI_HOTMOD;
1678| info->si_type = si_type;
1679| info->io.addr_data = addr;
1680| info->io.addr_type = addr_space;
1681| if (addr_space == 1)
1682| info->io_setup = mem_setup;
1683| else
1684| info->io_setup = port_setup;
1685|
1686| info->io.addr = ((void *)0);
1687| info->io.regspacing = regspacing;
1688| if (!info->io.regspacing)
1689| info->io.regspacing = 1;
1690| info->io.regsize = regsize;
1691| if (!info->io.regsize)
1692| info->io.regsize = 1;
1693| info->io.regshift = regshift;
1694| info->irq = irq;
1695| if (info->irq)
1696| info->irq_setup = std_irq_setup;
1697| info->slave_addr = ipmb;
1698|
1699| if (!add_smi(info)) {
1700| if (try_smi_init(info))
1701| cleanup_one_si(info);
1702| } else {
1703| kfree(info);
1704| }
1705| } else {
1706|
1707| struct smi_info *e, *tmp_e;
1708|
1709| __st_mutex_lock_st__(&smi_infos_lock);
1710| for (e = ({ const typeof( ((typeof(*e) *)0)->link ) *__mptr = ((&smi_infos)->next); (typeof(*e) *)( (char *)__mptr - 1 );}), tmp_e = ({ const typeof( ((typeof(*e) *)0)->link ) *__mptr = (e->link.next); (typeof(*e) *)( (char *)__mptr - 1 );}); &e->link != (&smi_infos); e = tmp_e, tmp_e = ({ const typeof( ((typeof(*tmp_e) *)0)->link ) *__mptr = (tmp_e->link.next); (typeof(*tmp_e) *)( (char *)__mptr - 1 );})) {
1711| if (e->io.addr_type != addr_space)
1712| continue;
1713| if (e->si_type != si_type)
1714| continue;
1715| if (e->io.addr_data == addr)
1716| cleanup_one_si(e);
1717| }
1718| __st_mutex_unlock_st__(&smi_infos_lock);
1719| }
1720| }
1721| rv = len;
1722| out:
1723| kfree(str);
1724| return rv;
1725|}
1726|
1727|static void hardcode_find_bmc(void)
1728|{
1729| int i;
1730| struct smi_info *info;
1731|
1732| for (i = 0; i < 4; i++) {
1733| if (!ports[i] && !addrs[i])
1734| continue;
1735|
1736| info = smi_info_alloc();
1737| if (!info)
1738| return;
1739|
1740| info->addr_source = SI_HARDCODED;
1741| printk("<6>" "ipmi_si: " "probing via hardcoded address\n");
1742|
1743| if (!si_type[i] || strcmp(si_type[i], "kcs") == 0) {
1744| info->si_type = SI_KCS;
1745| } else if (strcmp(si_type[i], "smic") == 0) {
1746| info->si_type = SI_SMIC;
1747| } else if (strcmp(si_type[i], "bt") == 0) {
1748| info->si_type = SI_BT;
1749| } else {
1750| printk("<4>" "ipmi_si: " "Interface type specified "
1751| "for interface %d, was invalid: %s\n",
1752| i, si_type[i]);
1753| kfree(info);
1754| continue;
1755| }
1756|
1757| if (ports[i]) {
1758|
1759| info->io_setup = port_setup;
1760| info->io.addr_data = ports[i];
1761| info->io.addr_type = 0;
1762| } else if (addrs[i]) {
1763|
1764| info->io_setup = mem_setup;
1765| info->io.addr_data = addrs[i];
1766| info->io.addr_type = 1;
1767| } else {
1768| printk("<4>" "ipmi_si: " "Interface type specified "
1769| "for interface %d, but port and address were "
1770| "not set or set to zero.\n", i);
1771| kfree(info);
1772| continue;
1773| }
1774|
1775| info->io.addr = ((void *)0);
1776| info->io.regspacing = regspacings[i];
1777| if (!info->io.regspacing)
1778| info->io.regspacing = 1;
1779| info->io.regsize = regsizes[i];
1780| if (!info->io.regsize)
1781| info->io.regsize = 1;
1782| info->io.regshift = regshifts[i];
1783| info->irq = irqs[i];
1784| if (info->irq)
1785| info->irq_setup = std_irq_setup;
1786| info->slave_addr = slave_addrs[i];
1787|
1788| if (!add_smi(info)) {
1789| if (try_smi_init(info))
1790| cleanup_one_si(info);
1791| } else {
1792| kfree(info);
1793| }
1794| }
1795|}
1796|
1797|
1798|
1799|
1800|
1801|
1802|typedef unsigned char BOOLEAN;
1803|typedef unsigned char UINT8;
1804|typedef unsigned short UINT16;
1805|typedef unsigned long long UINT64;
1806|typedef long long INT64;
1807|typedef unsigned int UINT32;
1808|typedef int INT32;
1809|
1810|
1811|
1812|typedef s64 acpi_native_int;
1813|
1814|typedef u64 acpi_size;
1815|typedef u64 acpi_io_address;
1816|typedef u64 acpi_physical_address;
1817|typedef u32 acpi_status;
1818|typedef u32 acpi_name;
1819|typedef char *acpi_string;
1820|typedef void *acpi_handle;
1821|
1822|
1823|
1824|typedef u8 acpi_owner_id;
1825|typedef u64 acpi_integer;
1826|typedef u32 acpi_object_type;
1827|typedef u32 acpi_event_type;
1828|typedef u32 acpi_event_status;
1829|typedef u8 acpi_adr_space_type;
1830|union acpi_object {
1831| acpi_object_type type;
1832| struct {
1833| acpi_object_type type;
1834| u64 value;
1835| } integer;
1836|
1837| struct {
1838| acpi_object_type type;
1839| u32 length;
1840| char *pointer;
1841| } string;
1842|
1843| struct {
1844| acpi_object_type type;
1845| u32 length;
1846| u8 *pointer;
1847| } buffer;
1848|
1849| struct {
1850| acpi_object_type type;
1851| u32 count;
1852| union acpi_object *elements;
1853| } package;
1854|
1855| struct {
1856| acpi_object_type type;
1857| acpi_object_type actual_type;
1858| acpi_handle handle;
1859| } reference;
1860|
1861| struct {
1862| acpi_object_type type;
1863| u32 proc_id;
1864| acpi_io_address pblk_address;
1865| u32 pblk_length;
1866| } processor;
1867|
1868| struct {
1869| acpi_object_type type;
1870| u32 system_level;
1871| u32 resource_order;
1872| } power_resource;
1873|};
1874|
1875|
1876|
1877|
1878|struct acpi_object_list {
1879| u32 count;
1880| union acpi_object *pointer;
1881|};
1882|struct acpi_buffer {
1883| acpi_size length;
1884| void *pointer;
1885|};
1886|struct acpi_predefined_names {
1887| char *name;
1888| u8 type;
1889| char *val;
1890|};
1891|struct acpi_system_info {
1892| u32 acpi_ca_version;
1893| u32 flags;
1894| u32 timer_resolution;
1895| u32 reserved1;
1896| u32 reserved2;
1897| u32 debug_level;
1898| u32 debug_layer;
1899|};
1900|typedef u32( * acpi_osd_handler) (void *context);
1901|
1902|typedef void
1903| ( * acpi_osd_exec_callback) (void *context);
1904|
1905|
1906|
1907|
1908|typedef u32(*acpi_event_handler) (void *context);
1909|
1910|typedef
1911|void (*acpi_notify_handler) (acpi_handle device, u32 value, void *context);
1912|
1913|typedef
1914|void (*acpi_object_handler) (acpi_handle object, void *data);
1915|
1916|typedef acpi_status(*acpi_init_handler) (acpi_handle object, u32 function);
1917|
1918|
1919|
1920|typedef
1921|acpi_status(*acpi_exception_handler) (acpi_status aml_status,
1922| acpi_name name,
1923| u16 opcode,
1924| u32 aml_offset, void *context);
1925|
1926|
1927|
1928|typedef
1929|acpi_status(*acpi_tbl_handler) (u32 event, void *table, void *context);
1930|
1931|
1932|
1933|typedef
1934|acpi_status(*acpi_adr_space_handler) (u32 function,
1935| acpi_physical_address address,
1936| u32 bit_width,
1937| u64 *value,
1938| void *handler_context,
1939| void *region_context);
1940|
1941|
1942|
1943|typedef
1944|acpi_status(*acpi_adr_space_setup) (acpi_handle region_handle,
1945| u32 function,
1946| void *handler_context,
1947| void **region_context);
1948|
1949|
1950|
1951|
1952|typedef
1953|acpi_status(*acpi_walk_callback) (acpi_handle object,
1954| u32 nesting_level,
1955| void *context, void **return_value);
1956|
1957|typedef
1958|u32 (*acpi_interface_handler) (acpi_string interface_name, u32 supported);
1959|struct acpica_device_id {
1960| u32 length;
1961| char *string;
1962|};
1963|
1964|struct acpica_device_id_list {
1965| u32 count;
1966| u32 list_size;
1967| struct acpica_device_id ids[1];
1968|};
1969|
1970|
1971|
1972|
1973|
1974|struct acpi_device_info {
1975| u32 info_size;
1976| u32 name;
1977| acpi_object_type type;
1978| u8 param_count;
1979| u8 valid;
1980| u8 flags;
1981| u8 highest_dstates[4];
1982| u8 lowest_dstates[5];
1983| u32 current_status;
1984| u64 address;
1985| struct acpica_device_id hardware_id;
1986| struct acpica_device_id unique_id;
1987| struct acpica_device_id_list compatible_id_list;
1988|};
1989|struct acpi_pci_id {
1990| u16 segment;
1991| u16 bus;
1992| u16 device;
1993| u16 function;
1994|};
1995|
1996|struct acpi_mem_space_context {
1997| u32 length;
1998| acpi_physical_address address;
1999| acpi_physical_address mapped_physical_address;
2000| u8 *mapped_logical_address;
2001| acpi_size mapped_length;
2002|};
2003|
2004|
2005|
2006|
2007|struct acpi_memory_list {
2008| char *list_name;
2009| void *list_head;
2010| u16 object_size;
2011| u16 max_depth;
2012| u16 current_depth;
2013| u16 link_offset;
2014|};
2015|
2016|
2017|
2018|static inline u64 acpi_os_get_thread_id(void)
2019|{
2020| return (u64)(unsigned long)get_current();
2021|}
2022|
2023|
2024|
2025|
2026|
2027|
2028|
2029|static inline void *acpi_os_allocate(acpi_size size)
2030|{
2031| return kmalloc(size, ({ unsigned long _flags; do { ({ unsigned long __dummy; typeof(_flags) __dummy2; (void)(&__dummy == &__dummy2); 1; }); _flags = arch_local_save_flags(); } while (0); ({ ({ unsigned long __dummy; typeof(_flags) __dummy2; (void)(&__dummy == &__dummy2); 1; }); arch_irqs_disabled_flags(_flags); }); }) ? ((( gfp_t)0x20u)) : ((( gfp_t)0x10u) | (( gfp_t)0x40u) | (( gfp_t)0x80u)));
2032|}
2033|
2034|static inline void *acpi_os_allocate_zeroed(acpi_size size)
2035|{
2036| return kzalloc(size, ({ unsigned long _flags; do { ({ unsigned long __dummy; typeof(_flags) __dummy2; (void)(&__dummy == &__dummy2); 1; }); _flags = arch_local_save_flags(); } while (0); ({ ({ unsigned long __dummy; typeof(_flags) __dummy2; (void)(&__dummy == &__dummy2); 1; }); arch_irqs_disabled_flags(_flags); }); }) ? ((( gfp_t)0x20u)) : ((( gfp_t)0x10u) | (( gfp_t)0x40u) | (( gfp_t)0x80u)));
2037|}
2038|
2039|static inline void *acpi_os_acquire_object(struct kmem_cache * cache)
2040|{
2041| return kmem_cache_zalloc(cache,
2042| ({ unsigned long _flags; do { ({ unsigned long __dummy; typeof(_flags) __dummy2; (void)(&__dummy == &__dummy2); 1; }); _flags = arch_local_save_flags(); } while (0); ({ ({ unsigned long __dummy; typeof(_flags) __dummy2; (void)(&__dummy == &__dummy2); 1; }); arch_irqs_disabled_flags(_flags); }); }) ? ((( gfp_t)0x20u)) : ((( gfp_t)0x10u) | (( gfp_t)0x40u) | (( gfp_t)0x80u)));
2043|}
2044|struct acpi_table_header {
2045| char signature[4];
2046| u32 length;
2047| u8 revision;
2048| u8 checksum;
2049| char oem_id[6];
2050| char oem_table_id[8];
2051| u32 oem_revision;
2052| char asl_compiler_id[4];
2053| u32 asl_compiler_revision;
2054|};
2055|struct acpi_generic_address {
2056| u8 space_id;
2057| u8 bit_width;
2058| u8 bit_offset;
2059| u8 access_width;
2060| u64 address;
2061|};
2062|struct acpi_table_rsdp {
2063| char signature[8];
2064| u8 checksum;
2065| char oem_id[6];
2066| u8 revision;
2067| u32 rsdt_physical_address;
2068| u32 length;
2069| u64 xsdt_physical_address;
2070| u8 extended_checksum;
2071| u8 reserved[3];
2072|};
2073|struct acpi_table_rsdt {
2074| struct acpi_table_header header;
2075| u32 table_offset_entry[1];
2076|};
2077|
2078|struct acpi_table_xsdt {
2079| struct acpi_table_header header;
2080| u64 table_offset_entry[1];
2081|};
2082|
2083|
2084|
2085|
2086|
2087|
2088|
2089|struct acpi_table_facs {
2090| char signature[4];
2091| u32 length;
2092| u32 hardware_signature;
2093| u32 firmware_waking_vector;
2094| u32 global_lock;
2095| u32 flags;
2096| u64 xfirmware_waking_vector;
2097| u8 version;
2098| u8 reserved[3];
2099| u32 ospm_flags;
2100| u8 reserved1[24];
2101|};
2102|struct acpi_table_fadt {
2103| struct acpi_table_header header;
2104| u32 facs;
2105| u32 dsdt;
2106| u8 model;
2107| u8 preferred_profile;
2108| u16 sci_interrupt;
2109| u32 smi_command;
2110| u8 acpi_enable;
2111| u8 acpi_disable;
2112| u8 S4bios_request;
2113| u8 pstate_control;
2114| u32 pm1a_event_block;
2115| u32 pm1b_event_block;
2116| u32 pm1a_control_block;
2117| u32 pm1b_control_block;
2118| u32 pm2_control_block;
2119| u32 pm_timer_block;
2120| u32 gpe0_block;
2121| u32 gpe1_block;
2122| u8 pm1_event_length;
2123| u8 pm1_control_length;
2124| u8 pm2_control_length;
2125| u8 pm_timer_length;
2126| u8 gpe0_block_length;
2127| u8 gpe1_block_length;
2128| u8 gpe1_base;
2129| u8 cst_control;
2130| u16 C2latency;
2131| u16 C3latency;
2132| u16 flush_size;
2133| u16 flush_stride;
2134| u8 duty_offset;
2135| u8 duty_width;
2136| u8 day_alarm;
2137| u8 month_alarm;
2138| u8 century;
2139| u16 boot_flags;
2140| u8 reserved;
2141| u32 flags;
2142| struct acpi_generic_address reset_register;
2143| u8 reset_value;
2144| u8 reserved4[3];
2145| u64 Xfacs;
2146| u64 Xdsdt;
2147| struct acpi_generic_address xpm1a_event_block;
2148| struct acpi_generic_address xpm1b_event_block;
2149| struct acpi_generic_address xpm1a_control_block;
2150| struct acpi_generic_address xpm1b_control_block;
2151| struct acpi_generic_address xpm2_control_block;
2152| struct acpi_generic_address xpm_timer_block;
2153| struct acpi_generic_address xgpe0_block;
2154| struct acpi_generic_address xgpe1_block;
2155|};
2156|enum acpi_prefered_pm_profiles {
2157| PM_UNSPECIFIED = 0,
2158| PM_DESKTOP = 1,
2159| PM_MOBILE = 2,
2160| PM_WORKSTATION = 3,
2161| PM_ENTERPRISE_SERVER = 4,
2162| PM_SOHO_SERVER = 5,
2163| PM_APPLIANCE_PC = 6
2164|};
2165|
2166|
2167|
2168|
2169|
2170|
2171|
2172|
2173|
2174|union acpi_name_union {
2175| u32 integer;
2176| char ascii[4];
2177|};
2178|
2179|
2180|
2181|struct acpi_table_desc {
2182| acpi_physical_address address;
2183| struct acpi_table_header *pointer;
2184| u32 length;
2185| union acpi_name_union signature;
2186| acpi_owner_id owner_id;
2187| u8 flags;
2188|};
2189|struct acpi_subtable_header {
2190| u8 type;
2191| u8 length;
2192|};
2193|
2194|
2195|
2196|struct acpi_whea_header {
2197| u8 action;
2198| u8 instruction;
2199| u8 flags;
2200| u8 reserved;
2201| struct acpi_generic_address register_region;
2202| u64 value;
2203| u64 mask;
2204|};
2205|struct acpi_table_bert {
2206| struct acpi_table_header header;
2207| u32 region_length;
2208| u64 address;
2209|};
2210|
2211|
2212|
2213|struct acpi_bert_region {
2214| u32 block_status;
2215| u32 raw_data_offset;
2216| u32 raw_data_length;
2217| u32 data_length;
2218| u32 error_severity;
2219|};
2220|enum acpi_bert_error_severity {
2221| ACPI_BERT_ERROR_CORRECTABLE = 0,
2222| ACPI_BERT_ERROR_FATAL = 1,
2223| ACPI_BERT_ERROR_CORRECTED = 2,
2224| ACPI_BERT_ERROR_NONE = 3,
2225| ACPI_BERT_ERROR_RESERVED = 4
2226|};
2227|struct acpi_table_cpep {
2228| struct acpi_table_header header;
2229| u64 reserved;
2230|};
2231|
2232|
2233|
2234|struct acpi_cpep_polling {
2235| struct acpi_subtable_header header;
2236| u8 id;
2237| u8 eid;
2238| u32 interval;
2239|};
2240|struct acpi_table_ecdt {
2241| struct acpi_table_header header;
2242| struct acpi_generic_address control;
2243| struct acpi_generic_address data;
2244| u32 uid;
2245| u8 gpe;
2246| u8 id[1];
2247|};
2248|struct acpi_table_einj {
2249| struct acpi_table_header header;
2250| u32 header_length;
2251| u8 flags;
2252| u8 reserved[3];
2253| u32 entries;
2254|};
2255|
2256|
2257|
2258|struct acpi_einj_entry {
2259| struct acpi_whea_header whea_header;
2260|};
2261|
2262|
2263|
2264|
2265|
2266|
2267|
2268|enum acpi_einj_actions {
2269| ACPI_EINJ_BEGIN_OPERATION = 0,
2270| ACPI_EINJ_GET_TRIGGER_TABLE = 1,
2271| ACPI_EINJ_SET_ERROR_TYPE = 2,
2272| ACPI_EINJ_GET_ERROR_TYPE = 3,
2273| ACPI_EINJ_END_OPERATION = 4,
2274| ACPI_EINJ_EXECUTE_OPERATION = 5,
2275| ACPI_EINJ_CHECK_BUSY_STATUS = 6,
2276| ACPI_EINJ_GET_COMMAND_STATUS = 7,
2277| ACPI_EINJ_ACTION_RESERVED = 8,
2278| ACPI_EINJ_TRIGGER_ERROR = 0xFF
2279|};
2280|
2281|
2282|
2283|enum acpi_einj_instructions {
2284| ACPI_EINJ_READ_REGISTER = 0,
2285| ACPI_EINJ_READ_REGISTER_VALUE = 1,
2286| ACPI_EINJ_WRITE_REGISTER = 2,
2287| ACPI_EINJ_WRITE_REGISTER_VALUE = 3,
2288| ACPI_EINJ_NOOP = 4,
2289| ACPI_EINJ_INSTRUCTION_RESERVED = 5
2290|};
2291|
2292|
2293|
2294|struct acpi_einj_trigger {
2295| u32 header_size;
2296| u32 revision;
2297| u32 table_size;
2298| u32 entry_count;
2299|};
2300|
2301|
2302|
2303|enum acpi_einj_command_status {
2304| ACPI_EINJ_SUCCESS = 0,
2305| ACPI_EINJ_FAILURE = 1,
2306| ACPI_EINJ_INVALID_ACCESS = 2,
2307| ACPI_EINJ_STATUS_RESERVED = 3
2308|};
2309|struct acpi_table_erst {
2310| struct acpi_table_header header;
2311| u32 header_length;
2312| u32 reserved;
2313| u32 entries;
2314|};
2315|
2316|
2317|
2318|struct acpi_erst_entry {
2319| struct acpi_whea_header whea_header;
2320|};
2321|
2322|
2323|
2324|
2325|
2326|
2327|
2328|enum acpi_erst_actions {
2329| ACPI_ERST_BEGIN_WRITE = 0,
2330| ACPI_ERST_BEGIN_READ = 1,
2331| ACPI_ERST_BEGIN_CLEAR = 2,
2332| ACPI_ERST_END = 3,
2333| ACPI_ERST_SET_RECORD_OFFSET = 4,
2334| ACPI_ERST_EXECUTE_OPERATION = 5,
2335| ACPI_ERST_CHECK_BUSY_STATUS = 6,
2336| ACPI_ERST_GET_COMMAND_STATUS = 7,
2337| ACPI_ERST_GET_RECORD_ID = 8,
2338| ACPI_ERST_SET_RECORD_ID = 9,
2339| ACPI_ERST_GET_RECORD_COUNT = 10,
2340| ACPI_ERST_BEGIN_DUMMY_WRIITE = 11,
2341| ACPI_ERST_NOT_USED = 12,
2342| ACPI_ERST_GET_ERROR_RANGE = 13,
2343| ACPI_ERST_GET_ERROR_LENGTH = 14,
2344| ACPI_ERST_GET_ERROR_ATTRIBUTES = 15,
2345| ACPI_ERST_ACTION_RESERVED = 16
2346|};
2347|
2348|
2349|
2350|enum acpi_erst_instructions {
2351| ACPI_ERST_READ_REGISTER = 0,
2352| ACPI_ERST_READ_REGISTER_VALUE = 1,
2353| ACPI_ERST_WRITE_REGISTER = 2,
2354| ACPI_ERST_WRITE_REGISTER_VALUE = 3,
2355| ACPI_ERST_NOOP = 4,
2356| ACPI_ERST_LOAD_VAR1 = 5,
2357| ACPI_ERST_LOAD_VAR2 = 6,
2358| ACPI_ERST_STORE_VAR1 = 7,
2359| ACPI_ERST_ADD = 8,
2360| ACPI_ERST_SUBTRACT = 9,
2361| ACPI_ERST_ADD_VALUE = 10,
2362| ACPI_ERST_SUBTRACT_VALUE = 11,
2363| ACPI_ERST_STALL = 12,
2364| ACPI_ERST_STALL_WHILE_TRUE = 13,
2365| ACPI_ERST_SKIP_NEXT_IF_TRUE = 14,
2366| ACPI_ERST_GOTO = 15,
2367| ACPI_ERST_SET_SRC_ADDRESS_BASE = 16,
2368| ACPI_ERST_SET_DST_ADDRESS_BASE = 17,
2369| ACPI_ERST_MOVE_DATA = 18,
2370| ACPI_ERST_INSTRUCTION_RESERVED = 19
2371|};
2372|
2373|
2374|
2375|enum acpi_erst_command_status {
2376| ACPI_ERST_SUCESS = 0,
2377| ACPI_ERST_NO_SPACE = 1,
2378| ACPI_ERST_NOT_AVAILABLE = 2,
2379| ACPI_ERST_FAILURE = 3,
2380| ACPI_ERST_RECORD_EMPTY = 4,
2381| ACPI_ERST_NOT_FOUND = 5,
2382| ACPI_ERST_STATUS_RESERVED = 6
2383|};
2384|
2385|
2386|
2387|struct acpi_erst_info {
2388| u16 signature;
2389| u8 data[48];
2390|};
2391|struct acpi_table_hest {
2392| struct acpi_table_header header;
2393| u32 error_source_count;
2394|};
2395|
2396|
2397|
2398|struct acpi_hest_header {
2399| u16 type;
2400| u16 source_id;
2401|};
2402|
2403|
2404|
2405|enum acpi_hest_types {
2406| ACPI_HEST_TYPE_IA32_CHECK = 0,
2407| ACPI_HEST_TYPE_IA32_CORRECTED_CHECK = 1,
2408| ACPI_HEST_TYPE_IA32_NMI = 2,
2409| ACPI_HEST_TYPE_NOT_USED3 = 3,
2410| ACPI_HEST_TYPE_NOT_USED4 = 4,
2411| ACPI_HEST_TYPE_NOT_USED5 = 5,
2412| ACPI_HEST_TYPE_AER_ROOT_PORT = 6,
2413| ACPI_HEST_TYPE_AER_ENDPOINT = 7,
2414| ACPI_HEST_TYPE_AER_BRIDGE = 8,
2415| ACPI_HEST_TYPE_GENERIC_ERROR = 9,
2416| ACPI_HEST_TYPE_RESERVED = 10
2417|};
2418|struct acpi_hest_ia_error_bank {
2419| u8 bank_number;
2420| u8 clear_status_on_init;
2421| u8 status_format;
2422| u8 reserved;
2423| u32 control_register;
2424| u64 control_data;
2425| u32 status_register;
2426| u32 address_register;
2427| u32 misc_register;
2428|};
2429|
2430|
2431|
2432|struct acpi_hest_aer_common {
2433| u16 reserved1;
2434| u8 flags;
2435| u8 enabled;
2436| u32 records_to_preallocate;
2437| u32 max_sections_per_record;
2438| u32 bus;
2439| u16 device;
2440| u16 function;
2441| u16 device_control;
2442| u16 reserved2;
2443| u32 uncorrectable_mask;
2444| u32 uncorrectable_severity;
2445| u32 correctable_mask;
2446| u32 advanced_capabilities;
2447|};
2448|struct acpi_hest_notify {
2449| u8 type;
2450| u8 length;
2451| u16 config_write_enable;
2452| u32 poll_interval;
2453| u32 vector;
2454| u32 polling_threshold_value;
2455| u32 polling_threshold_window;
2456| u32 error_threshold_value;
2457| u32 error_threshold_window;
2458|};
2459|
2460|
2461|
2462|enum acpi_hest_notify_types {
2463| ACPI_HEST_NOTIFY_POLLED = 0,
2464| ACPI_HEST_NOTIFY_EXTERNAL = 1,
2465| ACPI_HEST_NOTIFY_LOCAL = 2,
2466| ACPI_HEST_NOTIFY_SCI = 3,
2467| ACPI_HEST_NOTIFY_NMI = 4,
2468| ACPI_HEST_NOTIFY_RESERVED = 5
2469|};
2470|struct acpi_hest_ia_machine_check {
2471| struct acpi_hest_header header;
2472| u16 reserved1;
2473| u8 flags;
2474| u8 enabled;
2475| u32 records_to_preallocate;
2476| u32 max_sections_per_record;
2477| u64 global_capability_data;
2478| u64 global_control_data;
2479| u8 num_hardware_banks;
2480| u8 reserved3[7];
2481|};
2482|
2483|
2484|
2485|struct acpi_hest_ia_corrected {
2486| struct acpi_hest_header header;
2487| u16 reserved1;
2488| u8 flags;
2489| u8 enabled;
2490| u32 records_to_preallocate;
2491| u32 max_sections_per_record;
2492| struct acpi_hest_notify notify;
2493| u8 num_hardware_banks;
2494| u8 reserved2[3];
2495|};
2496|
2497|
2498|
2499|struct acpi_hest_ia_nmi {
2500| struct acpi_hest_header header;
2501| u32 reserved;
2502| u32 records_to_preallocate;
2503| u32 max_sections_per_record;
2504| u32 max_raw_data_length;
2505|};
2506|
2507|
2508|
2509|
2510|
2511|struct acpi_hest_aer_root {
2512| struct acpi_hest_header header;
2513| struct acpi_hest_aer_common aer;
2514| u32 root_error_command;
2515|};
2516|
2517|
2518|
2519|struct acpi_hest_aer {
2520| struct acpi_hest_header header;
2521| struct acpi_hest_aer_common aer;
2522|};
2523|
2524|
2525|
2526|struct acpi_hest_aer_bridge {
2527| struct acpi_hest_header header;
2528| struct acpi_hest_aer_common aer;
2529| u32 uncorrectable_mask2;
2530| u32 uncorrectable_severity2;
2531| u32 advanced_capabilities2;
2532|};
2533|
2534|
2535|
2536|struct acpi_hest_generic {
2537| struct acpi_hest_header header;
2538| u16 related_source_id;
2539| u8 reserved;
2540| u8 enabled;
2541| u32 records_to_preallocate;
2542| u32 max_sections_per_record;
2543| u32 max_raw_data_length;
2544| struct acpi_generic_address error_status_address;
2545| struct acpi_hest_notify notify;
2546| u32 error_block_length;
2547|};
2548|
2549|
2550|
2551|struct acpi_hest_generic_status {
2552| u32 block_status;
2553| u32 raw_data_offset;
2554| u32 raw_data_length;
2555| u32 data_length;
2556| u32 error_severity;
2557|};
2558|struct acpi_hest_generic_data {
2559| u8 section_type[16];
2560| u32 error_severity;
2561| u16 revision;
2562| u8 validation_bits;
2563| u8 flags;
2564| u32 error_data_length;
2565| u8 fru_id[16];
2566| u8 fru_text[20];
2567|};
2568|struct acpi_table_madt {
2569| struct acpi_table_header header;
2570| u32 address;
2571| u32 flags;
2572|};
2573|enum acpi_madt_type {
2574| ACPI_MADT_TYPE_LOCAL_APIC = 0,
2575| ACPI_MADT_TYPE_IO_APIC = 1,
2576| ACPI_MADT_TYPE_INTERRUPT_OVERRIDE = 2,
2577| ACPI_MADT_TYPE_NMI_SOURCE = 3,
2578| ACPI_MADT_TYPE_LOCAL_APIC_NMI = 4,
2579| ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE = 5,
2580| ACPI_MADT_TYPE_IO_SAPIC = 6,
2581| ACPI_MADT_TYPE_LOCAL_SAPIC = 7,
2582| ACPI_MADT_TYPE_INTERRUPT_SOURCE = 8,
2583| ACPI_MADT_TYPE_LOCAL_X2APIC = 9,
2584| ACPI_MADT_TYPE_LOCAL_X2APIC_NMI = 10,
2585| ACPI_MADT_TYPE_RESERVED = 11
2586|};
2587|
2588|
2589|
2590|
2591|
2592|
2593|
2594|struct acpi_madt_local_apic {
2595| struct acpi_subtable_header header;
2596| u8 processor_id;
2597| u8 id;
2598| u32 lapic_flags;
2599|};
2600|
2601|
2602|
2603|struct acpi_madt_io_apic {
2604| struct acpi_subtable_header header;
2605| u8 id;
2606| u8 reserved;
2607| u32 address;
2608| u32 global_irq_base;
2609|};
2610|
2611|
2612|
2613|struct acpi_madt_interrupt_override {
2614| struct acpi_subtable_header header;
2615| u8 bus;
2616| u8 source_irq;
2617| u32 global_irq;
2618| u16 inti_flags;
2619|};
2620|
2621|
2622|
2623|struct acpi_madt_nmi_source {
2624| struct acpi_subtable_header header;
2625| u16 inti_flags;
2626| u32 global_irq;
2627|};
2628|
2629|
2630|
2631|struct acpi_madt_local_apic_nmi {
2632| struct acpi_subtable_header header;
2633| u8 processor_id;
2634| u16 inti_flags;
2635| u8 lint;
2636|};
2637|
2638|
2639|
2640|struct acpi_madt_local_apic_override {
2641| struct acpi_subtable_header header;
2642| u16 reserved;
2643| u64 address;
2644|};
2645|
2646|
2647|
2648|struct acpi_madt_io_sapic {
2649| struct acpi_subtable_header header;
2650| u8 id;
2651| u8 reserved;
2652| u32 global_irq_base;
2653| u64 address;
2654|};
2655|
2656|
2657|
2658|struct acpi_madt_local_sapic {
2659| struct acpi_subtable_header header;
2660| u8 processor_id;
2661| u8 id;
2662| u8 eid;
2663| u8 reserved[3];
2664| u32 lapic_flags;
2665| u32 uid;
2666| char uid_string[1];
2667|};
2668|
2669|
2670|
2671|struct acpi_madt_interrupt_source {
2672| struct acpi_subtable_header header;
2673| u16 inti_flags;
2674| u8 type;
2675| u8 id;
2676| u8 eid;
2677| u8 io_sapic_vector;
2678| u32 global_irq;
2679| u32 flags;
2680|};
2681|
2682|
2683|
2684|
2685|
2686|
2687|
2688|struct acpi_madt_local_x2apic {
2689| struct acpi_subtable_header header;
2690| u16 reserved;
2691| u32 local_apic_id;
2692| u32 lapic_flags;
2693| u32 uid;
2694|};
2695|
2696|
2697|
2698|struct acpi_madt_local_x2apic_nmi {
2699| struct acpi_subtable_header header;
2700| u16 inti_flags;
2701| u32 uid;
2702| u8 lint;
2703| u8 reserved[3];
2704|};
2705|struct acpi_table_msct {
2706| struct acpi_table_header header;
2707| u32 proximity_offset;
2708| u32 max_proximity_domains;
2709| u32 max_clock_domains;
2710| u64 max_address;
2711|};
2712|
2713|
2714|
2715|struct acpi_msct_proximity {
2716| u8 revision;
2717| u8 length;
2718| u32 range_start;
2719| u32 range_end;
2720| u32 processor_capacity;
2721| u64 memory_capacity;
2722|};
2723|struct acpi_table_sbst {
2724| struct acpi_table_header header;
2725| u32 warning_level;
2726| u32 low_level;
2727| u32 critical_level;
2728|};
2729|struct acpi_table_slit {
2730| struct acpi_table_header header;
2731| u64 locality_count;
2732| u8 entry[1];
2733|};
2734|struct acpi_table_srat {
2735| struct acpi_table_header header;
2736| u32 table_revision;
2737| u64 reserved;
2738|};
2739|
2740|
2741|
2742|enum acpi_srat_type {
2743| ACPI_SRAT_TYPE_CPU_AFFINITY = 0,
2744| ACPI_SRAT_TYPE_MEMORY_AFFINITY = 1,
2745| ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY = 2,
2746| ACPI_SRAT_TYPE_RESERVED = 3
2747|};
2748|
2749|
2750|
2751|
2752|
2753|
2754|
2755|struct acpi_srat_cpu_affinity {
2756| struct acpi_subtable_header header;
2757| u8 proximity_domain_lo;
2758| u8 apic_id;
2759| u32 flags;
2760| u8 local_sapic_eid;
2761| u8 proximity_domain_hi[3];
2762| u32 reserved;
2763|};
2764|
2765|
2766|
2767|
2768|
2769|
2770|
2771|struct acpi_srat_mem_affinity {
2772| struct acpi_subtable_header header;
2773| u32 proximity_domain;
2774| u16 reserved;
2775| u64 base_address;
2776| u64 length;
2777| u32 reserved1;
2778| u32 flags;
2779| u64 reserved2;
2780|};
2781|struct acpi_srat_x2apic_cpu_affinity {
2782| struct acpi_subtable_header header;
2783| u16 reserved;
2784| u32 proximity_domain;
2785| u32 apic_id;
2786| u32 flags;
2787| u32 clock_domain;
2788| u32 reserved2;
2789|};
2790|
2791|
2792|
2793|
2794|
2795|
2796|
2797|struct acpi_table_asf {
2798| struct acpi_table_header header;
2799|};
2800|
2801|
2802|
2803|struct acpi_asf_header {
2804| u8 type;
2805| u8 reserved;
2806| u16 length;
2807|};
2808|
2809|
2810|
2811|enum acpi_asf_type {
2812| ACPI_ASF_TYPE_INFO = 0,
2813| ACPI_ASF_TYPE_ALERT = 1,
2814| ACPI_ASF_TYPE_CONTROL = 2,
2815| ACPI_ASF_TYPE_BOOT = 3,
2816| ACPI_ASF_TYPE_ADDRESS = 4,
2817| ACPI_ASF_TYPE_RESERVED = 5
2818|};
2819|
2820|
2821|
2822|
2823|
2824|
2825|
2826|struct acpi_asf_info {
2827| struct acpi_asf_header header;
2828| u8 min_reset_value;
2829| u8 min_poll_interval;
2830| u16 system_id;
2831| u32 mfg_id;
2832| u8 flags;
2833| u8 reserved2[3];
2834|};
2835|
2836|
2837|
2838|
2839|
2840|
2841|
2842|struct acpi_asf_alert {
2843| struct acpi_asf_header header;
2844| u8 assert_mask;
2845| u8 deassert_mask;
2846| u8 alerts;
2847| u8 data_length;
2848|};
2849|
2850|struct acpi_asf_alert_data {
2851| u8 address;
2852| u8 command;
2853| u8 mask;
2854| u8 value;
2855| u8 sensor_type;
2856| u8 type;
2857| u8 offset;
2858| u8 source_type;
2859| u8 severity;
2860| u8 sensor_number;
2861| u8 entity;
2862| u8 instance;
2863|};
2864|
2865|
2866|
2867|struct acpi_asf_remote {
2868| struct acpi_asf_header header;
2869| u8 controls;
2870| u8 data_length;
2871| u16 reserved2;
2872|};
2873|
2874|struct acpi_asf_control_data {
2875| u8 function;
2876| u8 address;
2877| u8 command;
2878| u8 value;
2879|};
2880|
2881|
2882|
2883|struct acpi_asf_rmcp {
2884| struct acpi_asf_header header;
2885| u8 capabilities[7];
2886| u8 completion_code;
2887| u32 enterprise_id;
2888| u8 command;
2889| u16 parameter;
2890| u16 boot_options;
2891| u16 oem_parameters;
2892|};
2893|
2894|
2895|
2896|struct acpi_asf_address {
2897| struct acpi_asf_header header;
2898| u8 eprom_address;
2899| u8 devices;
2900|};
2901|struct acpi_table_boot {
2902| struct acpi_table_header header;
2903| u8 cmos_index;
2904| u8 reserved[3];
2905|};
2906|struct acpi_table_dbgp {
2907| struct acpi_table_header header;
2908| u8 type;
2909| u8 reserved[3];
2910| struct acpi_generic_address debug_port;
2911|};
2912|struct acpi_table_dmar {
2913| struct acpi_table_header header;
2914| u8 width;
2915| u8 flags;
2916| u8 reserved[10];
2917|};
2918|
2919|
2920|
2921|
2922|
2923|
2924|
2925|struct acpi_dmar_header {
2926| u16 type;
2927| u16 length;
2928|};
2929|
2930|
2931|
2932|enum acpi_dmar_type {
2933| ACPI_DMAR_TYPE_HARDWARE_UNIT = 0,
2934| ACPI_DMAR_TYPE_RESERVED_MEMORY = 1,
2935| ACPI_DMAR_TYPE_ATSR = 2,
2936| ACPI_DMAR_HARDWARE_AFFINITY = 3,
2937| ACPI_DMAR_TYPE_RESERVED = 4
2938|};
2939|
2940|
2941|
2942|struct acpi_dmar_device_scope {
2943| u8 entry_type;
2944| u8 length;
2945| u16 reserved;
2946| u8 enumeration_id;
2947| u8 bus;
2948|};
2949|
2950|
2951|
2952|enum acpi_dmar_scope_type {
2953| ACPI_DMAR_SCOPE_TYPE_NOT_USED = 0,
2954| ACPI_DMAR_SCOPE_TYPE_ENDPOINT = 1,
2955| ACPI_DMAR_SCOPE_TYPE_BRIDGE = 2,
2956| ACPI_DMAR_SCOPE_TYPE_IOAPIC = 3,
2957| ACPI_DMAR_SCOPE_TYPE_HPET = 4,
2958| ACPI_DMAR_SCOPE_TYPE_RESERVED = 5
2959|};
2960|
2961|struct acpi_dmar_pci_path {
2962| u8 dev;
2963| u8 fn;
2964|};
2965|
2966|
2967|
2968|
2969|
2970|
2971|
2972|struct acpi_dmar_hardware_unit {
2973| struct acpi_dmar_header header;
2974| u8 flags;
2975| u8 reserved;
2976| u16 segment;
2977| u64 address;
2978|};
2979|
2980|
2981|
2982|
2983|
2984|
2985|
2986|struct acpi_dmar_reserved_memory {
2987| struct acpi_dmar_header header;
2988| u16 reserved;
2989| u16 segment;
2990| u64 base_address;
2991| u64 end_address;
2992|};
2993|
2994|
2995|
2996|
2997|
2998|
2999|
3000|struct acpi_dmar_atsr {
3001| struct acpi_dmar_header header;
3002| u8 flags;
3003| u8 reserved;
3004| u16 segment;
3005|};
3006|
3007|
3008|
3009|
3010|
3011|
3012|
3013|struct acpi_dmar_rhsa {
3014| struct acpi_dmar_header header;
3015| u32 reserved;
3016| u64 base_address;
3017| u32 proximity_domain;
3018|};
3019|struct acpi_table_hpet {
3020| struct acpi_table_header header;
3021| u32 id;
3022| struct acpi_generic_address address;
3023| u8 sequence;
3024| u16 minimum_tick;
3025| u8 flags;
3026|};
3027|
3028|
3029|
3030|
3031|
3032|
3033|
3034|enum acpi_hpet_page_protect {
3035| ACPI_HPET_NO_PAGE_PROTECT = 0,
3036| ACPI_HPET_PAGE_PROTECT4 = 1,
3037| ACPI_HPET_PAGE_PROTECT64 = 2
3038|};
3039|struct acpi_table_ibft {
3040| struct acpi_table_header header;
3041| u8 reserved[12];
3042|};
3043|
3044|
3045|
3046|struct acpi_ibft_header {
3047| u8 type;
3048| u8 version;
3049| u16 length;
3050| u8 index;
3051| u8 flags;
3052|};
3053|
3054|
3055|
3056|enum acpi_ibft_type {
3057| ACPI_IBFT_TYPE_NOT_USED = 0,
3058| ACPI_IBFT_TYPE_CONTROL = 1,
3059| ACPI_IBFT_TYPE_INITIATOR = 2,
3060| ACPI_IBFT_TYPE_NIC = 3,
3061| ACPI_IBFT_TYPE_TARGET = 4,
3062| ACPI_IBFT_TYPE_EXTENSIONS = 5,
3063| ACPI_IBFT_TYPE_RESERVED = 6
3064|};
3065|
3066|
3067|
3068|struct acpi_ibft_control {
3069| struct acpi_ibft_header header;
3070| u16 extensions;
3071| u16 initiator_offset;
3072| u16 nic0_offset;
3073| u16 target0_offset;
3074| u16 nic1_offset;
3075| u16 target1_offset;
3076|};
3077|
3078|struct acpi_ibft_initiator {
3079| struct acpi_ibft_header header;
3080| u8 sns_server[16];
3081| u8 slp_server[16];
3082| u8 primary_server[16];
3083| u8 secondary_server[16];
3084| u16 name_length;
3085| u16 name_offset;
3086|};
3087|
3088|struct acpi_ibft_nic {
3089| struct acpi_ibft_header header;
3090| u8 ip_address[16];
3091| u8 subnet_mask_prefix;
3092| u8 origin;
3093| u8 gateway[16];
3094| u8 primary_dns[16];
3095| u8 secondary_dns[16];
3096| u8 dhcp[16];
3097| u16 vlan;
3098| u8 mac_address[6];
3099| u16 pci_address;
3100| u16 name_length;
3101| u16 name_offset;
3102|};
3103|
3104|struct acpi_ibft_target {
3105| struct acpi_ibft_header header;
3106| u8 target_ip_address[16];
3107| u16 target_ip_socket;
3108| u8 target_boot_lun[8];
3109| u8 chap_type;
3110| u8 nic_association;
3111| u16 target_name_length;
3112| u16 target_name_offset;
3113| u16 chap_name_length;
3114| u16 chap_name_offset;
3115| u16 chap_secret_length;
3116| u16 chap_secret_offset;
3117| u16 reverse_chap_name_length;
3118| u16 reverse_chap_name_offset;
3119| u16 reverse_chap_secret_length;
3120| u16 reverse_chap_secret_offset;
3121|};
3122|struct acpi_table_ivrs {
3123| struct acpi_table_header header;
3124| u32 info;
3125| u64 reserved;
3126|};
3127|struct acpi_ivrs_header {
3128| u8 type;
3129| u8 flags;
3130| u16 length;
3131| u16 device_id;
3132|};
3133|
3134|
3135|
3136|enum acpi_ivrs_type {
3137| ACPI_IVRS_TYPE_HARDWARE = 0x10,
3138| ACPI_IVRS_TYPE_MEMORY1 = 0x20,
3139| ACPI_IVRS_TYPE_MEMORY2 = 0x21,
3140| ACPI_IVRS_TYPE_MEMORY3 = 0x22
3141|};
3142|struct acpi_ivrs_hardware {
3143| struct acpi_ivrs_header header;
3144| u16 capability_offset;
3145| u64 base_address;
3146| u16 pci_segment_group;
3147| u16 info;
3148| u32 reserved;
3149|};
3150|struct acpi_ivrs_de_header {
3151| u8 type;
3152| u16 id;
3153| u8 data_setting;
3154|};
3155|
3156|
3157|
3158|
3159|
3160|
3161|
3162|enum acpi_ivrs_device_entry_type {
3163|
3164|
3165| ACPI_IVRS_TYPE_PAD4 = 0,
3166| ACPI_IVRS_TYPE_ALL = 1,
3167| ACPI_IVRS_TYPE_SELECT = 2,
3168| ACPI_IVRS_TYPE_START = 3,
3169| ACPI_IVRS_TYPE_END = 4,
3170|
3171|
3172|
3173| ACPI_IVRS_TYPE_PAD8 = 64,
3174| ACPI_IVRS_TYPE_NOT_USED = 65,
3175| ACPI_IVRS_TYPE_ALIAS_SELECT = 66,
3176| ACPI_IVRS_TYPE_ALIAS_START = 67,
3177| ACPI_IVRS_TYPE_EXT_SELECT = 70,
3178| ACPI_IVRS_TYPE_EXT_START = 71,
3179| ACPI_IVRS_TYPE_SPECIAL = 72
3180|};
3181|struct acpi_ivrs_device4 {
3182| struct acpi_ivrs_de_header header;
3183|};
3184|
3185|
3186|
3187|struct acpi_ivrs_device8a {
3188| struct acpi_ivrs_de_header header;
3189| u8 reserved1;
3190| u16 used_id;
3191| u8 reserved2;
3192|};
3193|
3194|
3195|
3196|struct acpi_ivrs_device8b {
3197| struct acpi_ivrs_de_header header;
3198| u32 extended_data;
3199|};
3200|
3201|
3202|
3203|
3204|
3205|
3206|
3207|struct acpi_ivrs_device8c {
3208| struct acpi_ivrs_de_header header;
3209| u8 handle;
3210| u16 used_id;
3211| u8 variety;
3212|};
3213|struct acpi_ivrs_memory {
3214| struct acpi_ivrs_header header;
3215| u16 aux_data;
3216| u64 reserved;
3217| u64 start_address;
3218| u64 memory_length;
3219|};
3220|struct acpi_table_mcfg {
3221| struct acpi_table_header header;
3222| u8 reserved[8];
3223|};
3224|
3225|
3226|
3227|struct acpi_mcfg_allocation {
3228| u64 address;
3229| u16 pci_segment;
3230| u8 start_bus_number;
3231| u8 end_bus_number;
3232| u32 reserved;
3233|};
3234|struct acpi_table_mchi {
3235| struct acpi_table_header header;
3236| u8 interface_type;
3237| u8 protocol;
3238| u64 protocol_data;
3239| u8 interrupt_type;
3240| u8 gpe;
3241| u8 pci_device_flag;
3242| u32 global_interrupt;
3243| struct acpi_generic_address control_register;
3244| u8 pci_segment;
3245| u8 pci_bus;
3246| u8 pci_device;
3247| u8 pci_function;
3248|};
3249|struct acpi_table_spcr {
3250| struct acpi_table_header header;
3251| u8 interface_type;
3252| u8 reserved[3];
3253| struct acpi_generic_address serial_port;
3254| u8 interrupt_type;
3255| u8 pc_interrupt;
3256| u32 interrupt;
3257| u8 baud_rate;
3258| u8 parity;
3259| u8 stop_bits;
3260| u8 flow_control;
3261| u8 terminal_type;
3262| u8 reserved1;
3263| u16 pci_device_id;
3264| u16 pci_vendor_id;
3265| u8 pci_bus;
3266| u8 pci_device;
3267| u8 pci_function;
3268| u32 pci_flags;
3269| u8 pci_segment;
3270| u32 reserved2;
3271|};
3272|struct acpi_table_spmi {
3273| struct acpi_table_header header;
3274| u8 interface_type;
3275| u8 reserved;
3276| u16 spec_revision;
3277| u8 interrupt_type;
3278| u8 gpe_number;
3279| u8 reserved1;
3280| u8 pci_device_flag;
3281| u32 interrupt;
3282| struct acpi_generic_address ipmi_register;
3283| u8 pci_segment;
3284| u8 pci_bus;
3285| u8 pci_device;
3286| u8 pci_function;
3287| u8 reserved2;
3288|};
3289|
3290|
3291|
3292|enum acpi_spmi_interface_types {
3293| ACPI_SPMI_NOT_USED = 0,
3294| ACPI_SPMI_KEYBOARD = 1,
3295| ACPI_SPMI_SMI = 2,
3296| ACPI_SPMI_BLOCK_TRANSFER = 3,
3297| ACPI_SPMI_SMBUS = 4,
3298| ACPI_SPMI_RESERVED = 5
3299|};
3300|struct acpi_table_tcpa {
3301| struct acpi_table_header header;
3302| u16 reserved;
3303| u32 max_log_length;
3304| u64 log_address;
3305|};
3306|struct acpi_table_uefi {
3307| struct acpi_table_header header;
3308| u8 identifier[16];
3309| u16 data_offset;
3310|};
3311|struct acpi_table_waet {
3312| struct acpi_table_header header;
3313| u32 flags;
3314|};
3315|struct acpi_table_wdat {
3316| struct acpi_table_header header;
3317| u32 header_length;
3318| u16 pci_segment;
3319| u8 pci_bus;
3320| u8 pci_device;
3321| u8 pci_function;
3322| u8 reserved[3];
3323| u32 timer_period;
3324| u32 max_count;
3325| u32 min_count;
3326| u8 flags;
3327| u8 reserved2[3];
3328| u32 entries;
3329|};
3330|struct acpi_wdat_entry {
3331| u8 action;
3332| u8 instruction;
3333| u16 reserved;
3334| struct acpi_generic_address register_region;
3335| u32 value;
3336| u32 mask;
3337|};
3338|
3339|
3340|
3341|enum acpi_wdat_actions {
3342| ACPI_WDAT_RESET = 1,
3343| ACPI_WDAT_GET_CURRENT_COUNTDOWN = 4,
3344| ACPI_WDAT_GET_COUNTDOWN = 5,
3345| ACPI_WDAT_SET_COUNTDOWN = 6,
3346| ACPI_WDAT_GET_RUNNING_STATE = 8,
3347| ACPI_WDAT_SET_RUNNING_STATE = 9,
3348| ACPI_WDAT_GET_STOPPED_STATE = 10,
3349| ACPI_WDAT_SET_STOPPED_STATE = 11,
3350| ACPI_WDAT_GET_REBOOT = 16,
3351| ACPI_WDAT_SET_REBOOT = 17,
3352| ACPI_WDAT_GET_SHUTDOWN = 18,
3353| ACPI_WDAT_SET_SHUTDOWN = 19,
3354| ACPI_WDAT_GET_STATUS = 32,
3355| ACPI_WDAT_SET_STATUS = 33,
3356| ACPI_WDAT_ACTION_RESERVED = 34
3357|};
3358|
3359|
3360|
3361|enum acpi_wdat_instructions {
3362| ACPI_WDAT_READ_VALUE = 0,
3363| ACPI_WDAT_READ_COUNTDOWN = 1,
3364| ACPI_WDAT_WRITE_VALUE = 2,
3365| ACPI_WDAT_WRITE_COUNTDOWN = 3,
3366| ACPI_WDAT_INSTRUCTION_RESERVED = 4,
3367| ACPI_WDAT_PRESERVE_REGISTER = 0x80
3368|};
3369|struct acpi_table_wddt {
3370| struct acpi_table_header header;
3371| u16 spec_version;
3372| u16 table_version;
3373| u16 pci_vendor_id;
3374| struct acpi_generic_address address;
3375| u16 max_count;
3376| u16 min_count;
3377| u16 period;
3378| u16 status;
3379| u16 capability;
3380|};
3381|struct acpi_table_wdrt {
3382| struct acpi_table_header header;
3383| struct acpi_generic_address control_register;
3384| struct acpi_generic_address count_register;
3385| u16 pci_device_id;
3386| u16 pci_vendor_id;
3387| u8 pci_bus;
3388| u8 pci_device;
3389| u8 pci_function;
3390| u8 pci_segment;
3391| u16 max_count;
3392| u8 units;
3393|};
3394|
3395|
3396|
3397|typedef u16 acpi_rs_length;
3398|typedef u32 acpi_rsdesc_size;
3399|
3400|
3401|
3402|
3403|struct acpi_uuid {
3404| u8 data[16];
3405|};
3406|
3407|struct acpi_vendor_uuid {
3408| u8 subtype;
3409| u8 data[16];
3410|};
3411|
3412|
3413|
3414|
3415|struct acpi_resource_irq {
3416| u8 descriptor_length;
3417| u8 triggering;
3418| u8 polarity;
3419| u8 sharable;
3420| u8 interrupt_count;
3421| u8 interrupts[1];
3422|};
3423|
3424|struct acpi_resource_dma {
3425| u8 type;
3426| u8 bus_master;
3427| u8 transfer;
3428| u8 channel_count;
3429| u8 channels[1];
3430|};
3431|
3432|struct acpi_resource_start_dependent {
3433| u8 descriptor_length;
3434| u8 compatibility_priority;
3435| u8 performance_robustness;
3436|};
3437|
3438|
3439|
3440|
3441|
3442|
3443|struct acpi_resource_io {
3444| u8 io_decode;
3445| u8 alignment;
3446| u8 address_length;
3447| u16 minimum;
3448| u16 maximum;
3449|};
3450|
3451|struct acpi_resource_fixed_io {
3452| u16 address;
3453| u8 address_length;
3454|};
3455|
3456|struct acpi_resource_vendor {
3457| u16 byte_length;
3458| u8 byte_data[1];
3459|};
3460|
3461|
3462|
3463|struct acpi_resource_vendor_typed {
3464| u16 byte_length;
3465| u8 uuid_subtype;
3466| u8 uuid[16];
3467| u8 byte_data[1];
3468|};
3469|
3470|struct acpi_resource_end_tag {
3471| u8 checksum;
3472|};
3473|
3474|struct acpi_resource_memory24 {
3475| u8 write_protect;
3476| u16 minimum;
3477| u16 maximum;
3478| u16 alignment;
3479| u16 address_length;
3480|};
3481|
3482|struct acpi_resource_memory32 {
3483| u8 write_protect;
3484| u32 minimum;
3485| u32 maximum;
3486| u32 alignment;
3487| u32 address_length;
3488|};
3489|
3490|struct acpi_resource_fixed_memory32 {
3491| u8 write_protect;
3492| u32 address;
3493| u32 address_length;
3494|};
3495|
3496|struct acpi_memory_attribute {
3497| u8 write_protect;
3498| u8 caching;
3499| u8 range_type;
3500| u8 translation;
3501|};
3502|
3503|struct acpi_io_attribute {
3504| u8 range_type;
3505| u8 translation;
3506| u8 translation_type;
3507| u8 reserved1;
3508|};
3509|
3510|union acpi_resource_attribute {
3511| struct acpi_memory_attribute mem;
3512| struct acpi_io_attribute io;
3513|
3514|
3515|
3516| u8 type_specific;
3517|};
3518|
3519|struct acpi_resource_source {
3520| u8 index;
3521| u16 string_length;
3522| char *string_ptr;
3523|};
3524|struct acpi_resource_address {
3525|u8 resource_type; u8 producer_consumer; u8 decode; u8 min_address_fixed; u8 max_address_fixed; union acpi_resource_attribute info;};
3526|
3527|struct acpi_resource_address16 {
3528| u8 resource_type; u8 producer_consumer; u8 decode; u8 min_address_fixed; u8 max_address_fixed; union acpi_resource_attribute info; u16 granularity;
3529| u16 minimum;
3530| u16 maximum;
3531| u16 translation_offset;
3532| u16 address_length;
3533| struct acpi_resource_source resource_source;
3534|};
3535|
3536|struct acpi_resource_address32 {
3537| u8 resource_type; u8 producer_consumer; u8 decode; u8 min_address_fixed; u8 max_address_fixed; union acpi_resource_attribute info; u32 granularity;
3538| u32 minimum;
3539| u32 maximum;
3540| u32 translation_offset;
3541| u32 address_length;
3542| struct acpi_resource_source resource_source;
3543|};
3544|
3545|struct acpi_resource_address64 {
3546| u8 resource_type; u8 producer_consumer; u8 decode; u8 min_address_fixed; u8 max_address_fixed; union acpi_resource_attribute info; u64 granularity;
3547| u64 minimum;
3548| u64 maximum;
3549| u64 translation_offset;
3550| u64 address_length;
3551| struct acpi_resource_source resource_source;
3552|};
3553|
3554|struct acpi_resource_extended_address64 {
3555| u8 resource_type; u8 producer_consumer; u8 decode; u8 min_address_fixed; u8 max_address_fixed; union acpi_resource_attribute info; u8 revision_iD;
3556| u64 granularity;
3557| u64 minimum;
3558| u64 maximum;
3559| u64 translation_offset;
3560| u64 address_length;
3561| u64 type_specific;
3562|};
3563|
3564|struct acpi_resource_extended_irq {
3565| u8 producer_consumer;
3566| u8 triggering;
3567| u8 polarity;
3568| u8 sharable;
3569| u8 interrupt_count;
3570| struct acpi_resource_source resource_source;
3571| u32 interrupts[1];
3572|};
3573|
3574|struct acpi_resource_generic_register {
3575| u8 space_id;
3576| u8 bit_width;
3577| u8 bit_offset;
3578| u8 access_size;
3579| u64 address;
3580|};
3581|union acpi_resource_data {
3582| struct acpi_resource_irq irq;
3583| struct acpi_resource_dma dma;
3584| struct acpi_resource_start_dependent start_dpf;
3585| struct acpi_resource_io io;
3586| struct acpi_resource_fixed_io fixed_io;
3587| struct acpi_resource_vendor vendor;
3588| struct acpi_resource_vendor_typed vendor_typed;
3589| struct acpi_resource_end_tag end_tag;
3590| struct acpi_resource_memory24 memory24;
3591| struct acpi_resource_memory32 memory32;
3592| struct acpi_resource_fixed_memory32 fixed_memory32;
3593| struct acpi_resource_address16 address16;
3594| struct acpi_resource_address32 address32;
3595| struct acpi_resource_address64 address64;
3596| struct acpi_resource_extended_address64 ext_address64;
3597| struct acpi_resource_extended_irq extended_irq;
3598| struct acpi_resource_generic_register generic_reg;
3599|
3600|
3601|
3602| struct acpi_resource_address address;
3603|};
3604|
3605|
3606|
3607|struct acpi_resource {
3608| u32 type;
3609| u32 length;
3610| union acpi_resource_data data;
3611|};
3612|
3613|
3614|
3615|
3616|
3617|
3618|
3619|
3620|
3621|
3622|struct acpi_pci_routing_table {
3623| u32 length;
3624| u32 pin;
3625| u64 address;
3626| u32 source_index;
3627| char source[4];
3628|};
3629|typedef enum {
3630| OSL_GLOBAL_LOCK_HANDLER,
3631| OSL_NOTIFY_HANDLER,
3632| OSL_GPE_HANDLER,
3633| OSL_DEBUGGER_THREAD,
3634| OSL_EC_POLL_HANDLER,
3635| OSL_EC_BURST_HANDLER
3636|} acpi_execute_type;
3637|struct acpi_signal_fatal_info {
3638| u32 type;
3639| u32 code;
3640| u32 argument;
3641|};
3642|
3643|
3644|
3645|
3646|acpi_status acpi_os_initialize(void);
3647|
3648|acpi_status acpi_os_terminate(void);
3649|
3650|
3651|
3652|
3653|acpi_physical_address acpi_os_get_root_pointer(void);
3654|
3655|acpi_status
3656|acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
3657| acpi_string * new_val);
3658|
3659|acpi_status
3660|acpi_os_table_override(struct acpi_table_header *existing_table,
3661| struct acpi_table_header **new_table);
3662|
3663|
3664|
3665|
3666|void acpi_os_delete_lock(spinlock_t * handle);
3667|
3668|unsigned long acpi_os_acquire_lock(spinlock_t * handle);
3669|
3670|void acpi_os_release_lock(spinlock_t * handle, unsigned long flags);
3671|
3672|
3673|
3674|
3675|acpi_status
3676|acpi_os_create_semaphore(u32 max_units,
3677| u32 initial_units, void * * out_handle);
3678|
3679|acpi_status acpi_os_delete_semaphore(void * handle);
3680|
3681|acpi_status
3682|acpi_os_wait_semaphore(void * handle, u32 units, u16 timeout);
3683|
3684|acpi_status acpi_os_signal_semaphore(void * handle, u32 units);
3685|void *acpi_os_allocate(acpi_size size);
3686|
3687|void *acpi_os_map_memory(acpi_physical_address where,
3688| acpi_size length);
3689|
3690|void acpi_os_unmap_memory(void * logical_address, acpi_size size);
3691|void early_acpi_os_unmap_memory(void * virt, acpi_size size);
3692|acpi_status
3693|acpi_os_create_cache(char *cache_name,
3694| u16 object_size,
3695| u16 max_depth, struct kmem_cache ** return_cache);
3696|
3697|acpi_status acpi_os_delete_cache(struct kmem_cache * cache);
3698|
3699|acpi_status acpi_os_purge_cache(struct kmem_cache * cache);
3700|
3701|void *acpi_os_acquire_object(struct kmem_cache * cache);
3702|
3703|acpi_status acpi_os_release_object(struct kmem_cache * cache, void *object);
3704|
3705|
3706|
3707|
3708|acpi_status
3709|acpi_os_install_interrupt_handler(u32 gsi,
3710| acpi_osd_handler service_routine,
3711| void *context);
3712|
3713|acpi_status
3714|acpi_os_remove_interrupt_handler(u32 gsi, acpi_osd_handler service_routine);
3715|
3716|void acpi_os_gpe_count(u32 gpe_number);
3717|void acpi_os_fixed_event_count(u32 fixed_event_number);
3718|
3719|
3720|
3721|
3722|u64 acpi_os_get_thread_id(void);
3723|
3724|acpi_status
3725|acpi_os_execute(acpi_execute_type type,
3726| acpi_osd_exec_callback function, void *context);
3727|
3728|acpi_status
3729|acpi_os_hotplug_execute(acpi_osd_exec_callback function, void *context);
3730|
3731|void acpi_os_wait_events_complete(void *context);
3732|
3733|void acpi_os_sleep(u64 milliseconds);
3734|
3735|void acpi_os_stall(u32 microseconds);
3736|
3737|
3738|
3739|
3740|acpi_status acpi_os_read_port(acpi_io_address address, u32 * value, u32 width);
3741|
3742|acpi_status acpi_os_write_port(acpi_io_address address, u32 value, u32 width);
3743|
3744|
3745|
3746|
3747|acpi_status
3748|acpi_os_read_memory(acpi_physical_address address, u32 * value, u32 width);
3749|
3750|acpi_status
3751|acpi_os_write_memory(acpi_physical_address address, u32 value, u32 width);
3752|
3753|
3754|
3755|
3756|
3757|
3758|acpi_status
3759|acpi_os_read_pci_configuration(struct acpi_pci_id *pci_id,
3760| u32 reg, u64 *value, u32 width);
3761|
3762|acpi_status
3763|acpi_os_write_pci_configuration(struct acpi_pci_id *pci_id,
3764| u32 reg, u64 value, u32 width);
3765|
3766|
3767|
3768|
3769|acpi_status
3770|acpi_os_validate_address(u8 space_id, acpi_physical_address address,
3771| acpi_size length, char *name);
3772|acpi_status
3773|acpi_os_invalidate_address(u8 space_id, acpi_physical_address address,
3774| acpi_size length);
3775|
3776|u64 acpi_os_get_timer(void);
3777|
3778|acpi_status acpi_os_signal(u32 function, void *info);
3779|
3780|
3781|
3782|
3783|void acpi_os_printf(const char *format, ...);
3784|
3785|void acpi_os_vprintf(const char *format, int args);
3786|
3787|void acpi_os_redirect_output(void *destination);
3788|void *acpi_os_open_directory(char *pathname,
3789| char *wildcard_spec, char requested_file_type);
3790|
3791|
3792|
3793|
3794|
3795|
3796|char *acpi_os_get_next_filename(void *dir_handle);
3797|
3798|void acpi_os_close_directory(void *dir_handle);
3799|extern u8 acpi_gbl_permanent_mmap;
3800|
3801|
3802|
3803|
3804|
3805|extern u32 acpi_dbg_level;
3806|extern u32 acpi_dbg_layer;
3807|extern u8 acpi_gbl_enable_interpreter_slack;
3808|extern u8 acpi_gbl_all_methods_serialized;
3809|extern u8 acpi_gbl_create_osi_method;
3810|extern u8 acpi_gbl_use_default_register_widths;
3811|extern acpi_name acpi_gbl_trace_method_name;
3812|extern u32 acpi_gbl_trace_flags;
3813|extern u32 acpi_gbl_enable_aml_debug_object;
3814|extern u8 acpi_gbl_copy_dsdt_locally;
3815|extern u8 acpi_gbl_truncate_io_addresses;
3816|
3817|extern u32 acpi_current_gpe_count;
3818|extern struct acpi_table_fadt acpi_gbl_FADT;
3819|extern u8 acpi_gbl_system_awake_and_running;
3820|
3821|extern u32 acpi_rsdt_forced;
3822|
3823|
3824|
3825|acpi_status
3826|acpi_initialize_tables(struct acpi_table_desc *initial_storage,
3827| u32 initial_table_count, u8 allow_resize);
3828|
3829|acpi_status acpi_initialize_subsystem(void);
3830|
3831|acpi_status acpi_enable_subsystem(u32 flags);
3832|
3833|acpi_status acpi_initialize_objects(u32 flags);
3834|
3835|acpi_status acpi_terminate(void);
3836|
3837|
3838|
3839|
3840|
3841|acpi_status acpi_enable(void);
3842|
3843|acpi_status acpi_disable(void);
3844|
3845|
3846|
3847|
3848|
3849|const char *acpi_format_exception(acpi_status exception);
3850|
3851|acpi_status acpi_purge_cached_objects(void);
3852|
3853|acpi_status acpi_install_interface(acpi_string interface_name);
3854|
3855|acpi_status acpi_remove_interface(acpi_string interface_name);
3856|
3857|
3858|
3859|
3860|void *acpi_allocate(u32 size);
3861|
3862|void *acpi_callocate(u32 size);
3863|
3864|void acpi_free(void *address);
3865|
3866|
3867|
3868|
3869|acpi_status acpi_reallocate_root_table(void);
3870|
3871|acpi_status acpi_find_root_pointer(acpi_size *rsdp_address);
3872|
3873|acpi_status acpi_load_tables(void);
3874|
3875|acpi_status acpi_load_table(struct acpi_table_header *table_ptr);
3876|
3877|acpi_status acpi_unload_table_id(acpi_owner_id id);
3878|
3879|acpi_status
3880|acpi_get_table_header(acpi_string signature,
3881| u32 instance,
3882| struct acpi_table_header *out_table_header);
3883|
3884|acpi_status
3885|acpi_get_table_with_size(acpi_string signature,
3886| u32 instance, struct acpi_table_header **out_table,
3887| acpi_size *tbl_size);
3888|acpi_status
3889|acpi_get_table(acpi_string signature,
3890| u32 instance, struct acpi_table_header **out_table);
3891|
3892|acpi_status
3893|acpi_get_table_by_index(u32 table_index,
3894| struct acpi_table_header **out_table);
3895|
3896|acpi_status
3897|acpi_install_table_handler(acpi_tbl_handler handler, void *context);
3898|
3899|acpi_status acpi_remove_table_handler(acpi_tbl_handler handler);
3900|
3901|
3902|
3903|
3904|acpi_status
3905|acpi_walk_namespace(acpi_object_type type,
3906| acpi_handle start_object,
3907| u32 max_depth,
3908| acpi_walk_callback pre_order_visit,
3909| acpi_walk_callback post_order_visit,
3910| void *context, void **return_value);
3911|
3912|acpi_status
3913|acpi_get_devices(const char *HID,
3914| acpi_walk_callback user_function,
3915| void *context, void **return_value);
3916|
3917|acpi_status
3918|acpi_get_name(acpi_handle object,
3919| u32 name_type, struct acpi_buffer *ret_path_ptr);
3920|
3921|acpi_status
3922|acpi_get_handle(acpi_handle parent,
3923| acpi_string pathname, acpi_handle * ret_handle);
3924|
3925|acpi_status
3926|acpi_attach_data(acpi_handle object, acpi_object_handler handler, void *data);
3927|
3928|acpi_status acpi_detach_data(acpi_handle object, acpi_object_handler handler);
3929|
3930|acpi_status
3931|acpi_get_data(acpi_handle object, acpi_object_handler handler, void **data);
3932|
3933|acpi_status
3934|acpi_debug_trace(char *name, u32 debug_level, u32 debug_layer, u32 flags);
3935|
3936|
3937|
3938|
3939|acpi_status
3940|acpi_evaluate_object(acpi_handle object,
3941| acpi_string pathname,
3942| struct acpi_object_list *parameter_objects,
3943| struct acpi_buffer *return_object_buffer);
3944|
3945|acpi_status
3946|acpi_evaluate_object_typed(acpi_handle object,
3947| acpi_string pathname,
3948| struct acpi_object_list *external_params,
3949| struct acpi_buffer *return_buffer,
3950| acpi_object_type return_type);
3951|
3952|acpi_status
3953|acpi_get_object_info(acpi_handle object,
3954| struct acpi_device_info **return_buffer);
3955|
3956|acpi_status acpi_install_method(u8 *buffer);
3957|
3958|acpi_status
3959|acpi_get_next_object(acpi_object_type type,
3960| acpi_handle parent,
3961| acpi_handle child, acpi_handle * out_handle);
3962|
3963|acpi_status acpi_get_type(acpi_handle object, acpi_object_type * out_type);
3964|
3965|acpi_status acpi_get_id(acpi_handle object, acpi_owner_id * out_type);
3966|
3967|acpi_status acpi_get_parent(acpi_handle object, acpi_handle * out_handle);
3968|
3969|
3970|
3971|
3972|acpi_status
3973|acpi_install_initialization_handler(acpi_init_handler handler, u32 function);
3974|
3975|acpi_status
3976|acpi_install_fixed_event_handler(u32 acpi_event,
3977| acpi_event_handler handler, void *context);
3978|
3979|acpi_status
3980|acpi_remove_fixed_event_handler(u32 acpi_event, acpi_event_handler handler);
3981|
3982|acpi_status
3983|acpi_install_notify_handler(acpi_handle device,
3984| u32 handler_type,
3985| acpi_notify_handler handler, void *context);
3986|
3987|acpi_status
3988|acpi_remove_notify_handler(acpi_handle device,
3989| u32 handler_type, acpi_notify_handler handler);
3990|
3991|acpi_status
3992|acpi_install_address_space_handler(acpi_handle device,
3993| acpi_adr_space_type space_id,
3994| acpi_adr_space_handler handler,
3995| acpi_adr_space_setup setup, void *context);
3996|
3997|acpi_status
3998|acpi_remove_address_space_handler(acpi_handle device,
3999| acpi_adr_space_type space_id,
4000| acpi_adr_space_handler handler);
4001|
4002|acpi_status
4003|acpi_install_gpe_handler(acpi_handle gpe_device,
4004| u32 gpe_number,
4005| u32 type, acpi_event_handler address, void *context);
4006|
4007|acpi_status
4008|acpi_remove_gpe_handler(acpi_handle gpe_device,
4009| u32 gpe_number, acpi_event_handler address);
4010|
4011|
4012|
4013|
4014|
4015|acpi_status acpi_install_interface_handler(acpi_interface_handler handler);
4016|
4017|
4018|
4019|
4020|acpi_status acpi_acquire_global_lock(u16 timeout, u32 * handle);
4021|
4022|acpi_status acpi_release_global_lock(u32 handle);
4023|
4024|acpi_status acpi_enable_event(u32 event, u32 flags);
4025|
4026|acpi_status acpi_disable_event(u32 event, u32 flags);
4027|
4028|acpi_status acpi_clear_event(u32 event);
4029|
4030|acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status);
4031|
4032|
4033|
4034|
4035|acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number);
4036|
4037|acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number);
4038|
4039|acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number);
4040|
4041|acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number);
4042|
4043|acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action);
4044|
4045|acpi_status
4046|acpi_get_gpe_status(acpi_handle gpe_device,
4047| u32 gpe_number, acpi_event_status *event_status);
4048|
4049|acpi_status acpi_disable_all_gpes(void);
4050|
4051|acpi_status acpi_enable_all_runtime_gpes(void);
4052|
4053|acpi_status acpi_get_gpe_device(u32 gpe_index, acpi_handle *gpe_device);
4054|
4055|acpi_status
4056|acpi_install_gpe_block(acpi_handle gpe_device,
4057| struct acpi_generic_address *gpe_block_address,
4058| u32 register_count, u32 interrupt_number);
4059|
4060|acpi_status acpi_remove_gpe_block(acpi_handle gpe_device);
4061|
4062|acpi_status acpi_update_gpes(void);
4063|
4064|
4065|
4066|
4067|typedef
4068|acpi_status(*acpi_walk_resource_callback) (struct acpi_resource * resource,
4069| void *context);
4070|
4071|acpi_status
4072|acpi_get_vendor_resource(acpi_handle device,
4073| char *name,
4074| struct acpi_vendor_uuid *uuid,
4075| struct acpi_buffer *ret_buffer);
4076|
4077|acpi_status
4078|acpi_get_current_resources(acpi_handle device, struct acpi_buffer *ret_buffer);
4079|
4080|
4081|
4082|
4083|
4084|
4085|acpi_status
4086|acpi_walk_resources(acpi_handle device,
4087| char *name,
4088| acpi_walk_resource_callback user_function, void *context);
4089|
4090|acpi_status
4091|acpi_set_current_resources(acpi_handle device, struct acpi_buffer *in_buffer);
4092|
4093|acpi_status
4094|acpi_get_irq_routing_table(acpi_handle device, struct acpi_buffer *ret_buffer);
4095|
4096|acpi_status
4097|acpi_resource_to_address64(struct acpi_resource *resource,
4098| struct acpi_resource_address64 *out);
4099|
4100|
4101|
4102|
4103|acpi_status acpi_reset(void);
4104|
4105|acpi_status acpi_read_bit_register(u32 register_id, u32 *return_value);
4106|
4107|acpi_status acpi_write_bit_register(u32 register_id, u32 value);
4108|
4109|acpi_status acpi_set_firmware_waking_vector(u32 physical_address);
4110|
4111|
4112|acpi_status acpi_set_firmware_waking_vector64(u64 physical_address);
4113|
4114|
4115|acpi_status acpi_read(u64 *value, struct acpi_generic_address *reg);
4116|
4117|acpi_status acpi_write(u64 value, struct acpi_generic_address *reg);
4118|
4119|acpi_status
4120|acpi_get_sleep_type_data(u8 sleep_state, u8 * slp_typ_a, u8 * slp_typ_b);
4121|
4122|acpi_status acpi_enter_sleep_state_prep(u8 sleep_state);
4123|
4124|acpi_status acpi_enter_sleep_state(u8 sleep_state);
4125|
4126|acpi_status acpi_enter_sleep_state_s4bios(void);
4127|
4128|acpi_status acpi_leave_sleep_state_prep(u8 sleep_state);
4129|
4130|acpi_status acpi_leave_sleep_state(u8 sleep_state);
4131|
4132|
4133|
4134|
4135|void
4136|acpi_error(const char *module_name,
4137| u32 line_number, const char *format, ...) ;
4138|
4139|void
4140|acpi_exception(const char *module_name,
4141| u32 line_number,
4142| acpi_status status, const char *format, ...) ;
4143|
4144|void
4145|acpi_warning(const char *module_name,
4146| u32 line_number, const char *format, ...) ;
4147|
4148|void
4149|acpi_info(const char *module_name,
4150| u32 line_number, const char *format, ...) ;
4151|struct acpi_handle_list {
4152| u32 count;
4153| acpi_handle handles[10];
4154|};
4155|
4156|
4157|acpi_status
4158|acpi_extract_package(union acpi_object *package,
4159| struct acpi_buffer *format, struct acpi_buffer *buffer);
4160|acpi_status
4161|acpi_evaluate_integer(acpi_handle handle,
4162| acpi_string pathname,
4163| struct acpi_object_list *arguments, unsigned long long *data);
4164|acpi_status
4165|acpi_evaluate_reference(acpi_handle handle,
4166| acpi_string pathname,
4167| struct acpi_object_list *arguments,
4168| struct acpi_handle_list *list);
4169|
4170|
4171|
4172|
4173|
4174|
4175|extern struct proc_dir_entry *acpi_root_dir;
4176|
4177|enum acpi_bus_removal_type {
4178| ACPI_BUS_REMOVAL_NORMAL = 0,
4179| ACPI_BUS_REMOVAL_EJECT,
4180| ACPI_BUS_REMOVAL_SUPRISE,
4181| ACPI_BUS_REMOVAL_TYPE_COUNT
4182|};
4183|
4184|enum acpi_bus_device_type {
4185| ACPI_BUS_TYPE_DEVICE = 0,
4186| ACPI_BUS_TYPE_POWER,
4187| ACPI_BUS_TYPE_PROCESSOR,
4188| ACPI_BUS_TYPE_THERMAL,
4189| ACPI_BUS_TYPE_POWER_BUTTON,
4190| ACPI_BUS_TYPE_SLEEP_BUTTON,
4191| ACPI_BUS_DEVICE_TYPE_COUNT
4192|};
4193|
4194|struct acpi_driver;
4195|struct acpi_device;
4196|
4197|
4198|
4199|
4200|
4201|
4202|typedef int (*acpi_op_add) (struct acpi_device * device);
4203|typedef int (*acpi_op_remove) (struct acpi_device * device, int type);
4204|typedef int (*acpi_op_start) (struct acpi_device * device);
4205|typedef int (*acpi_op_suspend) (struct acpi_device * device,
4206| pm_message_t state);
4207|typedef int (*acpi_op_resume) (struct acpi_device * device);
4208|typedef int (*acpi_op_bind) (struct acpi_device * device);
4209|typedef int (*acpi_op_unbind) (struct acpi_device * device);
4210|typedef void (*acpi_op_notify) (struct acpi_device * device, u32 event);
4211|
4212|struct acpi_bus_ops {
4213| u32 acpi_op_add:1;
4214| u32 acpi_op_start:1;
4215|};
4216|
4217|struct acpi_device_ops {
4218| acpi_op_add add;
4219| acpi_op_remove remove;
4220| acpi_op_start start;
4221| acpi_op_suspend suspend;
4222| acpi_op_resume resume;
4223| acpi_op_bind bind;
4224| acpi_op_unbind unbind;
4225| acpi_op_notify notify;
4226|};
4227|
4228|
4229|
4230|struct acpi_driver {
4231| char name[80];
4232| char class[80];
4233| const struct acpi_device_id *ids;
4234| unsigned int flags;
4235| struct acpi_device_ops ops;
4236| struct device_driver drv;
4237| struct module *owner;
4238|};
4239|struct acpi_device_status {
4240| u32 present:1;
4241| u32 enabled:1;
4242| u32 show_in_ui:1;
4243| u32 functional:1;
4244| u32 battery_present:1;
4245| u32 reserved:27;
4246|};
4247|
4248|
4249|
4250|struct acpi_device_flags {
4251| u32 dynamic_status:1;
4252| u32 bus_address:1;
4253| u32 removable:1;
4254| u32 ejectable:1;
4255| u32 lockable:1;
4256| u32 suprise_removal_ok:1;
4257| u32 power_manageable:1;
4258| u32 performance_manageable:1;
4259| u32 wake_capable:1;
4260| u32 force_power_state:1;
4261| u32 reserved:22;
4262|};
4263|
4264|
4265|
4266|struct acpi_device_dir {
4267| struct proc_dir_entry *entry;
4268|};
4269|
4270|
4271|
4272|
4273|
4274|typedef char acpi_bus_id[8];
4275|typedef unsigned long acpi_bus_address;
4276|typedef char acpi_device_name[40];
4277|typedef char acpi_device_class[20];
4278|
4279|struct acpi_hardware_id {
4280| struct list_head list;
4281| char *id;
4282|};
4283|
4284|struct acpi_device_pnp {
4285| acpi_bus_id bus_id;
4286| acpi_bus_address bus_address;
4287| char *unique_id;
4288| struct list_head ids;
4289| acpi_device_name device_name;
4290| acpi_device_class device_class;
4291|};
4292|
4293|
4294|
4295|const char *acpi_device_hid(struct acpi_device *device);
4296|
4297|
4298|
4299|
4300|
4301|struct acpi_device_power_flags {
4302| u32 explicit_get:1;
4303| u32 power_resources:1;
4304| u32 inrush_current:1;
4305| u32 power_removed:1;
4306| u32 reserved:28;
4307|};
4308|
4309|struct acpi_device_power_state {
4310| struct {
4311| u8 valid:1;
4312| u8 explicit_set:1;
4313| u8 reserved:6;
4314| } flags;
4315| int power;
4316| int latency;
4317| struct acpi_handle_list resources;
4318|};
4319|
4320|struct acpi_device_power {
4321| int state;
4322| struct acpi_device_power_flags flags;
4323| struct acpi_device_power_state states[4];
4324|};
4325|
4326|
4327|
4328|struct acpi_device_perf_flags {
4329| u8 reserved:8;
4330|};
4331|
4332|struct acpi_device_perf_state {
4333| struct {
4334| u8 valid:1;
4335| u8 reserved:7;
4336| } flags;
4337| u8 power;
4338| u8 performance;
4339| int latency;
4340|};
4341|
4342|struct acpi_device_perf {
4343| int state;
4344| struct acpi_device_perf_flags flags;
4345| int state_count;
4346| struct acpi_device_perf_state *states;
4347|};
4348|
4349|
4350|struct acpi_device_wakeup_flags {
4351| u8 valid:1;
4352| u8 run_wake:1;
4353| u8 always_enabled:1;
4354| u8 notifier_present:1;
4355|};
4356|
4357|struct acpi_device_wakeup_state {
4358| u8 enabled:1;
4359|};
4360|
4361|struct acpi_device_wakeup {
4362| acpi_handle gpe_device;
4363| u64 gpe_number;
4364| u64 sleep_state;
4365| struct acpi_handle_list resources;
4366| struct acpi_device_wakeup_state state;
4367| struct acpi_device_wakeup_flags flags;
4368| int prepare_count;
4369| int run_wake_count;
4370|};
4371|
4372|
4373|
4374|struct acpi_device {
4375| int device_type;
4376| acpi_handle handle;
4377| struct acpi_device *parent;
4378| struct list_head children;
4379| struct list_head node;
4380| struct list_head wakeup_list;
4381| struct acpi_device_status status;
4382| struct acpi_device_flags flags;
4383| struct acpi_device_pnp pnp;
4384| struct acpi_device_power power;
4385| struct acpi_device_wakeup wakeup;
4386| struct acpi_device_perf performance;
4387| struct acpi_device_dir dir;
4388| struct acpi_device_ops ops;
4389| struct acpi_driver *driver;
4390| void *driver_data;
4391| struct device dev;
4392| struct acpi_bus_ops bus_ops;
4393| enum acpi_bus_removal_type removal_type;
4394|};
4395|
4396|static inline void *acpi_driver_data(struct acpi_device *d)
4397|{
4398| return d->driver_data;
4399|}
4400|
4401|
4402|
4403|
4404|
4405|extern struct bus_type acpi_bus_type;
4406|
4407|
4408|
4409|
4410|
4411|
4412|struct acpi_bus_event {
4413| struct list_head node;
4414| acpi_device_class device_class;
4415| acpi_bus_id bus_id;
4416| u32 type;
4417| u32 data;
4418|};
4419|
4420|extern struct kobject *acpi_kobj;
4421|extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int);
4422|void acpi_bus_private_data_handler(acpi_handle, void *);
4423|int acpi_bus_get_private_data(acpi_handle, void **);
4424|extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32);
4425|extern int register_acpi_notifier(struct notifier_block *);
4426|extern int unregister_acpi_notifier(struct notifier_block *);
4427|
4428|extern int register_acpi_bus_notifier(struct notifier_block *nb);
4429|extern void unregister_acpi_bus_notifier(struct notifier_block *nb);
4430|
4431|
4432|
4433|
4434|int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device);
4435|void acpi_bus_data_handler(acpi_handle handle, void *context);
4436|acpi_status acpi_bus_get_status_handle(acpi_handle handle,
4437| unsigned long long *sta);
4438|int acpi_bus_get_status(struct acpi_device *device);
4439|int acpi_bus_get_power(acpi_handle handle, int *state);
4440|int acpi_bus_set_power(acpi_handle handle, int state);
4441|bool acpi_bus_power_manageable(acpi_handle handle);
4442|bool acpi_bus_can_wakeup(acpi_handle handle);
4443|
4444|int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data);
4445|int acpi_bus_generate_proc_event4(const char *class, const char *bid, u8 type, int data);
4446|int acpi_bus_receive_event(struct acpi_bus_event *event);
4447|
4448|
4449|
4450|
4451|int acpi_bus_register_driver(struct acpi_driver *driver);
4452|void acpi_bus_unregister_driver(struct acpi_driver *driver);
4453|int acpi_bus_add(struct acpi_device **child, struct acpi_device *parent,
4454| acpi_handle handle, int type);
4455|int acpi_bus_trim(struct acpi_device *start, int rmdevice);
4456|int acpi_bus_start(struct acpi_device *device);
4457|acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd);
4458|int acpi_match_device_ids(struct acpi_device *device,
4459| const struct acpi_device_id *ids);
4460|int acpi_create_dir(struct acpi_device *);
4461|void acpi_remove_dir(struct acpi_device *);
4462|
4463|
4464|
4465|
4466|struct acpi_bus_type {
4467| struct list_head list;
4468| struct bus_type *bus;
4469|
4470| int (*find_device) (struct device *, acpi_handle *);
4471|
4472| int (*find_bridge) (struct device *, acpi_handle *);
4473|};
4474|int register_acpi_bus_type(struct acpi_bus_type *);
4475|int unregister_acpi_bus_type(struct acpi_bus_type *);
4476|struct device *acpi_get_physical_device(acpi_handle);
4477|
4478|struct acpi_pci_root {
4479| struct list_head node;
4480| struct acpi_device * device;
4481| struct acpi_pci_id id;
4482| struct pci_bus *bus;
4483| u16 segment;
4484| struct resource secondary;
4485|
4486| u32 osc_support_set;
4487| u32 osc_control_set;
4488|};
4489|
4490|
4491|acpi_handle acpi_get_child(acpi_handle, u64);
4492|int acpi_is_root_bridge(acpi_handle);
4493|acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
4494|struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle);
4495|
4496|
4497|int acpi_enable_wakeup_device_power(struct acpi_device *dev, int state);
4498|int acpi_disable_wakeup_device_power(struct acpi_device *dev);
4499|
4500|
4501|int acpi_pm_device_sleep_state(struct device *, int *);
4502|int acpi_pm_device_sleep_wake(struct device *, bool);
4503|int acpi_irq_penalty_init(void);
4504|int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering,
4505| int *polarity, char **name);
4506|int acpi_pci_link_free_irq(acpi_handle handle);
4507|
4508|
4509|
4510|int acpi_pci_irq_add_prt(acpi_handle handle, struct pci_bus *bus);
4511|void acpi_pci_irq_del_prt(struct pci_bus *bus);
4512|
4513|
4514|
4515|struct pci_bus;
4516|
4517|struct pci_dev *acpi_get_pci_dev(acpi_handle);
4518|int acpi_pci_bind_root(struct acpi_device *device);
4519|
4520|
4521|
4522|struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root);
4523|void pci_acpi_crs_quirks(void);
4524|struct acpi_dock_ops {
4525| acpi_notify_handler handler;
4526| acpi_notify_handler uevent;
4527|};
4528|
4529|
4530|extern int is_dock_device(acpi_handle handle);
4531|extern int register_dock_notifier(struct notifier_block *nb);
4532|extern void unregister_dock_notifier(struct notifier_block *nb);
4533|extern int register_hotplug_dock_device(acpi_handle handle,
4534| struct acpi_dock_ops *ops,
4535| void *context);
4536|extern void unregister_hotplug_dock_device(acpi_handle handle);
4537|extern int pxm_to_node(int);
4538|extern int node_to_pxm(int);
4539|extern void __acpi_map_pxm_to_node(int, int);
4540|extern int acpi_map_pxm_to_node(int);
4541|
4542|
4543|enum acpi_irq_model_id {
4544| ACPI_IRQ_MODEL_PIC = 0,
4545| ACPI_IRQ_MODEL_IOAPIC,
4546| ACPI_IRQ_MODEL_IOSAPIC,
4547| ACPI_IRQ_MODEL_PLATFORM,
4548| ACPI_IRQ_MODEL_COUNT
4549|};
4550|
4551|extern enum acpi_irq_model_id acpi_irq_model;
4552|
4553|enum acpi_interrupt_id {
4554| ACPI_INTERRUPT_PMI = 1,
4555| ACPI_INTERRUPT_INIT,
4556| ACPI_INTERRUPT_CPEI,
4557| ACPI_INTERRUPT_COUNT
4558|};
4559|
4560|
4561|
4562|enum acpi_address_range_id {
4563| ACPI_ADDRESS_RANGE_MEMORY = 1,
4564| ACPI_ADDRESS_RANGE_RESERVED = 2,
4565| ACPI_ADDRESS_RANGE_ACPI = 3,
4566| ACPI_ADDRESS_RANGE_NVS = 4,
4567| ACPI_ADDRESS_RANGE_COUNT
4568|};
4569|
4570|
4571|
4572|
4573|typedef int (*acpi_table_handler) (struct acpi_table_header *table);
4574|
4575|typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end);
4576|
4577|char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
4578|void __acpi_unmap_table(char *map, unsigned long size);
4579|int early_acpi_boot_init(void);
4580|int acpi_boot_init (void);
4581|void acpi_boot_table_init (void);
4582|int acpi_mps_check (void);
4583|int acpi_numa_init (void);
4584|
4585|int acpi_table_init (void);
4586|int acpi_table_parse (char *id, acpi_table_handler handler);
4587|int acpi_table_parse_entries(char *id, unsigned long table_size,
4588| int entry_id, acpi_table_entry_handler handler, unsigned int max_entries);
4589|int acpi_table_parse_madt (enum acpi_madt_type id, acpi_table_entry_handler handler, unsigned int max_entries);
4590|int acpi_parse_mcfg (struct acpi_table_header *header);
4591|void acpi_table_print_madt_entry (struct acpi_subtable_header *madt);
4592|
4593|
4594|void acpi_numa_slit_init (struct acpi_table_slit *slit);
4595|void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa);
4596|void acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa);
4597|void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);
4598|void acpi_numa_arch_fixup(void);
4599|
4600|
4601|
4602|int acpi_map_lsapic(acpi_handle handle, int *pcpu);
4603|int acpi_unmap_lsapic(int cpu);
4604|
4605|
4606|int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base);
4607|int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base);
4608|void acpi_irq_stats_init(void);
4609|extern u32 acpi_irq_handled;
4610|extern u32 acpi_irq_not_handled;
4611|
4612|extern int sbf_port;
4613|extern unsigned long acpi_realmode_flags;
4614|
4615|int acpi_register_gsi (struct device *dev, u32 gsi, int triggering, int polarity);
4616|int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
4617|int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi);
4618|
4619|
4620|extern int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity);
4621|void acpi_unregister_gsi (u32 gsi);
4622|
4623|struct pci_dev;
4624|
4625|int acpi_pci_irq_enable (struct pci_dev *dev);
4626|void acpi_penalize_isa_irq(int irq, int active);
4627|
4628|void acpi_pci_irq_disable (struct pci_dev *dev);
4629|
4630|struct acpi_pci_driver {
4631| struct acpi_pci_driver *next;
4632| int (*add)(acpi_handle handle);
4633| void (*remove)(acpi_handle handle);
4634|};
4635|
4636|int acpi_pci_register_driver(struct acpi_pci_driver *driver);
4637|void acpi_pci_unregister_driver(struct acpi_pci_driver *driver);
4638|
4639|extern int ec_read(u8 addr, u8 *val);
4640|extern int ec_write(u8 addr, u8 val);
4641|extern int ec_transaction(u8 command,
4642| const u8 *wdata, unsigned wdata_len,
4643| u8 *rdata, unsigned rdata_len,
4644| int force_poll);
4645|
4646|
4647|
4648|typedef void (*wmi_notify_handler) (u32 value, void *context);
4649|
4650|extern acpi_status wmi_evaluate_method(const char *guid, u8 instance,
4651| u32 method_id,
4652| const struct acpi_buffer *in,
4653| struct acpi_buffer *out);
4654|extern acpi_status wmi_query_block(const char *guid, u8 instance,
4655| struct acpi_buffer *out);
4656|extern acpi_status wmi_set_block(const char *guid, u8 instance,
4657| const struct acpi_buffer *in);
4658|extern acpi_status wmi_install_notify_handler(const char *guid,
4659| wmi_notify_handler handler, void *data);
4660|extern acpi_status wmi_remove_notify_handler(const char *guid);
4661|extern acpi_status wmi_get_event_data(u32 event, struct acpi_buffer *out);
4662|extern bool wmi_has_guid(const char *guid);
4663|extern long acpi_video_get_capabilities(acpi_handle graphics_dev_handle);
4664|extern long acpi_is_video_device(struct acpi_device *device);
4665|extern int acpi_video_backlight_support(void);
4666|extern int acpi_video_display_switch_support(void);
4667|extern int acpi_blacklisted(void);
4668|extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d);
4669|extern int acpi_osi_setup(char *str);
4670|
4671|
4672|int acpi_get_pxm(acpi_handle handle);
4673|int acpi_get_node(acpi_handle *handle);
4674|extern int acpi_paddr_to_node(u64 start_addr, u64 size);
4675|
4676|extern int pnpacpi_disabled;
4677|
4678|
4679|
4680|
4681|int acpi_check_resource_conflict(const struct resource *res);
4682|
4683|int acpi_check_region(resource_size_t start, resource_size_t n,
4684| const char *name);
4685|
4686|int acpi_resources_are_enforced(void);
4687|
4688|
4689|void acpi_no_s4_hw_signature(void);
4690|void acpi_old_suspend_ordering(void);
4691|void acpi_nvs_nosave(void);
4692|
4693|
4694|struct acpi_osc_context {
4695| char *uuid_str;
4696| int rev;
4697| struct acpi_buffer cap;
4698| struct acpi_buffer ret;
4699|};
4700|acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context);
4701|extern acpi_status acpi_pci_osc_control_set(acpi_handle handle,
4702| u32 *mask, u32 req);
4703|extern void acpi_early_init(void);
4704|
4705|int acpi_os_map_generic_address(struct acpi_generic_address *addr);
4706|void acpi_os_unmap_generic_address(struct acpi_generic_address *addr);
4707|
4708|
4709|
4710|
4711|
4712|
4713|static int acpi_failure;
4714|
4715|
4716|static u32 ipmi_acpi_gpe(void *context)
4717|{
4718| struct smi_info *smi_info = context;
4719| unsigned long flags;
4720|
4721|
4722|
4723|
4724| __st_spin_lock_irqsave_st__(&(smi_info->si_lock), flags);
4725|
4726| atomic_inc(&(smi_info)->stats[SI_STAT_interrupts]);
4727|
4728|
4729|
4730|
4731|
4732| smi_event_handler(smi_info, 0);
4733| __st_spin_unlock_irqrestore_st__(&(smi_info->si_lock), flags);
4734|
4735| return 0x01;
4736|}
4737|
4738|static void acpi_gpe_irq_cleanup(struct smi_info *info)
4739|{
4740| if (!info->irq)
4741| return;
4742|
4743| acpi_remove_gpe_handler(((void *)0), info->irq, &ipmi_acpi_gpe);
4744|}
4745|
4746|static int acpi_gpe_irq_setup(struct smi_info *info)
4747|{
4748| acpi_status status;
4749|
4750| if (!info->irq)
4751| return 0;
4752|
4753|
4754| status = acpi_install_gpe_handler(((void *)0),
4755| info->irq,
4756| (u8) 0x01,
4757| &ipmi_acpi_gpe,
4758| info);
4759| if (status != (acpi_status) 0x0000) {
4760| dev_warn(info->dev, "%s unable to claim ACPI GPE %d,"
4761| " running polled\n", "ipmi_si", info->irq);
4762| info->irq = 0;
4763| return -22;
4764| } else {
4765| info->irq_cleanup = acpi_gpe_irq_cleanup;
4766| _dev_info(info->dev, "Using ACPI GPE %d\n", info->irq);
4767| return 0;
4768| }
4769|}
4770|
4771|
4772|
4773|
4774|
4775|struct SPMITable {
4776| s8 Signature[4];
4777| u32 Length;
4778| u8 Revision;
4779| u8 Checksum;
4780| s8 OEMID[6];
4781| s8 OEMTableID[8];
4782| s8 OEMRevision[4];
4783| s8 CreatorID[4];
4784| s8 CreatorRevision[4];
4785| u8 InterfaceType;
4786| u8 IPMIlegacy;
4787| s16 SpecificationRevision;
4788|
4789|
4790|
4791|
4792|
4793| u8 InterruptType;
4794|
4795|
4796|
4797|
4798|
4799| u8 GPE;
4800|
4801| s16 Reserved;
4802|
4803|
4804|
4805|
4806|
4807| u32 GlobalSystemInterrupt;
4808|
4809|
4810| struct acpi_generic_address addr;
4811|
4812| u8 UID[4];
4813|
4814| s8 spmi_id[1];
4815|};
4816|
4817|static int try_init_spmi(struct SPMITable *spmi)
4818|{
4819| struct smi_info *info;
4820|
4821| if (spmi->IPMIlegacy != 1) {
4822| printk("<6>" "ipmi_si: " "Bad SPMI legacy %d\n", spmi->IPMIlegacy);
4823| return -19;
4824| }
4825|
4826| info = smi_info_alloc();
4827| if (!info) {
4828| printk("<3>" "ipmi_si: " "Could not allocate SI data (3)\n");
4829| return -12;
4830| }
4831|
4832| info->addr_source = SI_SPMI;
4833| printk("<6>" "ipmi_si: " "probing via SPMI\n");
4834|
4835|
4836| switch (spmi->InterfaceType) {
4837| case 1:
4838| info->si_type = SI_KCS;
4839| break;
4840| case 2:
4841| info->si_type = SI_SMIC;
4842| break;
4843| case 3:
4844| info->si_type = SI_BT;
4845| break;
4846| default:
4847| printk("<6>" "ipmi_si: " "Unknown ACPI/SPMI SI type %d\n",
4848| spmi->InterfaceType);
4849| kfree(info);
4850| return -5;
4851| }
4852|
4853| if (spmi->InterruptType & 1) {
4854|
4855| info->irq = spmi->GPE;
4856| info->irq_setup = acpi_gpe_irq_setup;
4857| } else if (spmi->InterruptType & 2) {
4858|
4859| info->irq = spmi->GlobalSystemInterrupt;
4860| info->irq_setup = std_irq_setup;
4861| } else {
4862|
4863| info->irq = 0;
4864| info->irq_setup = ((void *)0);
4865| }
4866|
4867| if (spmi->addr.bit_width) {
4868|
4869| info->io.regspacing = spmi->addr.bit_width / 8;
4870| } else {
4871| info->io.regspacing = 1;
4872| }
4873| info->io.regsize = info->io.regspacing;
4874| info->io.regshift = spmi->addr.bit_offset;
4875|
4876| if (spmi->addr.space_id == (acpi_adr_space_type) 0) {
4877| info->io_setup = mem_setup;
4878| info->io.addr_type = 1;
4879| } else if (spmi->addr.space_id == (acpi_adr_space_type) 1) {
4880| info->io_setup = port_setup;
4881| info->io.addr_type = 0;
4882| } else {
4883| kfree(info);
4884| printk("<4>" "ipmi_si: " "Unknown ACPI I/O Address type\n");
4885| return -5;
4886| }
4887| info->io.addr_data = spmi->addr.address;
4888|
4889| printk("<6>" "ipmi_si: SPMI: %s %#lx regsize %d spacing %d irq %d\n", (info->io.addr_type == 0) ? "io" : "mem", info->io.addr_data, info->io.regsize, info->io.regspacing, info->irq)
4890|
4891|
4892| ;
4893|
4894| if (add_smi(info))
4895| kfree(info);
4896|
4897| return 0;
4898|}
4899|
4900|static void spmi_find_bmc(void)
4901|{
4902| acpi_status status;
4903| struct SPMITable *spmi;
4904| int i;
4905|
4906| if (acpi_disabled)
4907| return;
4908|
4909| if (acpi_failure)
4910| return;
4911|
4912| for (i = 0; ; i++) {
4913| status = acpi_get_table("SPMI", i+1,
4914| (struct acpi_table_header **)&spmi);
4915| if (status != (acpi_status) 0x0000)
4916| return;
4917|
4918| try_init_spmi(spmi);
4919| }
4920|}
4921|
4922|static int ipmi_pnp_probe(struct pnp_dev *dev,
4923| const struct pnp_device_id *dev_id)
4924|{
4925| struct acpi_device *acpi_dev;
4926| struct smi_info *info;
4927| struct resource *res, *res_second;
4928| acpi_handle handle;
4929| acpi_status status;
4930| unsigned long long tmp;
4931|
4932| acpi_dev = pnp_acpi_device(dev);
4933| if (!acpi_dev)
4934| return -19;
4935|
4936| info = smi_info_alloc();
4937| if (!info)
4938| return -12;
4939|
4940| info->addr_source = SI_ACPI;
4941| printk("<6>" "ipmi_si: " "probing via ACPI\n");
4942|
4943| handle = acpi_dev->handle;
4944|
4945|
4946| status = acpi_evaluate_integer(handle, "_IFT", ((void *)0), &tmp);
4947| if ((status))
4948| goto err_free;
4949|
4950| switch (tmp) {
4951| case 1:
4952| info->si_type = SI_KCS;
4953| break;
4954| case 2:
4955| info->si_type = SI_SMIC;
4956| break;
4957| case 3:
4958| info->si_type = SI_BT;
4959| break;
4960| default:
4961| _dev_info(&dev->dev, "unknown IPMI type %lld\n", tmp);
4962| goto err_free;
4963| }
4964|
4965| res = pnp_get_resource(dev, 0x00000100, 0);
4966| if (res) {
4967| info->io_setup = port_setup;
4968| info->io.addr_type = 0;
4969| } else {
4970| res = pnp_get_resource(dev, 0x00000200, 0);
4971| if (res) {
4972| info->io_setup = mem_setup;
4973| info->io.addr_type = 1;
4974| }
4975| }
4976| if (!res) {
4977| dev_err(&dev->dev, "no I/O or memory address\n");
4978| goto err_free;
4979| }
4980| info->io.addr_data = res->start;
4981|
4982| info->io.regspacing = 1;
4983| res_second = pnp_get_resource(dev,
4984| (info->io.addr_type == 0) ?
4985| 0x00000100 : 0x00000200,
4986| 1);
4987| if (res_second) {
4988| if (res_second->start > info->io.addr_data)
4989| info->io.regspacing = res_second->start - info->io.addr_data;
4990| }
4991| info->io.regsize = 1;
4992| info->io.regshift = 0;
4993|
4994|
4995| status = acpi_evaluate_integer(handle, "_GPE", ((void *)0), &tmp);
4996| if ((!(status))) {
4997| info->irq = tmp;
4998| info->irq_setup = acpi_gpe_irq_setup;
4999| } else if (pnp_irq_valid(dev, 0)) {
5000| info->irq = pnp_irq(dev, 0);
5001| info->irq_setup = std_irq_setup;
5002| }
5003|
5004| info->dev = &dev->dev;
5005| pnp_set_drvdata(dev, info);
5006|
5007| _dev_info(info->dev, "%pR regsize %d spacing %d irq %d\n", res, info->io.regsize, info->io.regspacing, info->irq)
5008|
5009| ;
5010|
5011| if (add_smi(info))
5012| goto err_free;
5013|
5014| return 0;
5015|
5016|err_free:
5017| kfree(info);
5018| return -22;
5019|}
5020|
5021|static void ipmi_pnp_remove(struct pnp_dev *dev)
5022|{
5023| struct smi_info *info = pnp_get_drvdata(dev);
5024|
5025| cleanup_one_si(info);
5026|}
5027|
5028|static const struct pnp_device_id pnp_dev_table[] = {
5029| {"IPI0001", 0},
5030| {"", 0},
5031|};
5032|
5033|static struct pnp_driver ipmi_pnp_driver = {
5034| .name = "ipmi_si",
5035| .probe = ipmi_pnp_probe,
5036| .remove = ipmi_pnp_remove,
5037| .id_table = pnp_dev_table,
5038|};
5039|
5040|
5041|
5042|struct dmi_ipmi_data {
5043| u8 type;
5044| u8 addr_space;
5045| unsigned long base_addr;
5046| u8 irq;
5047| u8 offset;
5048| u8 slave_addr;
5049|};
5050|
5051|static int decode_dmi(const struct dmi_header *dm,
5052| struct dmi_ipmi_data *dmi)
5053|{
5054| const u8 *data = (const u8 *)dm;
5055| unsigned long base_addr;
5056| u8 reg_spacing;
5057| u8 len = dm->length;
5058|
5059| dmi->type = data[4];
5060|
5061| __st_memcpy_st__(&base_addr, data+8, sizeof(unsigned long));
5062| if (len >= 0x11) {
5063| if (base_addr & 1) {
5064|
5065| base_addr &= 0xFFFE;
5066| dmi->addr_space = 0;
5067| } else
5068|
5069| dmi->addr_space = 1;
5070|
5071|
5072|
5073| dmi->base_addr = base_addr | ((data[0x10] & 0x10) >> 4);
5074|
5075| dmi->irq = data[0x11];
5076|
5077|
5078| reg_spacing = (data[0x10] & 0xC0) >> 6;
5079| switch (reg_spacing) {
5080| case 0x00:
5081| dmi->offset = 1;
5082| break;
5083| case 0x01:
5084| dmi->offset = 4;
5085| break;
5086| case 0x02:
5087| dmi->offset = 16;
5088| break;
5089| default:
5090|
5091| return -5;
5092| }
5093| } else {
5094| dmi->base_addr = base_addr & 0xfffe;
5095| dmi->addr_space = 0;
5096| dmi->offset = 1;
5097| }
5098|
5099| dmi->slave_addr = data[6];
5100|
5101| return 0;
5102|}
5103|
5104|static void try_init_dmi(struct dmi_ipmi_data *ipmi_data)
5105|{
5106| struct smi_info *info;
5107|
5108| info = smi_info_alloc();
5109| if (!info) {
5110| printk("<3>" "ipmi_si: " "Could not allocate SI data\n");
5111| return;
5112| }
5113|
5114| info->addr_source = SI_SMBIOS;
5115| printk("<6>" "ipmi_si: " "probing via SMBIOS\n");
5116|
5117| switch (ipmi_data->type) {
5118| case 0x01:
5119| info->si_type = SI_KCS;
5120| break;
5121| case 0x02:
5122| info->si_type = SI_SMIC;
5123| break;
5124| case 0x03:
5125| info->si_type = SI_BT;
5126| break;
5127| default:
5128| kfree(info);
5129| return;
5130| }
5131|
5132| switch (ipmi_data->addr_space) {
5133| case 1:
5134| info->io_setup = mem_setup;
5135| info->io.addr_type = 1;
5136| break;
5137|
5138| case 0:
5139| info->io_setup = port_setup;
5140| info->io.addr_type = 0;
5141| break;
5142|
5143| default:
5144| kfree(info);
5145| printk("<4>" "ipmi_si: " "Unknown SMBIOS I/O Address type: %d\n",
5146| ipmi_data->addr_space);
5147| return;
5148| }
5149| info->io.addr_data = ipmi_data->base_addr;
5150|
5151| info->io.regspacing = ipmi_data->offset;
5152| if (!info->io.regspacing)
5153| info->io.regspacing = 1;
5154| info->io.regsize = 1;
5155| info->io.regshift = 0;
5156|
5157| info->slave_addr = ipmi_data->slave_addr;
5158|
5159| info->irq = ipmi_data->irq;
5160| if (info->irq)
5161| info->irq_setup = std_irq_setup;
5162|
5163| printk("<6>" "ipmi_si: SMBIOS: %s %#lx regsize %d spacing %d irq %d\n", (info->io.addr_type == 0) ? "io" : "mem", info->io.addr_data, info->io.regsize, info->io.regspacing, info->irq)
5164|
5165|
5166| ;
5167|
5168| if (add_smi(info))
5169| kfree(info);
5170|}
5171|
5172|static void dmi_find_bmc(void)
5173|{
5174| const struct dmi_device *dev = ((void *)0);
5175| struct dmi_ipmi_data data;
5176| int rv;
5177|
5178| while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, ((void *)0), dev))) {
5179| __st_memset_st__(&data, 0, sizeof(data));
5180| rv = decode_dmi((const struct dmi_header *) dev->device_data,
5181| &data);
5182| if (!rv)
5183| try_init_dmi(&data);
5184| }
5185|}
5186|static void ipmi_pci_cleanup(struct smi_info *info)
5187|{
5188| struct pci_dev *pdev = info->addr_source_data;
5189|
5190| pci_disable_device(pdev);
5191|}
5192|
5193|static int ipmi_pci_probe(struct pci_dev *pdev,
5194| const struct pci_device_id *ent)
5195|{
5196| int rv;
5197| int class_type = pdev->class & 0xff;
5198| struct smi_info *info;
5199|
5200| info = smi_info_alloc();
5201| if (!info)
5202| return -12;
5203|
5204| info->addr_source = SI_PCI;
5205| _dev_info(&pdev->dev, "probing via PCI");
5206|
5207| switch (class_type) {
5208| case 0x00:
5209| info->si_type = SI_SMIC;
5210| break;
5211|
5212| case 0x01:
5213| info->si_type = SI_KCS;
5214| break;
5215|
5216| case 0x02:
5217| info->si_type = SI_BT;
5218| break;
5219|
5220| default:
5221| kfree(info);
5222| _dev_info(&pdev->dev, "Unknown IPMI type: %d\n", class_type);
5223| return -12;
5224| }
5225|
5226| rv = pci_enable_device(pdev);
5227| if (rv) {
5228| dev_err(&pdev->dev, "couldn't enable PCI device\n");
5229| kfree(info);
5230| return rv;
5231| }
5232|
5233| info->addr_source_cleanup = ipmi_pci_cleanup;
5234| info->addr_source_data = pdev;
5235|
5236| if (((pdev)->resource[(0)].flags) & 0x00000100) {
5237| info->io_setup = port_setup;
5238| info->io.addr_type = 0;
5239| } else {
5240| info->io_setup = mem_setup;
5241| info->io.addr_type = 1;
5242| }
5243| info->io.addr_data = ((pdev)->resource[(0)].start);
5244|
5245| info->io.regspacing = 1;
5246| info->io.regsize = 1;
5247| info->io.regshift = 0;
5248|
5249| info->irq = pdev->irq;
5250| if (info->irq)
5251| info->irq_setup = std_irq_setup;
5252|
5253| info->dev = &pdev->dev;
5254| pci_set_drvdata(pdev, info);
5255|
5256| _dev_info(&pdev->dev, "%pR regsize %d spacing %d irq %d\n", &pdev->resource[0], info->io.regsize, info->io.regspacing, info->irq)
5257|
5258| ;
5259|
5260| if (add_smi(info))
5261| kfree(info);
5262|
5263| return 0;
5264|}
5265|
5266|static void ipmi_pci_remove(struct pci_dev *pdev)
5267|{
5268| struct smi_info *info = pci_get_drvdata(pdev);
5269| cleanup_one_si(info);
5270|}
5271|
5272|
5273|static int ipmi_pci_suspend(struct pci_dev *pdev, pm_message_t state)
5274|{
5275| return 0;
5276|}
5277|
5278|static int ipmi_pci_resume(struct pci_dev *pdev)
5279|{
5280| return 0;
5281|}
5282|
5283|
5284|static struct pci_device_id ipmi_pci_devices[] = {
5285| { .vendor = (0x103C), .device = (0x121A), .subvendor = (~0), .subdevice = (~0) },
5286| { .class = (0x0C0700), .class_mask = (0xffffff00), .vendor = (~0), .device = (~0), .subvendor = (~0), .subdevice = (~0) },
5287| { 0, }
5288|};
5289|extern const struct pci_device_id __mod_pci_device_table ;
5290|
5291|static struct pci_driver ipmi_pci_driver = {
5292| .name = "ipmi_si",
5293| .id_table = ipmi_pci_devices,
5294| .probe = ipmi_pci_probe,
5295| .remove = ipmi_pci_remove,
5296|
5297| .suspend = ipmi_pci_suspend,
5298| .resume = ipmi_pci_resume,
5299|
5300|};
5301|static int wait_for_msg_done(struct smi_info *smi_info)
5302|{
5303| enum si_sm_result smi_result;
5304|
5305| smi_result = smi_info->handlers->event(smi_info->si_sm, 0);
5306| for (;;) {
5307| if (smi_result == SI_SM_CALL_WITH_DELAY ||
5308| smi_result == SI_SM_CALL_WITH_TICK_DELAY) {
5309| schedule_timeout_uninterruptible(1);
5310| smi_result = smi_info->handlers->event(
5311| smi_info->si_sm, 100);
5312| } else if (smi_result == SI_SM_CALL_WITHOUT_DELAY) {
5313| smi_result = smi_info->handlers->event(
5314| smi_info->si_sm, 0);
5315| } else
5316| break;
5317| }
5318| if (smi_result == SI_SM_HOSED)
5319|
5320|
5321|
5322|
5323| return -19;
5324|
5325| return 0;
5326|}
5327|
5328|static int try_get_dev_id(struct smi_info *smi_info)
5329|{
5330| unsigned char msg[2];
5331| unsigned char *resp;
5332| unsigned long resp_len;
5333| int rv = 0;
5334|
5335| resp = kmalloc(272, __st_GFP_KERNEL_st__);
5336| if (!resp)
5337| return -12;
5338|
5339|
5340|
5341|
5342|
5343| msg[0] = 0x06 << 2;
5344| msg[1] = 0x01;
5345| smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
5346|
5347| rv = wait_for_msg_done(smi_info);
5348| if (rv)
5349| goto out;
5350|
5351| resp_len = smi_info->handlers->get_result(smi_info->si_sm,
5352| resp, 272);
5353|
5354|
5355| rv = ipmi_demangle_device_id(resp, resp_len, &smi_info->device_id);
5356|
5357| out:
5358| kfree(resp);
5359| return rv;
5360|}
5361|
5362|static int try_enable_event_buffer(struct smi_info *smi_info)
5363|{
5364| unsigned char msg[3];
5365| unsigned char *resp;
5366| unsigned long resp_len;
5367| int rv = 0;
5368|
5369| resp = kmalloc(272, __st_GFP_KERNEL_st__);
5370| if (!resp)
5371| return -12;
5372|
5373| msg[0] = 0x06 << 2;
5374| msg[1] = 0x2f;
5375| smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
5376|
5377| rv = wait_for_msg_done(smi_info);
5378| if (rv) {
5379| printk("<4>" "ipmi_si: " "Error getting response from get"
5380| " global enables command, the event buffer is not"
5381| " enabled.\n");
5382| goto out;
5383| }
5384|
5385| resp_len = smi_info->handlers->get_result(smi_info->si_sm,
5386| resp, 272);
5387|
5388| if (resp_len < 4 ||
5389| resp[0] != (0x06 | 1) << 2 ||
5390| resp[1] != 0x2f ||
5391| resp[2] != 0) {
5392| printk("<4>" "ipmi_si: " "Invalid return from get global"
5393| " enables command, cannot enable the event buffer.\n");
5394| rv = -22;
5395| goto out;
5396| }
5397|
5398| if (resp[3] & 0x04)
5399|
5400| goto out;
5401|
5402| msg[0] = 0x06 << 2;
5403| msg[1] = 0x2e;
5404| msg[2] = resp[3] | 0x04;
5405| smi_info->handlers->start_transaction(smi_info->si_sm, msg, 3);
5406|
5407| rv = wait_for_msg_done(smi_info);
5408| if (rv) {
5409| printk("<4>" "ipmi_si: " "Error getting response from set"
5410| " global, enables command, the event buffer is not"
5411| " enabled.\n");
5412| goto out;
5413| }
5414|
5415| resp_len = smi_info->handlers->get_result(smi_info->si_sm,
5416| resp, 272);
5417|
5418| if (resp_len < 3 ||
5419| resp[0] != (0x06 | 1) << 2 ||
5420| resp[1] != 0x2e) {
5421| printk("<4>" "ipmi_si: " "Invalid return from get global,"
5422| "enables command, not enable the event buffer.\n");
5423| rv = -22;
5424| goto out;
5425| }
5426|
5427| if (resp[2] != 0)
5428|
5429|
5430|
5431|
5432| rv = -2;
5433| out:
5434| kfree(resp);
5435| return rv;
5436|}
5437|
5438|static int type_file_read_proc(char *page, char **start, off_t off,
5439| int count, int *eof, void *data)
5440|{
5441| struct smi_info *smi = data;
5442|
5443| return sprintf(page, "%s\n", si_to_str[smi->si_type]);
5444|}
5445|
5446|static int stat_file_read_proc(char *page, char **start, off_t off,
5447| int count, int *eof, void *data)
5448|{
5449| char *out = (char *) page;
5450| struct smi_info *smi = data;
5451|
5452| out += sprintf(out, "interrupts_enabled: %d\n",
5453| smi->irq && !smi->interrupt_disabled);
5454| out += sprintf(out, "short_timeouts: %u\n",
5455| ((unsigned int) atomic_read(&(smi)->stats[SI_STAT_short_timeouts])));
5456| out += sprintf(out, "long_timeouts: %u\n",
5457| ((unsigned int) atomic_read(&(smi)->stats[SI_STAT_long_timeouts])));
5458| out += sprintf(out, "idles: %u\n",
5459| ((unsigned int) atomic_read(&(smi)->stats[SI_STAT_idles])));
5460| out += sprintf(out, "interrupts: %u\n",
5461| ((unsigned int) atomic_read(&(smi)->stats[SI_STAT_interrupts])));
5462| out += sprintf(out, "attentions: %u\n",
5463| ((unsigned int) atomic_read(&(smi)->stats[SI_STAT_attentions])));
5464| out += sprintf(out, "flag_fetches: %u\n",
5465| ((unsigned int) atomic_read(&(smi)->stats[SI_STAT_flag_fetches])));
5466| out += sprintf(out, "hosed_count: %u\n",
5467| ((unsigned int) atomic_read(&(smi)->stats[SI_STAT_hosed_count])));
5468| out += sprintf(out, "complete_transactions: %u\n",
5469| ((unsigned int) atomic_read(&(smi)->stats[SI_STAT_complete_transactions])));
5470| out += sprintf(out, "events: %u\n",
5471| ((unsigned int) atomic_read(&(smi)->stats[SI_STAT_events])));
5472| out += sprintf(out, "watchdog_pretimeouts: %u\n",
5473| ((unsigned int) atomic_read(&(smi)->stats[SI_STAT_watchdog_pretimeouts])));
5474| out += sprintf(out, "incoming_messages: %u\n",
5475| ((unsigned int) atomic_read(&(smi)->stats[SI_STAT_incoming_messages])));
5476|
5477| return out - page;
5478|}
5479|
5480|static int param_read_proc(char *page, char **start, off_t off,
5481| int count, int *eof, void *data)
5482|{
5483| struct smi_info *smi = data;
5484|
5485| return sprintf(page,
5486| "%s,%s,0x%lx,rsp=%d,rsi=%d,rsh=%d,irq=%d,ipmb=%d\n",
5487| si_to_str[smi->si_type],
5488| addr_space_to_str[smi->io.addr_type],
5489| smi->io.addr_data,
5490| smi->io.regspacing,
5491| smi->io.regsize,
5492| smi->io.regshift,
5493| smi->irq,
5494| smi->slave_addr);
5495|}
5496|static int oem_data_avail_to_receive_msg_avail(struct smi_info *smi_info)
5497|{
5498| smi_info->msg_flags = ((smi_info->msg_flags & ~(0x20 | 0x40 | 0x80)) |
5499| 0x01);
5500| return 1;
5501|}
5502|static void setup_dell_poweredge_oem_data_handler(struct smi_info *smi_info)
5503|{
5504| struct ipmi_device_id *id = &smi_info->device_id;
5505| if (id->manufacturer_id == 0x0002a2) {
5506| if (id->device_id == 0x20 &&
5507| id->device_revision == 0x80 &&
5508| id->ipmi_version == 0x51) {
5509| smi_info->oem_data_avail_handler =
5510| oem_data_avail_to_receive_msg_avail;
5511| } else if (((id)->ipmi_version & 0xf) < 1 ||
5512| (((id)->ipmi_version & 0xf) == 1 &&
5513| ((id)->ipmi_version >> 4) < 5)) {
5514| smi_info->oem_data_avail_handler =
5515| oem_data_avail_to_receive_msg_avail;
5516| }
5517| }
5518|}
5519|
5520|
5521|static void return_hosed_msg_badsize(struct smi_info *smi_info)
5522|{
5523| struct ipmi_smi_msg *msg = smi_info->curr_msg;
5524|
5525|
5526| msg->rsp[0] = msg->data[0] | 4;
5527| msg->rsp[1] = msg->data[1];
5528| msg->rsp[2] = 0xCA;
5529| msg->rsp_size = 3;
5530| smi_info->curr_msg = ((void *)0);
5531| deliver_recv_msg(smi_info, msg);
5532|}
5533|static int dell_poweredge_bt_xaction_handler(struct notifier_block *self,
5534| unsigned long unused,
5535| void *in)
5536|{
5537| struct smi_info *smi_info = in;
5538| unsigned char *data = smi_info->curr_msg->data;
5539| unsigned int size = smi_info->curr_msg->data_size;
5540| if (size >= 8 &&
5541| (data[0]>>2) == 0x0A &&
5542| data[1] == 0x23 &&
5543| data[7] == 0x3A) {
5544| return_hosed_msg_badsize(smi_info);
5545| return (0x0001|0x8000);
5546| }
5547| return 0x0000;
5548|}
5549|
5550|static struct notifier_block dell_poweredge_bt_xaction_notifier = {
5551| .notifier_call = dell_poweredge_bt_xaction_handler,
5552|};
5553|static void
5554|setup_dell_poweredge_bt_xaction_handler(struct smi_info *smi_info)
5555|{
5556| struct ipmi_device_id *id = &smi_info->device_id;
5557| if (id->manufacturer_id == 0x0002a2 &&
5558| smi_info->si_type == SI_BT)
5559| register_xaction_notifier(&dell_poweredge_bt_xaction_notifier);
5560|}
5561|static void setup_oem_data_handler(struct smi_info *smi_info)
5562|{
5563| setup_dell_poweredge_oem_data_handler(smi_info);
5564|}
5565|
5566|static void setup_xaction_handlers(struct smi_info *smi_info)
5567|{
5568| setup_dell_poweredge_bt_xaction_handler(smi_info);
5569|}
5570|
5571|static inline void wait_for_timer_and_thread(struct smi_info *smi_info)
5572|{
5573| if (smi_info->intf) {
5574|
5575|
5576|
5577|
5578| if (smi_info->thread != ((void *)0))
5579| kthread_stop(smi_info->thread);
5580| del_timer_sync(&smi_info->si_timer);
5581| }
5582|}
5583|
5584|static struct ipmi_default_vals
5585|{
5586| int type;
5587| int port;
5588|} ipmi_defaults[] =
5589|{
5590| { .type = SI_KCS, .port = 0xca2 },
5591| { .type = SI_SMIC, .port = 0xca9 },
5592| { .type = SI_BT, .port = 0xe4 },
5593| { .port = 0 }
5594|};
5595|
5596|static void default_find_bmc(void)
5597|{
5598| struct smi_info *info;
5599| int i;
5600|
5601| for (i = 0; ; i++) {
5602| if (!ipmi_defaults[i].port)
5603| break;
5604|
5605|
5606|
5607|
5608| info = smi_info_alloc();
5609| if (!info)
5610| return;
5611|
5612| info->addr_source = SI_DEFAULT;
5613|
5614| info->si_type = ipmi_defaults[i].type;
5615| info->io_setup = port_setup;
5616| info->io.addr_data = ipmi_defaults[i].port;
5617| info->io.addr_type = 0;
5618|
5619| info->io.addr = ((void *)0);
5620| info->io.regspacing = 1;
5621| info->io.regsize = 1;
5622| info->io.regshift = 0;
5623|
5624| if (add_smi(info) == 0) {
5625| if ((try_smi_init(info)) == 0) {
5626|
5627| printk("<6>" "ipmi_si: " "Found default %s"
5628| " state machine at %s address 0x%lx\n",
5629| si_to_str[info->si_type],
5630| addr_space_to_str[info->io.addr_type],
5631| info->io.addr_data);
5632| } else
5633| cleanup_one_si(info);
5634| } else {
5635| kfree(info);
5636| }
5637| }
5638|}
5639|
5640|static int is_new_interface(struct smi_info *info)
5641|{
5642| struct smi_info *e;
5643|
5644| for (e = ({ const typeof( ((typeof(*e) *)0)->link ) *__mptr = ((&smi_infos)->next); (typeof(*e) *)( (char *)__mptr - 1 );}); __builtin_prefetch(e->link.next), &e->link != (&smi_infos); e = ({ const typeof( ((typeof(*e) *)0)->link ) *__mptr = (e->link.next); (typeof(*e) *)( (char *)__mptr - 1 );})) {
5645| if (e->io.addr_type != info->io.addr_type)
5646| continue;
5647| if (e->io.addr_data == info->io.addr_data)
5648| return 0;
5649| }
5650|
5651| return 1;
5652|}
5653|
5654|static int add_smi(struct smi_info *new_smi)
5655|{
5656| int rv = 0;
5657|
5658| printk("<6>" "ipmi_si: " "Adding %s-specified %s state machine",
5659| ipmi_addr_src_to_str[new_smi->addr_source],
5660| si_to_str[new_smi->si_type]);
5661| __st_mutex_lock_st__(&smi_infos_lock);
5662| if (!is_new_interface(new_smi)) {
5663| printk("" " duplicate interface\n");
5664| rv = -16;
5665| goto out_err;
5666| }
5667|
5668| printk("" "\n");
5669|
5670|
5671| new_smi->intf = ((void *)0);
5672| new_smi->si_sm = ((void *)0);
5673| new_smi->handlers = ((void *)0);
5674|
5675| list_add_tail(&new_smi->link, &smi_infos);
5676|
5677|out_err:
5678| __st_mutex_unlock_st__(&smi_infos_lock);
5679| return rv;
5680|}
5681|
5682|static int try_smi_init(struct smi_info *new_smi)
5683|{
5684| int rv = 0;
5685| int i;
5686|
5687| printk("<6>" "ipmi_si: " "Trying %s-specified %s state"
5688| " machine at %s address 0x%lx, slave address 0x%x,"
5689| " irq %d\n",
5690| ipmi_addr_src_to_str[new_smi->addr_source],
5691| si_to_str[new_smi->si_type],
5692| addr_space_to_str[new_smi->io.addr_type],
5693| new_smi->io.addr_data,
5694| new_smi->slave_addr, new_smi->irq);
5695|
5696| switch (new_smi->si_type) {
5697| case SI_KCS:
5698| new_smi->handlers = &kcs_smi_handlers;
5699| break;
5700|
5701| case SI_SMIC:
5702| new_smi->handlers = &smic_smi_handlers;
5703| break;
5704|
5705| case SI_BT:
5706| new_smi->handlers = &bt_smi_handlers;
5707| break;
5708|
5709| default:
5710|
5711| rv = -5;
5712| goto out_err;
5713| }
5714|
5715|
5716| new_smi->si_sm = kmalloc(new_smi->handlers->size(), __st_GFP_KERNEL_st__);
5717| if (!new_smi->si_sm) {
5718| printk("<3>" "ipmi_si: "
5719| "Could not allocate state machine memory\n");
5720| rv = -12;
5721| goto out_err;
5722| }
5723| new_smi->io_size = new_smi->handlers->init_data(new_smi->si_sm,
5724| &new_smi->io);
5725|
5726|
5727| rv = new_smi->io_setup(new_smi);
5728| if (rv) {
5729| printk("<3>" "ipmi_si: " "Could not set up I/O space\n");
5730| goto out_err;
5731| }
5732|
5733|
5734| if (new_smi->handlers->detect(new_smi->si_sm)) {
5735| if (new_smi->addr_source)
5736| printk("<6>" "ipmi_si: " "Interface detection failed\n");
5737| rv = -19;
5738| goto out_err;
5739| }
5740|
5741|
5742|
5743|
5744|
5745| rv = try_get_dev_id(new_smi);
5746| if (rv) {
5747| if (new_smi->addr_source)
5748| printk("<6>" "ipmi_si: " "There appears to be no BMC"
5749| " at this location\n");
5750| goto out_err;
5751| }
5752|
5753| setup_oem_data_handler(new_smi);
5754| setup_xaction_handlers(new_smi);
5755|
5756| INIT_LIST_HEAD(&(new_smi->xmit_msgs));
5757| INIT_LIST_HEAD(&(new_smi->hp_xmit_msgs));
5758| new_smi->curr_msg = ((void *)0);
5759| atomic_set(&new_smi->req_events, 0);
5760| new_smi->run_to_completion = 0;
5761| for (i = 0; i < SI_NUM_STATS; i++)
5762| atomic_set(&new_smi->stats[i], 0);
5763|
5764| new_smi->interrupt_disabled = 1;
5765| atomic_set(&new_smi->stop_operation, 0);
5766| new_smi->intf_num = smi_num;
5767| smi_num++;
5768|
5769| rv = try_enable_event_buffer(new_smi);
5770| if (rv == 0)
5771| new_smi->has_event_buffer = 1;
5772|
5773|
5774|
5775|
5776|
5777| start_clear_flags(new_smi);
5778|
5779| if (new_smi->irq)
5780| new_smi->si_state = SI_CLEARING_FLAGS_THEN_SET_IRQ;
5781|
5782| if (!new_smi->dev) {
5783|
5784|
5785|
5786|
5787| new_smi->pdev = platform_device_alloc("ipmi_si",
5788| new_smi->intf_num);
5789| if (!new_smi->pdev) {
5790| printk("<3>" "ipmi_si: "
5791| "Unable to allocate platform device\n");
5792| goto out_err;
5793| }
5794| new_smi->dev = &new_smi->pdev->dev;
5795| new_smi->dev->driver = &ipmi_driver.driver;
5796|
5797| rv = platform_device_add(new_smi->pdev);
5798| if (rv) {
5799| printk("<3>" "ipmi_si: "
5800| "Unable to register system interface device:"
5801| " %d\n",
5802| rv);
5803| goto out_err;
5804| }
5805| new_smi->dev_registered = 1;
5806| }
5807|
5808| rv = ipmi_register_smi(&handlers,
5809| new_smi,
5810| &new_smi->device_id,
5811| new_smi->dev,
5812| "bmc",
5813| new_smi->slave_addr);
5814| if (rv) {
5815| dev_err(new_smi->dev, "Unable to register device: error %d\n",
5816| rv);
5817| goto out_err_stop_timer;
5818| }
5819|
5820| rv = ipmi_smi_add_proc_entry(new_smi->intf, "type",
5821| type_file_read_proc,
5822| new_smi);
5823| if (rv) {
5824| dev_err(new_smi->dev, "Unable to create proc entry: %d\n", rv);
5825| goto out_err_stop_timer;
5826| }
5827|
5828| rv = ipmi_smi_add_proc_entry(new_smi->intf, "si_stats",
5829| stat_file_read_proc,
5830| new_smi);
5831| if (rv) {
5832| dev_err(new_smi->dev, "Unable to create proc entry: %d\n", rv);
5833| goto out_err_stop_timer;
5834| }
5835|
5836| rv = ipmi_smi_add_proc_entry(new_smi->intf, "params",
5837| param_read_proc,
5838| new_smi);
5839| if (rv) {
5840| dev_err(new_smi->dev, "Unable to create proc entry: %d\n", rv);
5841| goto out_err_stop_timer;
5842| }
5843|
5844| _dev_info(new_smi->dev, "IPMI %s interface initialized\n", si_to_str[new_smi->si_type])
5845| ;
5846|
5847| return 0;
5848|
5849| out_err_stop_timer:
5850| atomic_inc(&new_smi->stop_operation);
5851| wait_for_timer_and_thread(new_smi);
5852|
5853| out_err:
5854| new_smi->interrupt_disabled = 1;
5855|
5856| if (new_smi->intf) {
5857| ipmi_unregister_smi(new_smi->intf);
5858| new_smi->intf = ((void *)0);
5859| }
5860|
5861| if (new_smi->irq_cleanup) {
5862| new_smi->irq_cleanup(new_smi);
5863| new_smi->irq_cleanup = ((void *)0);
5864| }
5865|
5866|
5867|
5868|
5869|
5870|
5871| synchronize_sched();
5872|
5873| if (new_smi->si_sm) {
5874| if (new_smi->handlers)
5875| new_smi->handlers->cleanup(new_smi->si_sm);
5876| kfree(new_smi->si_sm);
5877| new_smi->si_sm = ((void *)0);
5878| }
5879| if (new_smi->addr_source_cleanup) {
5880| new_smi->addr_source_cleanup(new_smi);
5881| new_smi->addr_source_cleanup = ((void *)0);
5882| }
5883| if (new_smi->io_cleanup) {
5884| new_smi->io_cleanup(new_smi);
5885| new_smi->io_cleanup = ((void *)0);
5886| }
5887|
5888| if (new_smi->dev_registered) {
5889| platform_device_unregister(new_smi->pdev);
5890| new_smi->dev_registered = 0;
5891| }
5892|
5893| return rv;
5894|}
5895|
5896|static int init_ipmi_si(void)
5897|{
5898| int i;
5899| char *str;
5900| int rv;
5901| struct smi_info *e;
5902| enum ipmi_addr_src type = SI_INVALID;
5903|
5904| if (initialized)
5905| return 0;
5906| initialized = 1;
5907|
5908|
5909| rv = driver_register(&ipmi_driver.driver);
5910| if (rv) {
5911| printk("<3>" "ipmi_si: " "Unable to register driver: %d\n", rv);
5912| return rv;
5913| }
5914|
5915|
5916|
5917| str = si_type_str;
5918| if (*str != '\0') {
5919| for (i = 0; (i < 4) && (*str != '\0'); i++) {
5920| si_type[i] = str;
5921| str = strchr(str, ',');
5922| if (str) {
5923| *str = '\0';
5924| str++;
5925| } else {
5926| break;
5927| }
5928| }
5929| }
5930|
5931| printk("<6>" "IPMI System Interface driver.\n");
5932|
5933| hardcode_find_bmc();
5934|
5935|
5936| __st_mutex_lock_st__(&smi_infos_lock);
5937| if (!list_empty(&smi_infos)) {
5938| __st_mutex_unlock_st__(&smi_infos_lock);
5939| return 0;
5940| }
5941| __st_mutex_unlock_st__(&smi_infos_lock);
5942|
5943|
5944| rv = __pci_register_driver(&ipmi_pci_driver, (&__this_module), "ipmi_si");
5945| if (rv)
5946| printk("<3>" "ipmi_si: " "Unable to register PCI driver: %d\n", rv);
5947| else
5948| pci_registered = 1;
5949|
5950|
5951|
5952| pnp_register_driver(&ipmi_pnp_driver);
5953| pnp_registered = 1;
5954|
5955|
5956|
5957| dmi_find_bmc();
5958|
5959|
5960|
5961| spmi_find_bmc();
5962| __st_mutex_lock_st__(&smi_infos_lock);
5963| for (e = ({ const typeof( ((typeof(*e) *)0)->link ) *__mptr = ((&smi_infos)->next); (typeof(*e) *)( (char *)__mptr - 1 );}); __builtin_prefetch(e->link.next), &e->link != (&smi_infos); e = ({ const typeof( ((typeof(*e) *)0)->link ) *__mptr = (e->link.next); (typeof(*e) *)( (char *)__mptr - 1 );})) {
5964|
5965|
5966|
5967| if (e->irq && (!type || e->addr_source == type)) {
5968| if (!try_smi_init(e)) {
5969| type = e->addr_source;
5970| }
5971| }
5972| }
5973|
5974|
5975| if (type) {
5976| __st_mutex_unlock_st__(&smi_infos_lock);
5977| return 0;
5978| }
5979|
5980|
5981|
5982| for (e = ({ const typeof( ((typeof(*e) *)0)->link ) *__mptr = ((&smi_infos)->next); (typeof(*e) *)( (char *)__mptr - 1 );}); __builtin_prefetch(e->link.next), &e->link != (&smi_infos); e = ({ const typeof( ((typeof(*e) *)0)->link ) *__mptr = (e->link.next); (typeof(*e) *)( (char *)__mptr - 1 );})) {
5983| if (!e->irq && (!type || e->addr_source == type)) {
5984| if (!try_smi_init(e)) {
5985| type = e->addr_source;
5986| }
5987| }
5988| }
5989| __st_mutex_unlock_st__(&smi_infos_lock);
5990|
5991| if (type)
5992| return 0;
5993|
5994| if (si_trydefaults) {
5995| __st_mutex_lock_st__(&smi_infos_lock);
5996| if (list_empty(&smi_infos)) {
5997|
5998| __st_mutex_unlock_st__(&smi_infos_lock);
5999| default_find_bmc();
6000| } else
6001| __st_mutex_unlock_st__(&smi_infos_lock);
6002| }
6003|
6004| __st_mutex_lock_st__(&smi_infos_lock);
6005| if (unload_when_empty && list_empty(&smi_infos)) {
6006| __st_mutex_unlock_st__(&smi_infos_lock);
6007|
6008| if (pci_registered)
6009| pci_unregister_driver(&ipmi_pci_driver);
6010|
6011|
6012|
6013|
6014|
6015|
6016| driver_unregister(&ipmi_driver.driver);
6017| printk("<4>" "ipmi_si: "
6018| "Unable to find any System Interface(s)\n");
6019| return -19;
6020| } else {
6021| __st_mutex_unlock_st__(&smi_infos_lock);
6022| return 0;
6023| }
6024|}
6025|static inline initcall_t __inittest(void) { return init_ipmi_si; } int init_module(void) ;;
6026|
6027|static void cleanup_one_si(struct smi_info *to_clean)
6028|{
6029| int rv = 0;
6030| unsigned long flags;
6031|
6032| if (!to_clean)
6033| return;
6034|
6035| list_del(&to_clean->link);
6036|
6037|
6038| atomic_inc(&to_clean->stop_operation);
6039|
6040|
6041|
6042|
6043|
6044| wait_for_timer_and_thread(to_clean);
6045|
6046|
6047|
6048|
6049|
6050|
6051| __st_spin_lock_irqsave_st__(&to_clean->si_lock, flags);
6052| while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) {
6053| __st_spin_unlock_irqrestore_st__(&to_clean->si_lock, flags);
6054| poll(to_clean);
6055| schedule_timeout_uninterruptible(1);
6056| __st_spin_lock_irqsave_st__(&to_clean->si_lock, flags);
6057| }
6058| disable_si_irq(to_clean);
6059| __st_spin_unlock_irqrestore_st__(&to_clean->si_lock, flags);
6060| while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) {
6061| poll(to_clean);
6062| schedule_timeout_uninterruptible(1);
6063| }
6064|
6065|
6066| if (to_clean->irq_cleanup)
6067| to_clean->irq_cleanup(to_clean);
6068| while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) {
6069| poll(to_clean);
6070| schedule_timeout_uninterruptible(1);
6071| }
6072|
6073| if (to_clean->intf)
6074| rv = ipmi_unregister_smi(to_clean->intf);
6075|
6076| if (rv) {
6077| printk("<3>" "ipmi_si: " "Unable to unregister device: errno=%d\n",
6078| rv);
6079| }
6080|
6081| if (to_clean->handlers)
6082| to_clean->handlers->cleanup(to_clean->si_sm);
6083|
6084| kfree(to_clean->si_sm);
6085|
6086| if (to_clean->addr_source_cleanup)
6087| to_clean->addr_source_cleanup(to_clean);
6088| if (to_clean->io_cleanup)
6089| to_clean->io_cleanup(to_clean);
6090|
6091| if (to_clean->dev_registered)
6092| platform_device_unregister(to_clean->pdev);
6093|
6094| kfree(to_clean);
6095|}
6096|
6097|static void cleanup_ipmi_si(void)
6098|{
6099| struct smi_info *e, *tmp_e;
6100|
6101| if (!initialized)
6102| return;
6103|
6104|
6105| if (pci_registered)
6106| pci_unregister_driver(&ipmi_pci_driver);
6107|
6108|
6109| if (pnp_registered)
6110| pnp_unregister_driver(&ipmi_pnp_driver);
6111|
6112|
6113|
6114|
6115|
6116|
6117|
6118| __st_mutex_lock_st__(&smi_infos_lock);
6119| for (e = ({ const typeof( ((typeof(*e) *)0)->link ) *__mptr = ((&smi_infos)->next); (typeof(*e) *)( (char *)__mptr - 1 );}), tmp_e = ({ const typeof( ((typeof(*e) *)0)->link ) *__mptr = (e->link.next); (typeof(*e) *)( (char *)__mptr - 1 );}); &e->link != (&smi_infos); e = tmp_e, tmp_e = ({ const typeof( ((typeof(*tmp_e) *)0)->link ) *__mptr = (tmp_e->link.next); (typeof(*tmp_e) *)( (char *)__mptr - 1 );}))
6120| cleanup_one_si(e);
6121| __st_mutex_unlock_st__(&smi_infos_lock);
6122|
6123| driver_unregister(&ipmi_driver.driver);
6124|}
6125|static inline exitcall_t __exittest(void) { return cleanup_ipmi_si; } void cleanup_module(void) ;;
6126|
6127|static const char __mod_license3558[] = "license" "=" "GPL";
6128|static const char __mod_author3559[] = "author" "=" "Corey Minyard ";
6129|static const char
6130| __mod_description3561
6131| [] = "description" "=" "Interface to the IPMI driver for the KCS, SMIC, and BT" " system interfaces."
6132| ;