]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/ipmi/ipmi.c
MFV r326007: less v529.
[FreeBSD/FreeBSD.git] / sys / dev / ipmi / ipmi.c
1 /*-
2  * Copyright (c) 2006 IronPort Systems Inc. <ambrisko@ironport.com>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/bus.h>
33 #include <sys/condvar.h>
34 #include <sys/conf.h>
35 #include <sys/kernel.h>
36 #include <sys/malloc.h>
37 #include <sys/module.h>
38 #include <sys/poll.h>
39 #include <sys/reboot.h>
40 #include <sys/rman.h>
41 #include <sys/selinfo.h>
42 #include <sys/sysctl.h>
43 #include <sys/watchdog.h>
44
45 #ifdef LOCAL_MODULE
46 #include <ipmi.h>
47 #include <ipmivars.h>
48 #else
49 #include <sys/ipmi.h>
50 #include <dev/ipmi/ipmivars.h>
51 #endif
52
53 /*
54  * Driver request structures are allocated on the stack via alloca() to
55  * avoid calling malloc(), especially for the watchdog handler.
56  * To avoid too much stack growth, a previously allocated structure can
57  * be reused via IPMI_INIT_DRIVER_REQUEST(), but the caller should ensure
58  * that there is adequate reply/request space in the original allocation.
59  */
60 #define IPMI_INIT_DRIVER_REQUEST(req, addr, cmd, reqlen, replylen)      \
61         bzero((req), sizeof(struct ipmi_request));                      \
62         ipmi_init_request((req), NULL, 0, (addr), (cmd), (reqlen), (replylen))
63
64 #define IPMI_ALLOC_DRIVER_REQUEST(req, addr, cmd, reqlen, replylen)     \
65         (req) = __builtin_alloca(sizeof(struct ipmi_request) +          \
66             (reqlen) + (replylen));                                     \
67         IPMI_INIT_DRIVER_REQUEST((req), (addr), (cmd), (reqlen),        \
68             (replylen))
69
70 #ifdef IPMB
71 static int ipmi_ipmb_checksum(u_char, int);
72 static int ipmi_ipmb_send_message(device_t, u_char, u_char, u_char,
73      u_char, u_char, int)
74 #endif
75
76 static d_ioctl_t ipmi_ioctl;
77 static d_poll_t ipmi_poll;
78 static d_open_t ipmi_open;
79 static void ipmi_dtor(void *arg);
80
81 int ipmi_attached = 0;
82
83 static int on = 1;
84 static bool wd_in_shutdown = false;
85 static int wd_timer_actions = IPMI_SET_WD_ACTION_POWER_CYCLE;
86 static int wd_shutdown_countdown = 0; /* sec */
87 static int wd_startup_countdown = 0; /* sec */
88 static int wd_pretimeout_countdown = 120; /* sec */
89 static int cycle_wait = 10; /* sec */
90
91 static SYSCTL_NODE(_hw, OID_AUTO, ipmi, CTLFLAG_RD, 0,
92     "IPMI driver parameters");
93 SYSCTL_INT(_hw_ipmi, OID_AUTO, on, CTLFLAG_RWTUN,
94         &on, 0, "");
95 SYSCTL_INT(_hw_ipmi, OID_AUTO, wd_timer_actions, CTLFLAG_RW,
96         &wd_timer_actions, 0,
97         "IPMI watchdog timer actions (including pre-timeout interrupt)");
98 SYSCTL_INT(_hw_ipmi, OID_AUTO, wd_shutdown_countdown, CTLFLAG_RW,
99         &wd_shutdown_countdown, 0,
100         "IPMI watchdog countdown for shutdown (seconds)");
101 SYSCTL_INT(_hw_ipmi, OID_AUTO, wd_startup_countdown, CTLFLAG_RDTUN,
102         &wd_startup_countdown, 0,
103         "IPMI watchdog countdown initialized during startup (seconds)");
104 SYSCTL_INT(_hw_ipmi, OID_AUTO, wd_pretimeout_countdown, CTLFLAG_RW,
105         &wd_pretimeout_countdown, 0,
106         "IPMI watchdog pre-timeout countdown (seconds)");
107 SYSCTL_INT(_hw_ipmi, OID_AUTO, cyle_wait, CTLFLAG_RWTUN,
108         &cycle_wait, 0,
109         "IPMI power cycle on reboot delay time (seconds)");
110
111 static struct cdevsw ipmi_cdevsw = {
112         .d_version =    D_VERSION,
113         .d_open =       ipmi_open,
114         .d_ioctl =      ipmi_ioctl,
115         .d_poll =       ipmi_poll,
116         .d_name =       "ipmi",
117 };
118
119 static MALLOC_DEFINE(M_IPMI, "ipmi", "ipmi");
120
121 static int
122 ipmi_open(struct cdev *cdev, int flags, int fmt, struct thread *td)
123 {
124         struct ipmi_device *dev;
125         struct ipmi_softc *sc;
126         int error;
127
128         if (!on)
129                 return (ENOENT);
130
131         /* Initialize the per file descriptor data. */
132         dev = malloc(sizeof(struct ipmi_device), M_IPMI, M_WAITOK | M_ZERO);
133         error = devfs_set_cdevpriv(dev, ipmi_dtor);
134         if (error) {
135                 free(dev, M_IPMI);
136                 return (error);
137         }
138
139         sc = cdev->si_drv1;
140         TAILQ_INIT(&dev->ipmi_completed_requests);
141         dev->ipmi_address = IPMI_BMC_SLAVE_ADDR;
142         dev->ipmi_lun = IPMI_BMC_SMS_LUN;
143         dev->ipmi_softc = sc;
144         IPMI_LOCK(sc);
145         sc->ipmi_opened++;
146         IPMI_UNLOCK(sc);
147
148         return (0);
149 }
150
151 static int
152 ipmi_poll(struct cdev *cdev, int poll_events, struct thread *td)
153 {
154         struct ipmi_device *dev;
155         struct ipmi_softc *sc;
156         int revents = 0;
157
158         if (devfs_get_cdevpriv((void **)&dev))
159                 return (0);
160
161         sc = cdev->si_drv1;
162         IPMI_LOCK(sc);
163         if (poll_events & (POLLIN | POLLRDNORM)) {
164                 if (!TAILQ_EMPTY(&dev->ipmi_completed_requests))
165                     revents |= poll_events & (POLLIN | POLLRDNORM);
166                 if (dev->ipmi_requests == 0)
167                     revents |= POLLERR;
168         }
169
170         if (revents == 0) {
171                 if (poll_events & (POLLIN | POLLRDNORM))
172                         selrecord(td, &dev->ipmi_select);
173         }
174         IPMI_UNLOCK(sc);
175
176         return (revents);
177 }
178
179 static void
180 ipmi_purge_completed_requests(struct ipmi_device *dev)
181 {
182         struct ipmi_request *req;
183
184         while (!TAILQ_EMPTY(&dev->ipmi_completed_requests)) {
185                 req = TAILQ_FIRST(&dev->ipmi_completed_requests);
186                 TAILQ_REMOVE(&dev->ipmi_completed_requests, req, ir_link);
187                 dev->ipmi_requests--;
188                 ipmi_free_request(req);
189         }
190 }
191
192 static void
193 ipmi_dtor(void *arg)
194 {
195         struct ipmi_request *req, *nreq;
196         struct ipmi_device *dev;
197         struct ipmi_softc *sc;
198
199         dev = arg;
200         sc = dev->ipmi_softc;
201
202         IPMI_LOCK(sc);
203         if (dev->ipmi_requests) {
204                 /* Throw away any pending requests for this device. */
205                 TAILQ_FOREACH_SAFE(req, &sc->ipmi_pending_requests, ir_link,
206                     nreq) {
207                         if (req->ir_owner == dev) {
208                                 TAILQ_REMOVE(&sc->ipmi_pending_requests, req,
209                                     ir_link);
210                                 dev->ipmi_requests--;
211                                 ipmi_free_request(req);
212                         }
213                 }
214
215                 /* Throw away any pending completed requests for this device. */
216                 ipmi_purge_completed_requests(dev);
217
218                 /*
219                  * If we still have outstanding requests, they must be stuck
220                  * in an interface driver, so wait for those to drain.
221                  */
222                 dev->ipmi_closing = 1;
223                 while (dev->ipmi_requests > 0) {
224                         msleep(&dev->ipmi_requests, &sc->ipmi_requests_lock,
225                             PWAIT, "ipmidrain", 0);
226                         ipmi_purge_completed_requests(dev);
227                 }
228         }
229         sc->ipmi_opened--;
230         IPMI_UNLOCK(sc);
231
232         /* Cleanup. */
233         free(dev, M_IPMI);
234 }
235
236 #ifdef IPMB
237 static int
238 ipmi_ipmb_checksum(u_char *data, int len)
239 {
240         u_char sum = 0;
241
242         for (; len; len--) {
243                 sum += *data++;
244         }
245         return (-sum);
246 }
247
248 /* XXX: Needs work */
249 static int
250 ipmi_ipmb_send_message(device_t dev, u_char channel, u_char netfn,
251     u_char command, u_char seq, u_char *data, int data_len)
252 {
253         struct ipmi_softc *sc = device_get_softc(dev);
254         struct ipmi_request *req;
255         u_char slave_addr = 0x52;
256         int error;
257
258         IPMI_ALLOC_DRIVER_REQUEST(req, IPMI_ADDR(IPMI_APP_REQUEST, 0),
259             IPMI_SEND_MSG, data_len + 8, 0);
260         req->ir_request[0] = channel;
261         req->ir_request[1] = slave_addr;
262         req->ir_request[2] = IPMI_ADDR(netfn, 0);
263         req->ir_request[3] = ipmi_ipmb_checksum(&req->ir_request[1], 2);
264         req->ir_request[4] = sc->ipmi_address;
265         req->ir_request[5] = IPMI_ADDR(seq, sc->ipmi_lun);
266         req->ir_request[6] = command;
267
268         bcopy(data, &req->ir_request[7], data_len);
269         temp[data_len + 7] = ipmi_ipmb_checksum(&req->ir_request[4],
270             data_len + 3);
271
272         ipmi_submit_driver_request(sc, req);
273         error = req->ir_error;
274
275         return (error);
276 }
277
278 static int
279 ipmi_handle_attn(struct ipmi_softc *sc)
280 {
281         struct ipmi_request *req;
282         int error;
283
284         device_printf(sc->ipmi_dev, "BMC has a message\n");
285         IPMI_ALLOC_DRIVER_REQUEST(req, IPMI_ADDR(IPMI_APP_REQUEST, 0),
286             IPMI_GET_MSG_FLAGS, 0, 1);
287
288         ipmi_submit_driver_request(sc, req);
289
290         if (req->ir_error == 0 && req->ir_compcode == 0) {
291                 if (req->ir_reply[0] & IPMI_MSG_BUFFER_FULL) {
292                         device_printf(sc->ipmi_dev, "message buffer full");
293                 }
294                 if (req->ir_reply[0] & IPMI_WDT_PRE_TIMEOUT) {
295                         device_printf(sc->ipmi_dev,
296                             "watchdog about to go off");
297                 }
298                 if (req->ir_reply[0] & IPMI_MSG_AVAILABLE) {
299                         IPMI_ALLOC_DRIVER_REQUEST(req,
300                             IPMI_ADDR(IPMI_APP_REQUEST, 0), IPMI_GET_MSG, 0,
301                             16);
302
303                         device_printf(sc->ipmi_dev, "throw out message ");
304                         dump_buf(temp, 16);
305                 }
306         }
307         error = req->ir_error;
308
309         return (error);
310 }
311 #endif
312
313 #ifdef IPMICTL_SEND_COMMAND_32
314 #define PTRIN(p)        ((void *)(uintptr_t)(p))
315 #define PTROUT(p)       ((uintptr_t)(p))
316 #endif
317
318 static int
319 ipmi_ioctl(struct cdev *cdev, u_long cmd, caddr_t data,
320     int flags, struct thread *td)
321 {
322         struct ipmi_softc *sc;
323         struct ipmi_device *dev;
324         struct ipmi_request *kreq;
325         struct ipmi_req *req = (struct ipmi_req *)data;
326         struct ipmi_recv *recv = (struct ipmi_recv *)data;
327         struct ipmi_addr addr;
328 #ifdef IPMICTL_SEND_COMMAND_32
329         struct ipmi_req32 *req32 = (struct ipmi_req32 *)data;
330         struct ipmi_recv32 *recv32 = (struct ipmi_recv32 *)data;
331         union {
332                 struct ipmi_req req;
333                 struct ipmi_recv recv;
334         } thunk32;
335 #endif
336         int error, len;
337
338         error = devfs_get_cdevpriv((void **)&dev);
339         if (error)
340                 return (error);
341
342         sc = cdev->si_drv1;
343
344 #ifdef IPMICTL_SEND_COMMAND_32
345         /* Convert 32-bit structures to native. */
346         switch (cmd) {
347         case IPMICTL_SEND_COMMAND_32:
348                 req = &thunk32.req;
349                 req->addr = PTRIN(req32->addr);
350                 req->addr_len = req32->addr_len;
351                 req->msgid = req32->msgid;
352                 req->msg.netfn = req32->msg.netfn;
353                 req->msg.cmd = req32->msg.cmd;
354                 req->msg.data_len = req32->msg.data_len;
355                 req->msg.data = PTRIN(req32->msg.data);
356                 break;
357         case IPMICTL_RECEIVE_MSG_TRUNC_32:
358         case IPMICTL_RECEIVE_MSG_32:
359                 recv = &thunk32.recv;
360                 recv->addr = PTRIN(recv32->addr);
361                 recv->addr_len = recv32->addr_len;
362                 recv->msg.data_len = recv32->msg.data_len;
363                 recv->msg.data = PTRIN(recv32->msg.data);
364                 break;
365         }
366 #endif
367
368         switch (cmd) {
369 #ifdef IPMICTL_SEND_COMMAND_32
370         case IPMICTL_SEND_COMMAND_32:
371 #endif
372         case IPMICTL_SEND_COMMAND:
373                 /*
374                  * XXX: Need to add proper handling of this.
375                  */
376                 error = copyin(req->addr, &addr, sizeof(addr));
377                 if (error)
378                         return (error);
379
380                 IPMI_LOCK(sc);
381                 /* clear out old stuff in queue of stuff done */
382                 /* XXX: This seems odd. */
383                 while ((kreq = TAILQ_FIRST(&dev->ipmi_completed_requests))) {
384                         TAILQ_REMOVE(&dev->ipmi_completed_requests, kreq,
385                             ir_link);
386                         dev->ipmi_requests--;
387                         ipmi_free_request(kreq);
388                 }
389                 IPMI_UNLOCK(sc);
390
391                 kreq = ipmi_alloc_request(dev, req->msgid,
392                     IPMI_ADDR(req->msg.netfn, 0), req->msg.cmd,
393                     req->msg.data_len, IPMI_MAX_RX);
394                 error = copyin(req->msg.data, kreq->ir_request,
395                     req->msg.data_len);
396                 if (error) {
397                         ipmi_free_request(kreq);
398                         return (error);
399                 }
400                 IPMI_LOCK(sc);
401                 dev->ipmi_requests++;
402                 error = sc->ipmi_enqueue_request(sc, kreq);
403                 IPMI_UNLOCK(sc);
404                 if (error)
405                         return (error);
406                 break;
407 #ifdef IPMICTL_SEND_COMMAND_32
408         case IPMICTL_RECEIVE_MSG_TRUNC_32:
409         case IPMICTL_RECEIVE_MSG_32:
410 #endif
411         case IPMICTL_RECEIVE_MSG_TRUNC:
412         case IPMICTL_RECEIVE_MSG:
413                 error = copyin(recv->addr, &addr, sizeof(addr));
414                 if (error)
415                         return (error);
416
417                 IPMI_LOCK(sc);
418                 kreq = TAILQ_FIRST(&dev->ipmi_completed_requests);
419                 if (kreq == NULL) {
420                         IPMI_UNLOCK(sc);
421                         return (EAGAIN);
422                 }
423                 addr.channel = IPMI_BMC_CHANNEL;
424                 /* XXX */
425                 recv->recv_type = IPMI_RESPONSE_RECV_TYPE;
426                 recv->msgid = kreq->ir_msgid;
427                 recv->msg.netfn = IPMI_REPLY_ADDR(kreq->ir_addr) >> 2;
428                 recv->msg.cmd = kreq->ir_command;
429                 error = kreq->ir_error;
430                 if (error) {
431                         TAILQ_REMOVE(&dev->ipmi_completed_requests, kreq,
432                             ir_link);
433                         dev->ipmi_requests--;
434                         IPMI_UNLOCK(sc);
435                         ipmi_free_request(kreq);
436                         return (error);
437                 }
438                 len = kreq->ir_replylen + 1;
439                 if (recv->msg.data_len < len &&
440                     (cmd == IPMICTL_RECEIVE_MSG
441 #ifdef IPMICTL_RECEIVE_MSG_32
442                      || cmd == IPMICTL_RECEIVE_MSG_32
443 #endif
444                     )) {
445                         IPMI_UNLOCK(sc);
446                         return (EMSGSIZE);
447                 }
448                 TAILQ_REMOVE(&dev->ipmi_completed_requests, kreq, ir_link);
449                 dev->ipmi_requests--;
450                 IPMI_UNLOCK(sc);
451                 len = min(recv->msg.data_len, len);
452                 recv->msg.data_len = len;
453                 error = copyout(&addr, recv->addr,sizeof(addr));
454                 if (error == 0)
455                         error = copyout(&kreq->ir_compcode, recv->msg.data, 1);
456                 if (error == 0)
457                         error = copyout(kreq->ir_reply, recv->msg.data + 1,
458                             len - 1);
459                 ipmi_free_request(kreq);
460                 if (error)
461                         return (error);
462                 break;
463         case IPMICTL_SET_MY_ADDRESS_CMD:
464                 IPMI_LOCK(sc);
465                 dev->ipmi_address = *(int*)data;
466                 IPMI_UNLOCK(sc);
467                 break;
468         case IPMICTL_GET_MY_ADDRESS_CMD:
469                 IPMI_LOCK(sc);
470                 *(int*)data = dev->ipmi_address;
471                 IPMI_UNLOCK(sc);
472                 break;
473         case IPMICTL_SET_MY_LUN_CMD:
474                 IPMI_LOCK(sc);
475                 dev->ipmi_lun = *(int*)data & 0x3;
476                 IPMI_UNLOCK(sc);
477                 break;
478         case IPMICTL_GET_MY_LUN_CMD:
479                 IPMI_LOCK(sc);
480                 *(int*)data = dev->ipmi_lun;
481                 IPMI_UNLOCK(sc);
482                 break;
483         case IPMICTL_SET_GETS_EVENTS_CMD:
484                 /*
485                 device_printf(sc->ipmi_dev,
486                     "IPMICTL_SET_GETS_EVENTS_CMD NA\n");
487                 */
488                 break;
489         case IPMICTL_REGISTER_FOR_CMD:
490         case IPMICTL_UNREGISTER_FOR_CMD:
491                 return (EOPNOTSUPP);
492         default:
493                 device_printf(sc->ipmi_dev, "Unknown IOCTL %lX\n", cmd);
494                 return (ENOIOCTL);
495         }
496
497 #ifdef IPMICTL_SEND_COMMAND_32
498         /* Update changed fields in 32-bit structures. */
499         switch (cmd) {
500         case IPMICTL_RECEIVE_MSG_TRUNC_32:
501         case IPMICTL_RECEIVE_MSG_32:
502                 recv32->recv_type = recv->recv_type;
503                 recv32->msgid = recv->msgid;
504                 recv32->msg.netfn = recv->msg.netfn;
505                 recv32->msg.cmd = recv->msg.cmd;
506                 recv32->msg.data_len = recv->msg.data_len;
507                 break;
508         }
509 #endif
510         return (0);
511 }
512
513 /*
514  * Request management.
515  */
516
517 static __inline void
518 ipmi_init_request(struct ipmi_request *req, struct ipmi_device *dev, long msgid,
519     uint8_t addr, uint8_t command, size_t requestlen, size_t replylen)
520 {
521
522         req->ir_owner = dev;
523         req->ir_msgid = msgid;
524         req->ir_addr = addr;
525         req->ir_command = command;
526         if (requestlen) {
527                 req->ir_request = (char *)&req[1];
528                 req->ir_requestlen = requestlen;
529         }
530         if (replylen) {
531                 req->ir_reply = (char *)&req[1] + requestlen;
532                 req->ir_replybuflen = replylen;
533         }
534 }
535
536 /* Allocate a new request with request and reply buffers. */
537 struct ipmi_request *
538 ipmi_alloc_request(struct ipmi_device *dev, long msgid, uint8_t addr,
539     uint8_t command, size_t requestlen, size_t replylen)
540 {
541         struct ipmi_request *req;
542
543         req = malloc(sizeof(struct ipmi_request) + requestlen + replylen,
544             M_IPMI, M_WAITOK | M_ZERO);
545         ipmi_init_request(req, dev, msgid, addr, command, requestlen, replylen);
546         return (req);
547 }
548
549 /* Free a request no longer in use. */
550 void
551 ipmi_free_request(struct ipmi_request *req)
552 {
553
554         free(req, M_IPMI);
555 }
556
557 /* Store a processed request on the appropriate completion queue. */
558 void
559 ipmi_complete_request(struct ipmi_softc *sc, struct ipmi_request *req)
560 {
561         struct ipmi_device *dev;
562
563         IPMI_LOCK_ASSERT(sc);
564
565         /*
566          * Anonymous requests (from inside the driver) always have a
567          * waiter that we awaken.
568          */
569         if (req->ir_owner == NULL)
570                 wakeup(req);
571         else {
572                 dev = req->ir_owner;
573                 TAILQ_INSERT_TAIL(&dev->ipmi_completed_requests, req, ir_link);
574                 selwakeup(&dev->ipmi_select);
575                 if (dev->ipmi_closing)
576                         wakeup(&dev->ipmi_requests);
577         }
578 }
579
580 /* Perform an internal driver request. */
581 int
582 ipmi_submit_driver_request(struct ipmi_softc *sc, struct ipmi_request *req,
583     int timo)
584 {
585
586         return (sc->ipmi_driver_request(sc, req, timo));
587 }
588
589 /*
590  * Helper routine for polled system interfaces that use
591  * ipmi_polled_enqueue_request() to queue requests.  This request
592  * waits until there is a pending request and then returns the first
593  * request.  If the driver is shutting down, it returns NULL.
594  */
595 struct ipmi_request *
596 ipmi_dequeue_request(struct ipmi_softc *sc)
597 {
598         struct ipmi_request *req;
599
600         IPMI_LOCK_ASSERT(sc);
601
602         while (!sc->ipmi_detaching && TAILQ_EMPTY(&sc->ipmi_pending_requests))
603                 cv_wait(&sc->ipmi_request_added, &sc->ipmi_requests_lock);
604         if (sc->ipmi_detaching)
605                 return (NULL);
606
607         req = TAILQ_FIRST(&sc->ipmi_pending_requests);
608         TAILQ_REMOVE(&sc->ipmi_pending_requests, req, ir_link);
609         return (req);
610 }
611
612 /* Default implementation of ipmi_enqueue_request() for polled interfaces. */
613 int
614 ipmi_polled_enqueue_request(struct ipmi_softc *sc, struct ipmi_request *req)
615 {
616
617         IPMI_LOCK_ASSERT(sc);
618
619         TAILQ_INSERT_TAIL(&sc->ipmi_pending_requests, req, ir_link);
620         cv_signal(&sc->ipmi_request_added);
621         return (0);
622 }
623
624 /*
625  * Watchdog event handler.
626  */
627
628 static int
629 ipmi_reset_watchdog(struct ipmi_softc *sc)
630 {
631         struct ipmi_request *req;
632         int error;
633
634         IPMI_ALLOC_DRIVER_REQUEST(req, IPMI_ADDR(IPMI_APP_REQUEST, 0),
635             IPMI_RESET_WDOG, 0, 0);
636         error = ipmi_submit_driver_request(sc, req, 0);
637         if (error)
638                 device_printf(sc->ipmi_dev, "Failed to reset watchdog\n");
639         return (error);
640 }
641
642 static int
643 ipmi_set_watchdog(struct ipmi_softc *sc, unsigned int sec)
644 {
645         struct ipmi_request *req;
646         int error;
647
648         if (sec > 0xffff / 10)
649                 return (EINVAL);
650
651         IPMI_ALLOC_DRIVER_REQUEST(req, IPMI_ADDR(IPMI_APP_REQUEST, 0),
652             IPMI_SET_WDOG, 6, 0);
653         if (sec) {
654                 req->ir_request[0] = IPMI_SET_WD_TIMER_DONT_STOP
655                     | IPMI_SET_WD_TIMER_SMS_OS;
656                 req->ir_request[1] = (wd_timer_actions & 0xff);
657                 req->ir_request[2] = (wd_pretimeout_countdown & 0xff);
658                 req->ir_request[3] = 0; /* Timer use */
659                 req->ir_request[4] = (sec * 10) & 0xff;
660                 req->ir_request[5] = (sec * 10) >> 8;
661         } else {
662                 req->ir_request[0] = IPMI_SET_WD_TIMER_SMS_OS;
663                 req->ir_request[1] = 0;
664                 req->ir_request[2] = 0;
665                 req->ir_request[3] = 0; /* Timer use */
666                 req->ir_request[4] = 0;
667                 req->ir_request[5] = 0;
668         }
669         error = ipmi_submit_driver_request(sc, req, 0);
670         if (error)
671                 device_printf(sc->ipmi_dev, "Failed to set watchdog\n");
672         return (error);
673 }
674
675 static void
676 ipmi_wd_event(void *arg, unsigned int cmd, int *error)
677 {
678         struct ipmi_softc *sc = arg;
679         unsigned int timeout;
680         int e;
681
682         /* Ignore requests while disabled. */
683         if (!on)
684                 return;
685
686         /*
687          * To prevent infinite hangs, we don't let anyone pat or change
688          * the watchdog when we're shutting down. (See ipmi_shutdown_event().)
689          * However, we do want to keep patting the watchdog while we are doing
690          * a coredump.
691          */
692         if (wd_in_shutdown) {
693                 if (dumping && sc->ipmi_watchdog_active)
694                         ipmi_reset_watchdog(sc);
695                 return;
696         }
697
698         cmd &= WD_INTERVAL;
699         if (cmd > 0 && cmd <= 63) {
700                 timeout = ((uint64_t)1 << cmd) / 1000000000;
701                 if (timeout == 0)
702                         timeout = 1;
703                 if (timeout != sc->ipmi_watchdog_active ||
704                     wd_timer_actions != sc->ipmi_watchdog_actions ||
705                     wd_pretimeout_countdown != sc->ipmi_watchdog_pretimeout) {
706                         e = ipmi_set_watchdog(sc, timeout);
707                         if (e == 0) {
708                                 sc->ipmi_watchdog_active = timeout;
709                                 sc->ipmi_watchdog_actions = wd_timer_actions;
710                                 sc->ipmi_watchdog_pretimeout = wd_pretimeout_countdown;
711                         } else {
712                                 (void)ipmi_set_watchdog(sc, 0);
713                                 sc->ipmi_watchdog_active = 0;
714                                 sc->ipmi_watchdog_actions = 0;
715                                 sc->ipmi_watchdog_pretimeout = 0;
716                         }
717                 }
718                 if (sc->ipmi_watchdog_active != 0) {
719                         e = ipmi_reset_watchdog(sc);
720                         if (e == 0) {
721                                 *error = 0;
722                         } else {
723                                 (void)ipmi_set_watchdog(sc, 0);
724                                 sc->ipmi_watchdog_active = 0;
725                                 sc->ipmi_watchdog_actions = 0;
726                                 sc->ipmi_watchdog_pretimeout = 0;
727                         }
728                 }
729         } else if (atomic_readandclear_int(&sc->ipmi_watchdog_active) != 0) {
730                 sc->ipmi_watchdog_actions = 0;
731                 sc->ipmi_watchdog_pretimeout = 0;
732
733                 e = ipmi_set_watchdog(sc, 0);
734                 if (e != 0 && cmd == 0)
735                         *error = EOPNOTSUPP;
736         }
737 }
738
739 static void
740 ipmi_shutdown_event(void *arg, unsigned int cmd, int *error)
741 {
742         struct ipmi_softc *sc = arg;
743
744         /* Ignore event if disabled. */
745         if (!on)
746                 return;
747
748         /*
749          * Positive wd_shutdown_countdown value will re-arm watchdog;
750          * Zero value in wd_shutdown_countdown will disable watchdog;
751          * Negative value in wd_shutdown_countdown will keep existing state;
752          *
753          * Revert to using a power cycle to ensure that the watchdog will
754          * do something useful here.  Having the watchdog send an NMI
755          * instead is useless during shutdown, and might be ignored if an
756          * NMI already triggered.
757          */
758
759         wd_in_shutdown = true;
760         if (wd_shutdown_countdown == 0) {
761                 /* disable watchdog */
762                 ipmi_set_watchdog(sc, 0);
763                 sc->ipmi_watchdog_active = 0;
764         } else if (wd_shutdown_countdown > 0) {
765                 /* set desired action and time, and, reset watchdog */
766                 wd_timer_actions = IPMI_SET_WD_ACTION_POWER_CYCLE;
767                 ipmi_set_watchdog(sc, wd_shutdown_countdown);
768                 sc->ipmi_watchdog_active = wd_shutdown_countdown;
769                 ipmi_reset_watchdog(sc);
770         }
771 }
772
773 static void
774 ipmi_power_cycle(void *arg, int howto)
775 {
776         struct ipmi_softc *sc = arg;
777         struct ipmi_request *req;
778
779         /*
780          * Ignore everything except power cycling requests
781          */
782         if ((howto & RB_POWERCYCLE) == 0)
783                 return;
784
785         device_printf(sc->ipmi_dev, "Power cycling using IPMI\n");
786
787         /*
788          * Send a CHASSIS_CONTROL command to the CHASSIS device, subcommand 2
789          * as described in IPMI v2.0 spec section 28.3.
790          */
791         IPMI_ALLOC_DRIVER_REQUEST(req, IPMI_ADDR(IPMI_CHASSIS_REQUEST, 0),
792             IPMI_CHASSIS_CONTROL, 1, 0);
793         req->ir_request[0] = IPMI_CC_POWER_CYCLE;
794
795         ipmi_submit_driver_request(sc, req, MAX_TIMEOUT);
796
797         if (req->ir_error != 0 || req->ir_compcode != 0) {
798                 device_printf(sc->ipmi_dev, "Power cycling via IPMI failed code %#x %#x\n",
799                     req->ir_error, req->ir_compcode);
800                 return;
801         }
802
803         /*
804          * BMCs are notoriously slow, give it cyle_wait seconds for the power
805          * down leg of the power cycle. If that fails, fallback to the next
806          * hanlder in the shutdown_final chain and/or the platform failsafe.
807          */
808         DELAY(cycle_wait * 1000 * 1000);
809         device_printf(sc->ipmi_dev, "Power cycling via IPMI timed out\n");
810 }
811
812 static void
813 ipmi_startup(void *arg)
814 {
815         struct ipmi_softc *sc = arg;
816         struct ipmi_request *req;
817         device_t dev;
818         int error, i;
819
820         config_intrhook_disestablish(&sc->ipmi_ich);
821         dev = sc->ipmi_dev;
822
823         /* Initialize interface-independent state. */
824         mtx_init(&sc->ipmi_requests_lock, "ipmi requests", NULL, MTX_DEF);
825         mtx_init(&sc->ipmi_io_lock, "ipmi io", NULL, MTX_DEF);
826         cv_init(&sc->ipmi_request_added, "ipmireq");
827         TAILQ_INIT(&sc->ipmi_pending_requests);
828
829         /* Initialize interface-dependent state. */
830         error = sc->ipmi_startup(sc);
831         if (error) {
832                 device_printf(dev, "Failed to initialize interface: %d\n",
833                     error);
834                 return;
835         }
836
837         /* Send a GET_DEVICE_ID request. */
838         IPMI_ALLOC_DRIVER_REQUEST(req, IPMI_ADDR(IPMI_APP_REQUEST, 0),
839             IPMI_GET_DEVICE_ID, 0, 15);
840
841         error = ipmi_submit_driver_request(sc, req, MAX_TIMEOUT);
842         if (error == EWOULDBLOCK) {
843                 device_printf(dev, "Timed out waiting for GET_DEVICE_ID\n");
844                 return;
845         } else if (error) {
846                 device_printf(dev, "Failed GET_DEVICE_ID: %d\n", error);
847                 return;
848         } else if (req->ir_compcode != 0) {
849                 device_printf(dev,
850                     "Bad completion code for GET_DEVICE_ID: %d\n",
851                     req->ir_compcode);
852                 return;
853         } else if (req->ir_replylen < 5) {
854                 device_printf(dev, "Short reply for GET_DEVICE_ID: %d\n",
855                     req->ir_replylen);
856                 return;
857         }
858
859         device_printf(dev, "IPMI device rev. %d, firmware rev. %d.%d%d, "
860             "version %d.%d, device support mask %#x\n",
861             req->ir_reply[1] & 0x0f,
862             req->ir_reply[2] & 0x7f, req->ir_reply[3] >> 4, req->ir_reply[3] & 0x0f,
863             req->ir_reply[4] & 0x0f, req->ir_reply[4] >> 4, req->ir_reply[5]);
864
865         sc->ipmi_dev_support = req->ir_reply[5];
866
867         IPMI_INIT_DRIVER_REQUEST(req, IPMI_ADDR(IPMI_APP_REQUEST, 0),
868             IPMI_CLEAR_FLAGS, 1, 0);
869
870         ipmi_submit_driver_request(sc, req, 0);
871
872         /* XXX: Magic numbers */
873         if (req->ir_compcode == 0xc0) {
874                 device_printf(dev, "Clear flags is busy\n");
875         }
876         if (req->ir_compcode == 0xc1) {
877                 device_printf(dev, "Clear flags illegal\n");
878         }
879
880         for (i = 0; i < 8; i++) {
881                 IPMI_INIT_DRIVER_REQUEST(req, IPMI_ADDR(IPMI_APP_REQUEST, 0),
882                     IPMI_GET_CHANNEL_INFO, 1, 0);
883                 req->ir_request[0] = i;
884
885                 ipmi_submit_driver_request(sc, req, 0);
886
887                 if (req->ir_compcode != 0)
888                         break;
889         }
890         device_printf(dev, "Number of channels %d\n", i);
891
892         /*
893          * Probe for watchdog, but only for backends which support
894          * polled driver requests.
895          */
896         if (sc->ipmi_driver_requests_polled) {
897                 IPMI_INIT_DRIVER_REQUEST(req, IPMI_ADDR(IPMI_APP_REQUEST, 0),
898                     IPMI_GET_WDOG, 0, 0);
899
900                 ipmi_submit_driver_request(sc, req, 0);
901
902                 if (req->ir_compcode == 0x00) {
903                         device_printf(dev, "Attached watchdog\n");
904                         /* register the watchdog event handler */
905                         sc->ipmi_watchdog_tag = EVENTHANDLER_REGISTER(
906                                 watchdog_list, ipmi_wd_event, sc, 0);
907                         sc->ipmi_shutdown_tag = EVENTHANDLER_REGISTER(
908                                 shutdown_pre_sync, ipmi_shutdown_event,
909                                 sc, 0);
910                 }
911         }
912
913         sc->ipmi_cdev = make_dev(&ipmi_cdevsw, device_get_unit(dev),
914             UID_ROOT, GID_OPERATOR, 0660, "ipmi%d", device_get_unit(dev));
915         if (sc->ipmi_cdev == NULL) {
916                 device_printf(dev, "Failed to create cdev\n");
917                 return;
918         }
919         sc->ipmi_cdev->si_drv1 = sc;
920
921         /*
922          * Set initial watchdog state. If desired, set an initial
923          * watchdog on startup. Or, if the watchdog device is
924          * disabled, clear any existing watchdog.
925          */
926         if (on && wd_startup_countdown > 0) {
927                 wd_timer_actions = IPMI_SET_WD_ACTION_POWER_CYCLE;
928                 if (ipmi_set_watchdog(sc, wd_startup_countdown) == 0 &&
929                     ipmi_reset_watchdog(sc) == 0) {
930                         sc->ipmi_watchdog_active = wd_startup_countdown;
931                         sc->ipmi_watchdog_actions = wd_timer_actions;
932                         sc->ipmi_watchdog_pretimeout = wd_pretimeout_countdown;
933                 } else
934                         (void)ipmi_set_watchdog(sc, 0);
935                 ipmi_reset_watchdog(sc);
936         } else if (!on)
937                 (void)ipmi_set_watchdog(sc, 0);
938         /*
939          * Power cycle the system off using IPMI. We use last - 1 since we don't
940          * handle all the other kinds of reboots. We'll let others handle them.
941          * We only try to do this if the BMC supports the Chassis device.
942          */
943         if (sc->ipmi_dev_support & IPMI_ADS_CHASSIS) {
944                 device_printf(dev, "Establishing power cycle handler\n");
945                 sc->ipmi_power_cycle_tag = EVENTHANDLER_REGISTER(shutdown_final,
946                     ipmi_power_cycle, sc, SHUTDOWN_PRI_LAST - 1);
947         }
948 }
949
950 int
951 ipmi_attach(device_t dev)
952 {
953         struct ipmi_softc *sc = device_get_softc(dev);
954         int error;
955
956         if (sc->ipmi_irq_res != NULL && sc->ipmi_intr != NULL) {
957                 error = bus_setup_intr(dev, sc->ipmi_irq_res, INTR_TYPE_MISC,
958                     NULL, sc->ipmi_intr, sc, &sc->ipmi_irq);
959                 if (error) {
960                         device_printf(dev, "can't set up interrupt\n");
961                         return (error);
962                 }
963         }
964
965         bzero(&sc->ipmi_ich, sizeof(struct intr_config_hook));
966         sc->ipmi_ich.ich_func = ipmi_startup;
967         sc->ipmi_ich.ich_arg = sc;
968         if (config_intrhook_establish(&sc->ipmi_ich) != 0) {
969                 device_printf(dev, "can't establish configuration hook\n");
970                 return (ENOMEM);
971         }
972
973         ipmi_attached = 1;
974         return (0);
975 }
976
977 int
978 ipmi_detach(device_t dev)
979 {
980         struct ipmi_softc *sc;
981
982         sc = device_get_softc(dev);
983
984         /* Fail if there are any open handles. */
985         IPMI_LOCK(sc);
986         if (sc->ipmi_opened) {
987                 IPMI_UNLOCK(sc);
988                 return (EBUSY);
989         }
990         IPMI_UNLOCK(sc);
991         if (sc->ipmi_cdev)
992                 destroy_dev(sc->ipmi_cdev);
993
994         /* Detach from watchdog handling and turn off watchdog. */
995         if (sc->ipmi_shutdown_tag)
996                 EVENTHANDLER_DEREGISTER(shutdown_pre_sync,
997                 sc->ipmi_shutdown_tag);
998         if (sc->ipmi_watchdog_tag) {
999                 EVENTHANDLER_DEREGISTER(watchdog_list, sc->ipmi_watchdog_tag);
1000                 ipmi_set_watchdog(sc, 0);
1001         }
1002
1003         /* Detach from shutdown handling for power cycle reboot */
1004         if (sc->ipmi_power_cycle_tag)
1005                 EVENTHANDLER_DEREGISTER(shutdown_final, sc->ipmi_power_cycle_tag);
1006
1007         /* XXX: should use shutdown callout I think. */
1008         /* If the backend uses a kthread, shut it down. */
1009         IPMI_LOCK(sc);
1010         sc->ipmi_detaching = 1;
1011         if (sc->ipmi_kthread) {
1012                 cv_broadcast(&sc->ipmi_request_added);
1013                 msleep(sc->ipmi_kthread, &sc->ipmi_requests_lock, 0,
1014                     "ipmi_wait", 0);
1015         }
1016         IPMI_UNLOCK(sc);
1017         if (sc->ipmi_irq)
1018                 bus_teardown_intr(dev, sc->ipmi_irq_res, sc->ipmi_irq);
1019
1020         ipmi_release_resources(dev);
1021         mtx_destroy(&sc->ipmi_io_lock);
1022         mtx_destroy(&sc->ipmi_requests_lock);
1023         return (0);
1024 }
1025
1026 void
1027 ipmi_release_resources(device_t dev)
1028 {
1029         struct ipmi_softc *sc;
1030         int i;
1031
1032         sc = device_get_softc(dev);
1033         if (sc->ipmi_irq)
1034                 bus_teardown_intr(dev, sc->ipmi_irq_res, sc->ipmi_irq);
1035         if (sc->ipmi_irq_res)
1036                 bus_release_resource(dev, SYS_RES_IRQ, sc->ipmi_irq_rid,
1037                     sc->ipmi_irq_res);
1038         for (i = 0; i < MAX_RES; i++)
1039                 if (sc->ipmi_io_res[i])
1040                         bus_release_resource(dev, sc->ipmi_io_type,
1041                             sc->ipmi_io_rid + i, sc->ipmi_io_res[i]);
1042 }
1043
1044 devclass_t ipmi_devclass;
1045
1046 /* XXX: Why? */
1047 static void
1048 ipmi_unload(void *arg)
1049 {
1050         device_t *      devs;
1051         int             count;
1052         int             i;
1053
1054         if (devclass_get_devices(ipmi_devclass, &devs, &count) != 0)
1055                 return;
1056         for (i = 0; i < count; i++)
1057                 device_delete_child(device_get_parent(devs[i]), devs[i]);
1058         free(devs, M_TEMP);
1059 }
1060 SYSUNINIT(ipmi_unload, SI_SUB_DRIVERS, SI_ORDER_FIRST, ipmi_unload, NULL);
1061
1062 #ifdef IMPI_DEBUG
1063 static void
1064 dump_buf(u_char *data, int len)
1065 {
1066         char buf[20];
1067         char line[1024];
1068         char temp[30];
1069         int count = 0;
1070         int i=0;
1071
1072         printf("Address %p len %d\n", data, len);
1073         if (len > 256)
1074                 len = 256;
1075         line[0] = '\000';
1076         for (; len > 0; len--, data++) {
1077                 sprintf(temp, "%02x ", *data);
1078                 strcat(line, temp);
1079                 if (*data >= ' ' && *data <= '~')
1080                         buf[count] = *data;
1081                 else if (*data >= 'A' && *data <= 'Z')
1082                         buf[count] = *data;
1083                 else
1084                         buf[count] = '.';
1085                 if (++count == 16) {
1086                         buf[count] = '\000';
1087                         count = 0;
1088                         printf("  %3x  %s %s\n", i, line, buf);
1089                         i+=16;
1090                         line[0] = '\000';
1091                 }
1092         }
1093         buf[count] = '\000';
1094
1095         for (; count != 16; count++) {
1096                 strcat(line, "   ");
1097         }
1098         printf("  %3x  %s %s\n", i, line, buf);
1099 }
1100 #endif