]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/uart/uart_core.c
Remove unused variable.
[FreeBSD/FreeBSD.git] / sys / dev / uart / uart_core.c
1 /*-
2  * Copyright (c) 2003 Marcel Moolenaar
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  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 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/conf.h>
34 #include <sys/cons.h>
35 #include <sys/fcntl.h>
36 #include <sys/interrupt.h>
37 #include <sys/kdb.h>
38 #include <sys/kernel.h>
39 #include <sys/malloc.h>
40 #include <sys/queue.h>
41 #include <sys/reboot.h>
42 #include <machine/bus.h>
43 #include <sys/rman.h>
44 #include <machine/resource.h>
45 #include <machine/stdarg.h>
46
47 #include <dev/uart/uart.h>
48 #include <dev/uart/uart_bus.h>
49 #include <dev/uart/uart_cpu.h>
50
51 #include "uart_if.h"
52
53 devclass_t uart_devclass;
54 char uart_driver_name[] = "uart";
55
56 SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs =
57     SLIST_HEAD_INITIALIZER(uart_sysdevs);
58
59 static MALLOC_DEFINE(M_UART, "UART", "UART driver");
60
61 #ifndef UART_POLL_FREQ
62 #define UART_POLL_FREQ          50
63 #endif
64 static int uart_poll_freq = UART_POLL_FREQ;
65 TUNABLE_INT("debug.uart_poll_freq", &uart_poll_freq);
66
67 void
68 uart_add_sysdev(struct uart_devinfo *di)
69 {
70         SLIST_INSERT_HEAD(&uart_sysdevs, di, next);
71 }
72
73 const char *
74 uart_getname(struct uart_class *uc)
75 {
76         return ((uc != NULL) ? uc->name : NULL);
77 }
78
79 struct uart_ops *
80 uart_getops(struct uart_class *uc)
81 {
82         return ((uc != NULL) ? uc->uc_ops : NULL);
83 }
84
85 int
86 uart_getrange(struct uart_class *uc)
87 {
88         return ((uc != NULL) ? uc->uc_range : 0);
89 }
90
91 u_int
92 uart_getregshift(struct uart_class *uc)
93 {
94         return ((uc != NULL) ? uc->uc_rshift : 0);
95 }
96
97 /*
98  * Schedule a soft interrupt. We do this on the 0 to !0 transition
99  * of the TTY pending interrupt status.
100  */
101 void
102 uart_sched_softih(struct uart_softc *sc, uint32_t ipend)
103 {
104         uint32_t new, old;
105
106         do {
107                 old = sc->sc_ttypend;
108                 new = old | ipend;
109         } while (!atomic_cmpset_32(&sc->sc_ttypend, old, new));
110
111         if ((old & SER_INT_MASK) == 0)
112                 swi_sched(sc->sc_softih, 0);
113 }
114
115 /*
116  * A break condition has been detected. We treat the break condition as
117  * a special case that should not happen during normal operation. When
118  * the break condition is to be passed to higher levels in the form of
119  * a NUL character, we really want the break to be in the right place in
120  * the input stream. The overhead to achieve that is not in relation to
121  * the exceptional nature of the break condition, so we permit ourselves
122  * to be sloppy.
123  */
124 static __inline int
125 uart_intr_break(void *arg)
126 {
127         struct uart_softc *sc = arg;
128
129 #if defined(KDB)
130         if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
131                 if (kdb_break())
132                         return (0);
133         }
134 #endif
135         if (sc->sc_opened)
136                 uart_sched_softih(sc, SER_INT_BREAK);
137         return (0);
138 }
139
140 /*
141  * Handle a receiver overrun situation. We lost at least 1 byte in the
142  * input stream and it's our job to contain the situation. We grab as
143  * much of the data we can, but otherwise flush the receiver FIFO to
144  * create some breathing room. The net effect is that we avoid the
145  * overrun condition to happen for the next X characters, where X is
146  * related to the FIFO size at the cost of losing data right away.
147  * So, instead of having multiple overrun interrupts in close proximity
148  * to each other and possibly pessimizing UART interrupt latency for
149  * other UARTs in a multiport configuration, we create a longer segment
150  * of missing characters by freeing up the FIFO.
151  * Each overrun condition is marked in the input buffer by a token. The
152  * token represents the loss of at least one, but possible more bytes in
153  * the input stream.
154  */
155 static __inline int
156 uart_intr_overrun(void *arg)
157 {
158         struct uart_softc *sc = arg;
159
160         if (sc->sc_opened) {
161                 UART_RECEIVE(sc);
162                 if (uart_rx_put(sc, UART_STAT_OVERRUN))
163                         sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
164                 uart_sched_softih(sc, SER_INT_RXREADY);
165         }
166         UART_FLUSH(sc, UART_FLUSH_RECEIVER);
167         return (0);
168 }
169
170 /*
171  * Received data ready.
172  */
173 static __inline int
174 uart_intr_rxready(void *arg)
175 {
176         struct uart_softc *sc = arg;
177         int rxp;
178
179         rxp = sc->sc_rxput;
180         UART_RECEIVE(sc);
181 #if defined(KDB)
182         if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
183                 while (rxp != sc->sc_rxput) {
184                         kdb_alt_break(sc->sc_rxbuf[rxp++], &sc->sc_altbrk);
185                         if (rxp == sc->sc_rxbufsz)
186                                 rxp = 0;
187                 }
188         }
189 #endif
190         if (sc->sc_opened)
191                 uart_sched_softih(sc, SER_INT_RXREADY);
192         else
193                 sc->sc_rxput = sc->sc_rxget;    /* Ignore received data. */
194         return (1);
195 }
196
197 /*
198  * Line or modem status change (OOB signalling).
199  * We pass the signals to the software interrupt handler for further
200  * processing. Note that we merge the delta bits, but set the state
201  * bits. This is to avoid losing state transitions due to having more
202  * than 1 hardware interrupt between software interrupts.
203  */
204 static __inline int
205 uart_intr_sigchg(void *arg)
206 {
207         struct uart_softc *sc = arg;
208         int new, old, sig;
209
210         sig = UART_GETSIG(sc);
211
212         if (sc->sc_pps.ppsparam.mode & PPS_CAPTUREBOTH) {
213                 if (sig & UART_SIG_DPPS) {
214                         pps_capture(&sc->sc_pps);
215                         pps_event(&sc->sc_pps, (sig & UART_SIG_PPS) ?
216                             PPS_CAPTUREASSERT : PPS_CAPTURECLEAR);
217                 }
218         }
219
220         /*
221          * Keep track of signal changes, even when the device is not
222          * opened. This allows us to inform upper layers about a
223          * possible loss of DCD and thus the existence of a (possibly)
224          * different connection when we have DCD back, during the time
225          * that the device was closed.
226          */
227         do {
228                 old = sc->sc_ttypend;
229                 new = old & ~SER_MASK_STATE;
230                 new |= sig & SER_INT_SIGMASK;
231         } while (!atomic_cmpset_32(&sc->sc_ttypend, old, new));
232
233         if (sc->sc_opened)
234                 uart_sched_softih(sc, SER_INT_SIGCHG);
235         return (1);
236 }
237
238 /*
239  * The transmitter can accept more data.
240  */
241 static __inline int
242 uart_intr_txidle(void *arg)
243 {
244         struct uart_softc *sc = arg;
245
246         if (sc->sc_txbusy) {
247                 sc->sc_txbusy = 0;
248                 uart_sched_softih(sc, SER_INT_TXIDLE);
249         }
250         return (0);
251 }
252
253 static int
254 uart_intr(void *arg)
255 {
256         struct uart_softc *sc = arg;
257         int cnt, ipend;
258
259         if (sc->sc_leaving)
260                 return (FILTER_STRAY);
261
262         cnt = 0;
263         while (cnt < 20 && (ipend = UART_IPEND(sc)) != 0) {
264                 cnt++;
265                 if (ipend & SER_INT_OVERRUN)
266                         uart_intr_overrun(sc);
267                 if (ipend & SER_INT_BREAK)
268                         uart_intr_break(sc);
269                 if (ipend & SER_INT_RXREADY)
270                         uart_intr_rxready(sc);
271                 if (ipend & SER_INT_SIGCHG)
272                         uart_intr_sigchg(sc);
273                 if (ipend & SER_INT_TXIDLE)
274                         uart_intr_txidle(sc);           
275         }
276
277         if (sc->sc_polled) {
278                 callout_reset(&sc->sc_timer, hz / uart_poll_freq,
279                     (timeout_t *)uart_intr, sc);
280         }
281
282         return ((cnt == 0) ? FILTER_STRAY :
283             ((cnt == 20) ? FILTER_SCHEDULE_THREAD : FILTER_HANDLED));
284 }
285
286 serdev_intr_t *
287 uart_bus_ihand(device_t dev, int ipend)
288 {
289
290         switch (ipend) {
291         case SER_INT_BREAK:
292                 return (uart_intr_break);
293         case SER_INT_OVERRUN:
294                 return (uart_intr_overrun);
295         case SER_INT_RXREADY:
296                 return (uart_intr_rxready);
297         case SER_INT_SIGCHG:
298                 return (uart_intr_sigchg);
299         case SER_INT_TXIDLE:
300                 return (uart_intr_txidle);
301         }
302         return (NULL);
303 }
304
305 int
306 uart_bus_ipend(device_t dev)
307 {
308         struct uart_softc *sc;
309
310         sc = device_get_softc(dev);
311         return (UART_IPEND(sc));
312 }
313
314 int
315 uart_bus_sysdev(device_t dev)
316 {
317         struct uart_softc *sc;
318
319         sc = device_get_softc(dev);
320         return ((sc->sc_sysdev != NULL) ? 1 : 0);
321 }
322
323 int
324 uart_bus_probe(device_t dev, int regshft, int rclk, int rid, int chan)
325 {
326         struct uart_softc *sc;
327         struct uart_devinfo *sysdev;
328         int error;
329
330         sc = device_get_softc(dev);
331
332         /*
333          * All uart_class references are weak. Check that the needed
334          * class has been compiled-in. Fail if not.
335          */
336         if (sc->sc_class == NULL)
337                 return (ENXIO);
338
339         /*
340          * Initialize the instance. Note that the instance (=softc) does
341          * not necessarily match the hardware specific softc. We can't do
342          * anything about it now, because we may not attach to the device.
343          * Hardware drivers cannot use any of the class specific fields
344          * while probing.
345          */
346         kobj_init((kobj_t)sc, (kobj_class_t)sc->sc_class);
347         sc->sc_dev = dev;
348         if (device_get_desc(dev) == NULL)
349                 device_set_desc(dev, uart_getname(sc->sc_class));
350
351         /*
352          * Allocate the register resource. We assume that all UARTs have
353          * a single register window in either I/O port space or memory
354          * mapped I/O space. Any UART that needs multiple windows will
355          * consequently not be supported by this driver as-is. We try I/O
356          * port space first because that's the common case.
357          */
358         sc->sc_rrid = rid;
359         sc->sc_rtype = SYS_RES_IOPORT;
360         sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype, &sc->sc_rrid,
361             0, ~0, uart_getrange(sc->sc_class), RF_ACTIVE);
362         if (sc->sc_rres == NULL) {
363                 sc->sc_rrid = rid;
364                 sc->sc_rtype = SYS_RES_MEMORY;
365                 sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype,
366                     &sc->sc_rrid, 0, ~0, uart_getrange(sc->sc_class),
367                     RF_ACTIVE);
368                 if (sc->sc_rres == NULL)
369                         return (ENXIO);
370         }
371
372         /*
373          * Fill in the bus access structure and compare this device with
374          * a possible console device and/or a debug port. We set the flags
375          * in the softc so that the hardware dependent probe can adjust
376          * accordingly. In general, you don't want to permanently disrupt
377          * console I/O.
378          */
379         sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres);
380         sc->sc_bas.bst = rman_get_bustag(sc->sc_rres);
381         sc->sc_bas.chan = chan;
382         sc->sc_bas.regshft = regshft;
383         sc->sc_bas.rclk = (rclk == 0) ? sc->sc_class->uc_rclk : rclk;
384
385         SLIST_FOREACH(sysdev, &uart_sysdevs, next) {
386                 if (chan == sysdev->bas.chan &&
387                     uart_cpu_eqres(&sc->sc_bas, &sysdev->bas)) {
388                         /* XXX check if ops matches class. */
389                         sc->sc_sysdev = sysdev;
390                         sysdev->bas.rclk = sc->sc_bas.rclk;
391                 }
392         }
393
394         error = UART_PROBE(sc);
395         bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres);
396         return ((error) ? error : BUS_PROBE_DEFAULT);
397 }
398
399 int
400 uart_bus_attach(device_t dev)
401 {
402         struct uart_softc *sc, *sc0;
403         const char *sep;
404         int error, filt;
405
406         /*
407          * The sc_class field defines the type of UART we're going to work
408          * with and thus the size of the softc. Replace the generic softc
409          * with one that matches the UART now that we're certain we handle
410          * the device.
411          */
412         sc0 = device_get_softc(dev);
413         if (sc0->sc_class->size > sizeof(*sc)) {
414                 sc = malloc(sc0->sc_class->size, M_UART, M_WAITOK|M_ZERO);
415                 bcopy(sc0, sc, sizeof(*sc));
416                 device_set_softc(dev, sc);
417         } else
418                 sc = sc0;
419
420         /*
421          * Now that we know the softc for this device, connect the back
422          * pointer from the sysdev for this device, if any
423          */
424         if (sc->sc_sysdev != NULL)
425                 sc->sc_sysdev->sc = sc;
426
427         /*
428          * Protect ourselves against interrupts while we're not completely
429          * finished attaching and initializing. We don't expect interrupts
430          * until after UART_ATTACH() though.
431          */
432         sc->sc_leaving = 1;
433
434         mtx_init(&sc->sc_hwmtx_s, "uart_hwmtx", NULL, MTX_SPIN);
435         if (sc->sc_hwmtx == NULL)
436                 sc->sc_hwmtx = &sc->sc_hwmtx_s;
437
438         /*
439          * Re-allocate. We expect that the softc contains the information
440          * collected by uart_bus_probe() intact.
441          */
442         sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype, &sc->sc_rrid,
443             0, ~0, uart_getrange(sc->sc_class), RF_ACTIVE);
444         if (sc->sc_rres == NULL) {
445                 mtx_destroy(&sc->sc_hwmtx_s);
446                 return (ENXIO);
447         }
448         sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres);
449         sc->sc_bas.bst = rman_get_bustag(sc->sc_rres);
450
451         /*
452          * Ensure there is room for at least three full FIFOs of data in the
453          * receive buffer (handles the case of low-level drivers with huge
454          * FIFOs), and also ensure that there is no less than the historical
455          * size of 384 bytes (handles the typical small-FIFO case).
456          */
457         sc->sc_rxbufsz = MAX(384, sc->sc_rxfifosz * 3);
458         sc->sc_rxbuf = malloc(sc->sc_rxbufsz * sizeof(*sc->sc_rxbuf),
459             M_UART, M_WAITOK);
460         sc->sc_txbuf = malloc(sc->sc_txfifosz * sizeof(*sc->sc_txbuf),
461             M_UART, M_WAITOK);
462
463         error = UART_ATTACH(sc);
464         if (error)
465                 goto fail;
466
467         if (sc->sc_hwiflow || sc->sc_hwoflow) {
468                 sep = "";
469                 device_print_prettyname(dev);
470                 if (sc->sc_hwiflow) {
471                         printf("%sRTS iflow", sep);
472                         sep = ", ";
473                 }
474                 if (sc->sc_hwoflow) {
475                         printf("%sCTS oflow", sep);
476                         sep = ", ";
477                 }
478                 printf("\n");
479         }
480
481         if (sc->sc_sysdev != NULL) {
482                 if (sc->sc_sysdev->baudrate == 0) {
483                         if (UART_IOCTL(sc, UART_IOCTL_BAUD,
484                             (intptr_t)&sc->sc_sysdev->baudrate) != 0)
485                                 sc->sc_sysdev->baudrate = -1;
486                 }
487                 switch (sc->sc_sysdev->type) {
488                 case UART_DEV_CONSOLE:
489                         device_printf(dev, "console");
490                         break;
491                 case UART_DEV_DBGPORT:
492                         device_printf(dev, "debug port");
493                         break;
494                 case UART_DEV_KEYBOARD:
495                         device_printf(dev, "keyboard");
496                         break;
497                 default:
498                         device_printf(dev, "unknown system device");
499                         break;
500                 }
501                 printf(" (%d,%c,%d,%d)\n", sc->sc_sysdev->baudrate,
502                     "noems"[sc->sc_sysdev->parity], sc->sc_sysdev->databits,
503                     sc->sc_sysdev->stopbits);
504         }
505
506         sc->sc_pps.ppscap = PPS_CAPTUREBOTH;
507         pps_init(&sc->sc_pps);
508
509         sc->sc_leaving = 0;
510         filt = uart_intr(sc);
511
512         /*
513          * Don't use interrupts if we couldn't clear any pending interrupt
514          * conditions. We may have broken H/W and polling is probably the
515          * safest thing to do.
516          */
517         if (filt != FILTER_SCHEDULE_THREAD) {
518                 sc->sc_irid = 0;
519                 sc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
520                     &sc->sc_irid, RF_ACTIVE | RF_SHAREABLE);
521         }
522         if (sc->sc_ires != NULL) {
523                 error = bus_setup_intr(dev, sc->sc_ires, INTR_TYPE_TTY,
524                     uart_intr, NULL, sc, &sc->sc_icookie);
525                 sc->sc_fastintr = (error == 0) ? 1 : 0;
526
527                 if (!sc->sc_fastintr)
528                         error = bus_setup_intr(dev, sc->sc_ires,
529                             INTR_TYPE_TTY | INTR_MPSAFE, NULL,
530                             (driver_intr_t *)uart_intr, sc, &sc->sc_icookie);
531
532                 if (error) {
533                         device_printf(dev, "could not activate interrupt\n");
534                         bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid,
535                             sc->sc_ires);
536                         sc->sc_ires = NULL;
537                 }
538         }
539         if (sc->sc_ires == NULL) {
540                 /* No interrupt resource. Force polled mode. */
541                 sc->sc_polled = 1;
542                 callout_init(&sc->sc_timer, 1);
543         }
544
545         if (bootverbose && (sc->sc_fastintr || sc->sc_polled)) {
546                 sep = "";
547                 device_print_prettyname(dev);
548                 if (sc->sc_fastintr) {
549                         printf("%sfast interrupt", sep);
550                         sep = ", ";
551                 }
552                 if (sc->sc_polled) {
553                         printf("%spolled mode (%dHz)", sep, uart_poll_freq);
554                         sep = ", ";
555                 }
556                 printf("\n");
557         }
558
559         error = (sc->sc_sysdev != NULL && sc->sc_sysdev->attach != NULL)
560             ? (*sc->sc_sysdev->attach)(sc) : uart_tty_attach(sc);
561         if (error)
562                 goto fail;
563
564         if (sc->sc_sysdev != NULL)
565                 sc->sc_sysdev->hwmtx = sc->sc_hwmtx;
566
567         return (0);
568
569  fail:
570         free(sc->sc_txbuf, M_UART);
571         free(sc->sc_rxbuf, M_UART);
572
573         if (sc->sc_ires != NULL) {
574                 bus_teardown_intr(dev, sc->sc_ires, sc->sc_icookie);
575                 bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid,
576                     sc->sc_ires);
577         }
578         bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres);
579
580         mtx_destroy(&sc->sc_hwmtx_s);
581
582         return (error);
583 }
584
585 int
586 uart_bus_detach(device_t dev)
587 {
588         struct uart_softc *sc;
589
590         sc = device_get_softc(dev);
591
592         sc->sc_leaving = 1;
593
594         if (sc->sc_sysdev != NULL)
595                 sc->sc_sysdev->hwmtx = NULL;
596
597         UART_DETACH(sc);
598
599         if (sc->sc_sysdev != NULL && sc->sc_sysdev->detach != NULL)
600                 (*sc->sc_sysdev->detach)(sc);
601         else
602                 uart_tty_detach(sc);
603
604         free(sc->sc_txbuf, M_UART);
605         free(sc->sc_rxbuf, M_UART);
606
607         if (sc->sc_ires != NULL) {
608                 bus_teardown_intr(dev, sc->sc_ires, sc->sc_icookie);
609                 bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid,
610                     sc->sc_ires);
611         }
612         bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres);
613
614         mtx_destroy(&sc->sc_hwmtx_s);
615
616         if (sc->sc_class->size > sizeof(*sc)) {
617                 device_set_softc(dev, NULL);
618                 free(sc, M_UART);
619         } else
620                 device_set_softc(dev, NULL);
621
622         return (0);
623 }
624
625 int
626 uart_bus_resume(device_t dev)
627 {
628         struct uart_softc *sc;
629
630         sc = device_get_softc(dev);
631         return (UART_ATTACH(sc));
632 }
633
634 void
635 uart_grab(struct uart_devinfo *di)
636 {
637
638         if (di->sc)
639                 UART_GRAB(di->sc);
640 }
641
642 void
643 uart_ungrab(struct uart_devinfo *di)
644 {
645
646         if (di->sc)
647                 UART_UNGRAB(di->sc);
648 }