The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/pc/uartpci.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 #include "u.h"
    2 #include "../port/lib.h"
    3 #include "mem.h"
    4 #include "dat.h"
    5 #include "fns.h"
    6 #include "io.h"
    7 #include "../port/error.h"
    8 
    9 extern PhysUart i8250physuart;
   10 extern PhysUart pciphysuart;
   11 extern void* i8250alloc(int, int, int);
   12 
   13 static Uart *perlehead, *perletail;
   14 
   15 static Uart*
   16 uartpci(int ctlrno, Pcidev* p, int barno, int n, int freq, char* name,
   17         int iosize)
   18 {
   19         int i, io;
   20         void *ctlr;
   21         char buf[64];
   22         Uart *head, *uart;
   23 
   24         io = p->mem[barno].bar & ~0x01;
   25         snprint(buf, sizeof(buf), "%s%d", pciphysuart.name, ctlrno);
   26         if(ioalloc(io, p->mem[barno].size, 0, buf) < 0){
   27                 print("uartpci: I/O 0x%uX in use\n", io);
   28                 return nil;
   29         }
   30 
   31         head = uart = malloc(sizeof(Uart)*n);
   32         for(i = 0; i < n; i++){
   33                 ctlr = i8250alloc(io, p->intl, p->tbdf);
   34                 io += iosize;
   35                 if(ctlr == nil)
   36                         continue;
   37 
   38                 uart->regs = ctlr;
   39                 snprint(buf, sizeof(buf), "%s.%8.8uX", name, p->tbdf);
   40                 kstrdup(&uart->name, buf);
   41                 uart->freq = freq;
   42                 uart->phys = &i8250physuart;
   43                 if(uart != head)
   44                         (uart-1)->next = uart;
   45                 uart++;
   46         }
   47 
   48         if (head) {
   49                 if(perlehead != nil)
   50                         perletail->next = head;
   51                 else
   52                         perlehead = head;
   53                 for(perletail = head; perletail->next != nil;
   54                     perletail = perletail->next)
   55                         ;
   56         }
   57         return head;
   58 }
   59 
   60 static Uart *
   61 ultraport16si(int ctlrno, Pcidev *p, ulong freq)
   62 {
   63         int io, i;
   64         char *name;
   65         Uart *uart;
   66 
   67         name = "Ultraport16si";         /* 16L788 UARTs */
   68         io = p->mem[4].bar & ~1;
   69         if (ioalloc(io, p->mem[4].size, 0, name) < 0) {
   70                 print("uartpci: can't get IO space to set %s to rs-232\n", name);
   71                 return nil;
   72         }
   73         for (i = 0; i < 16; i++) {
   74                 outb(io, i << 4);
   75                 outb(io, (i << 4) + 1); /* set to RS232 mode  (Don't ask!) */
   76         }
   77 
   78         uart = uartpci(ctlrno, p, 2, 8, freq, name, 16);
   79         if(uart)
   80                 uart = uartpci(ctlrno, p, 3, 8, freq, name, 16);
   81         return uart;
   82 }
   83 
   84 static Uart*
   85 uartpcipnp(void)
   86 {
   87         Pcidev *p;
   88         char *name;
   89         int ctlrno, subid;
   90         ulong freq;
   91         Uart *uart;
   92 
   93         /*
   94          * Loop through all PCI devices looking for simple serial
   95          * controllers (ccrb == 0x07) and configure the ones which
   96          * are familiar. All suitable devices are configured to
   97          * simply point to the generic i8250 driver.
   98          */
   99         perlehead = perletail = nil;
  100         ctlrno = 0;
  101         for(p = pcimatch(nil, 0, 0); p != nil; p = pcimatch(p, 0, 0)){
  102                 if(p->ccrb != 0x07 || p->ccru > 2)
  103                         continue;
  104 
  105                 switch(p->did<<16 | p->vid){
  106                 default:
  107                         continue;
  108                 case (0x9835<<16)|0x9710:       /* StarTech PCI2S550 */
  109                         uart = uartpci(ctlrno, p, 0, 1, 1843200, "PCI2S550-0", 8);
  110                         if(uart == nil)
  111                                 continue;
  112                         uart->next = uartpci(ctlrno, p, 1, 1, 1843200,
  113                                 "PCI2S550-1", 8);
  114                         if(uart->next == nil)
  115                                 continue;
  116                         break;
  117                 case (0x950A<<16)|0x1415:       /* Oxford Semi OX16PCI954 */
  118                 case (0x9501<<16)|0x1415:
  119                         /*
  120                          * These are common devices used by 3rd-party
  121                          * manufacturers.
  122                          * Must check the subsystem VID and DID for correct
  123                          * match.
  124                          */
  125                         subid = pcicfgr16(p, PciSVID);
  126                         subid |= pcicfgr16(p, PciSID)<<16;
  127                         switch(subid){
  128                         default:
  129                                 print("oxsemi uart %.8#ux of vid %#ux did %#ux unknown\n",
  130                                         subid, p->vid, p->did);
  131                                 continue;
  132                         case (0<<16)|0x1415:
  133                                 uart = uartpci(ctlrno, p, 0, 4, 1843200,
  134                                         "starport-pex4s", 8);
  135                                 break;
  136                         case (0x2000<<16)|0x131F:/* SIIG CyberSerial PCIe */
  137                                 uart = uartpci(ctlrno, p, 0, 1, 18432000,
  138                                         "CyberSerial-1S", 8);
  139                                 break;
  140                         }
  141                         break;
  142                 case (0x9050<<16)|0x10B5:       /* Perle PCI-Fast4 series */
  143                 case (0x9030<<16)|0x10B5:       /* Perle Ultraport series */
  144                         /*
  145                          * These devices consists of a PLX bridge (the above
  146                          * PCI VID+DID) behind which are some 16C654 UARTs.
  147                          * Must check the subsystem VID and DID for correct
  148                          * match.
  149                          */
  150                         subid = pcicfgr16(p, PciSVID);
  151                         subid |= pcicfgr16(p, PciSID)<<16;
  152                         freq = 7372800;
  153                         switch(subid){
  154                         default:
  155                                 continue;
  156                         case (0x0011<<16)|0x12E0:       /* Perle PCI-Fast16 */
  157                                 name = "PCI-Fast16";
  158                                 uart = uartpci(ctlrno, p, 2, 16, freq, name, 8);
  159                                 break;
  160                         case (0x0021<<16)|0x12E0:       /* Perle PCI-Fast8 */
  161                                 name = "PCI-Fast8";
  162                                 uart = uartpci(ctlrno, p, 2, 8, freq, name, 8);
  163                                 break;
  164                         case (0x0031<<16)|0x12E0:       /* Perle PCI-Fast4 */
  165                                 name = "PCI-Fast4";
  166                                 uart = uartpci(ctlrno, p, 2, 4, freq, name, 8);
  167                                 break;
  168                         case (0x0021<<16)|0x155F:       /* Perle Ultraport8 */
  169                                 name = "Ultraport8";    /* 16C754 UARTs */
  170                                 uart = uartpci(ctlrno, p, 2, 8, freq, name, 8);
  171                                 break;
  172                         case (0x0041<<16)|0x155F:       /* Perle Ultraport16 */
  173                                 name = "Ultraport16";
  174                                 uart = uartpci(ctlrno, p, 2, 16, 2 * freq,
  175                                         name, 8);
  176                                 break;
  177                         case (0x0241<<16)|0x155F:       /* Perle Ultraport16 */
  178                                 uart = ultraport16si(ctlrno, p, 4 * freq);
  179                                 break;
  180                         }
  181                         break;
  182                 }
  183                 if(uart)
  184                         ctlrno++;
  185         }
  186 
  187         return perlehead;
  188 }
  189 
  190 PhysUart pciphysuart = {
  191         .name           = "UartPCI",
  192         .pnp            = uartpcipnp,
  193         .enable         = nil,
  194         .disable        = nil,
  195         .kick           = nil,
  196         .dobreak        = nil,
  197         .baud           = nil,
  198         .bits           = nil,
  199         .stop           = nil,
  200         .parity         = nil,
  201         .modemctl       = nil,
  202         .rts            = nil,
  203         .dtr            = nil,
  204         .status         = nil,
  205         .fifo           = nil,
  206 };

Cache object: 7829e9a154c6063d113c32e4f3d630fc


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.